Skip to content

Commit

Permalink
providers: Add SM4 GCM implementation
Browse files Browse the repository at this point in the history
The GCM mode of the SM4 algorithm is specifieded by RFC8998.

Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>

Reviewed-by: Paul Yang <kaishen.yy@antfin.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from #16491)

(cherry picked from commit c2ee608)
  • Loading branch information
uudiin authored and t8m committed Nov 9, 2022
1 parent 852bb13 commit 8c39948
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 1 deletion.
2 changes: 2 additions & 0 deletions providers/defltprov.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ static const OSSL_ALGORITHM_CAPABLE deflt_ciphers[] = {
ALG(PROV_NAMES_DES_EDE_CFB, ossl_tdes_ede2_cfb_functions),
#endif /* OPENSSL_NO_DES */
#ifndef OPENSSL_NO_SM4
ALG(PROV_NAMES_SM4_GCM, ossl_sm4128gcm_functions),
ALG(PROV_NAMES_SM4_CCM, ossl_sm4128ccm_functions),
ALG(PROV_NAMES_SM4_ECB, ossl_sm4128ecb_functions),
ALG(PROV_NAMES_SM4_CBC, ossl_sm4128cbc_functions),
ALG(PROV_NAMES_SM4_CTR, ossl_sm4128ctr_functions),
Expand Down
4 changes: 3 additions & 1 deletion providers/implementations/ciphers/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ ENDIF

IF[{- !$disabled{sm4} -}]
SOURCE[$SM4_GOAL]=\
cipher_sm4.c cipher_sm4_hw.c
cipher_sm4.c cipher_sm4_hw.c \
cipher_sm4_gcm.c cipher_sm4_gcm_hw.c \
cipher_sm4_ccm.c cipher_sm4_ccm_hw.c
ENDIF

IF[{- !$disabled{ocb} -}]
Expand Down
39 changes: 39 additions & 0 deletions providers/implementations/ciphers/cipher_sm4_ccm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

/* Dispatch functions for SM4 CCM mode */

#include "cipher_sm4_ccm.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"

static OSSL_FUNC_cipher_freectx_fn sm4_ccm_freectx;

static void *sm4_ccm_newctx(void *provctx, size_t keybits)
{
PROV_SM4_CCM_CTX *ctx;

if (!ossl_prov_is_running())
return NULL;

ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx != NULL)
ossl_ccm_initctx(&ctx->base, keybits, ossl_prov_sm4_hw_ccm(keybits));
return ctx;
}

static void sm4_ccm_freectx(void *vctx)
{
PROV_SM4_CCM_CTX *ctx = (PROV_SM4_CCM_CTX *)vctx;

OPENSSL_clear_free(ctx, sizeof(*ctx));
}

/* sm4128ccm functions */
IMPLEMENT_aead_cipher(sm4, ccm, CCM, AEAD_FLAGS, 128, 8, 96);
22 changes: 22 additions & 0 deletions providers/implementations/ciphers/cipher_sm4_ccm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

#include "crypto/sm4.h"
#include "prov/ciphercommon.h"
#include "prov/ciphercommon_ccm.h"

typedef struct prov_sm4_ccm_ctx_st {
PROV_CCM_CTX base; /* Must be first */
union {
OSSL_UNION_ALIGN;
SM4_KEY ks;
} ks; /* SM4 key schedule to use */
} PROV_SM4_CCM_CTX;

const PROV_CCM_HW *ossl_prov_sm4_hw_ccm(size_t keylen);
41 changes: 41 additions & 0 deletions providers/implementations/ciphers/cipher_sm4_ccm_hw.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

/*-
* Generic support for SM4 CCM.
*/

#include "cipher_sm4_ccm.h"

static int ccm_sm4_initkey(PROV_CCM_CTX *ctx,
const unsigned char *key, size_t keylen)
{
PROV_SM4_CCM_CTX *actx = (PROV_SM4_CCM_CTX *)ctx;

ossl_sm4_set_key(key, &actx->ks.ks);
CRYPTO_ccm128_init(&ctx->ccm_ctx, ctx->m, ctx->l, &actx->ks.ks,
(block128_f)ossl_sm4_encrypt);
ctx->str = NULL;
ctx->key_set = 1;
return 1;
}

static const PROV_CCM_HW ccm_sm4 = {
ccm_sm4_initkey,
ossl_ccm_generic_setiv,
ossl_ccm_generic_setaad,
ossl_ccm_generic_auth_encrypt,
ossl_ccm_generic_auth_decrypt,
ossl_ccm_generic_gettag
};

const PROV_CCM_HW *ossl_prov_sm4_hw_ccm(size_t keybits)
{
return &ccm_sm4;
}
40 changes: 40 additions & 0 deletions providers/implementations/ciphers/cipher_sm4_gcm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

/* Dispatch functions for SM4 GCM mode */

#include "cipher_sm4_gcm.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"

static OSSL_FUNC_cipher_freectx_fn sm4_gcm_freectx;

static void *sm4_gcm_newctx(void *provctx, size_t keybits)
{
PROV_SM4_GCM_CTX *ctx;

if (!ossl_prov_is_running())
return NULL;

ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx != NULL)
ossl_gcm_initctx(provctx, &ctx->base, keybits,
ossl_prov_sm4_hw_gcm(keybits));
return ctx;
}

static void sm4_gcm_freectx(void *vctx)
{
PROV_SM4_GCM_CTX *ctx = (PROV_SM4_GCM_CTX *)vctx;

OPENSSL_clear_free(ctx, sizeof(*ctx));
}

/* ossl_sm4128gcm_functions */
IMPLEMENT_aead_cipher(sm4, gcm, GCM, AEAD_FLAGS, 128, 8, 96);
22 changes: 22 additions & 0 deletions providers/implementations/ciphers/cipher_sm4_gcm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

#include "crypto/sm4.h"
#include "prov/ciphercommon.h"
#include "prov/ciphercommon_gcm.h"

typedef struct prov_sm4_gcm_ctx_st {
PROV_GCM_CTX base; /* must be first entry in struct */
union {
OSSL_UNION_ALIGN;
SM4_KEY ks;
} ks;
} PROV_SM4_GCM_CTX;

const PROV_GCM_HW *ossl_prov_sm4_hw_gcm(size_t keybits);
43 changes: 43 additions & 0 deletions providers/implementations/ciphers/cipher_sm4_gcm_hw.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

/*-
* Generic support for SM4 GCM.
*/

#include "cipher_sm4_gcm.h"

static int sm4_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
size_t keylen)
{
PROV_SM4_GCM_CTX *actx = (PROV_SM4_GCM_CTX *)ctx;
SM4_KEY *ks = &actx->ks.ks;

ctx->ks = ks;
ossl_sm4_set_key(key, ks);
CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)ossl_sm4_encrypt);
ctx->ctr = (ctr128_f)NULL;
ctx->key_set = 1;

return 1;
}

static const PROV_GCM_HW sm4_gcm = {
sm4_gcm_initkey,
ossl_gcm_setiv,
ossl_gcm_aad_update,
ossl_gcm_cipher_update,
ossl_gcm_cipher_final,
ossl_gcm_one_shot
};

const PROV_GCM_HW *ossl_prov_sm4_hw_gcm(size_t keybits)
{
return &sm4_gcm;
}
2 changes: 2 additions & 0 deletions providers/implementations/include/prov/implementations.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ extern const OSSL_DISPATCH ossl_seed128ofb128_functions[];
extern const OSSL_DISPATCH ossl_seed128cfb128_functions[];
#endif /* OPENSSL_NO_SEED */
#ifndef OPENSSL_NO_SM4
extern const OSSL_DISPATCH ossl_sm4128gcm_functions[];
extern const OSSL_DISPATCH ossl_sm4128ccm_functions[];
extern const OSSL_DISPATCH ossl_sm4128ecb_functions[];
extern const OSSL_DISPATCH ossl_sm4128cbc_functions[];
extern const OSSL_DISPATCH ossl_sm4128ctr_functions[];
Expand Down
2 changes: 2 additions & 0 deletions providers/implementations/include/prov/names.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@
#define PROV_NAMES_SM4_CTR "SM4-CTR:1.2.156.10197.1.104.7"
#define PROV_NAMES_SM4_OFB "SM4-OFB:SM4-OFB128:1.2.156.10197.1.104.3"
#define PROV_NAMES_SM4_CFB "SM4-CFB:SM4-CFB128:1.2.156.10197.1.104.4"
#define PROV_NAMES_SM4_GCM "SM4-GCM:1.2.156.10197.1.104.8"
#define PROV_NAMES_SM4_CCM "SM4-CCM:1.2.156.10197.1.104.9"
#define PROV_NAMES_ChaCha20 "ChaCha20"
#define PROV_NAMES_ChaCha20_Poly1305 "ChaCha20-Poly1305"
#define PROV_NAMES_CAST5_ECB "CAST5-ECB"
Expand Down
20 changes: 20 additions & 0 deletions test/recipes/30-test_evp_data/evpciph_sm4.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,23 @@ Key = 0123456789ABCDEFFEDCBA9876543210
IV = 0123456789ABCDEFFEDCBA9876543210
Plaintext = AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA
Ciphertext = C2B4759E78AC3CF43D0852F4E8D5F9FD7256E8A5FCB65A350EE00630912E44492A0B17E1B85B060D0FBA612D8A95831638B361FD5FFACD942F081485A83CA35D

Title = SM4 GCM test vectors from RFC8998

Cipher = SM4-GCM
Key = 0123456789abcdeffedcba9876543210
IV = 00001234567800000000abcd
AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
Tag = 83de3541e4c2b58177e065a9bf7b62ec
Plaintext = aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa
Ciphertext = 17f399f08c67d5ee19d0dc9969c4bb7d5fd46fd3756489069157b282bb200735d82710ca5c22f0ccfa7cbf93d496ac15a56834cbcf98c397b4024a2691233b8d

Title = SM4 CCM test vectors from RFC8998

Cipher = SM4-CCM
Key = 0123456789abcdeffedcba9876543210
IV = 00001234567800000000abcd
AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
Tag = 16842d4fa186f56ab33256971fa110f4
Plaintext = aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa
Ciphertext = 48af93501fa62adbcd414cce6034d895dda1bf8f132f042098661572e7483094fd12e518ce062c98acee28d95df4416bed31a2f04476c18bb40c84a74b97dc5b

0 comments on commit 8c39948

Please sign in to comment.