diff --git a/common/inc/params_parser.h b/common/inc/params_parser.h index 3912e8638e3b78dde38667a15cc4907d44f06a6d..6c356cb512a486cee702ece638716e3a36a4bfce 100644 --- a/common/inc/params_parser.h +++ b/common/inc/params_parser.h @@ -31,10 +31,12 @@ typedef enum { typedef enum { HCF_ALG_AES = 1, + HCF_ALG_SM4, HCF_ALG_DES, HCF_ALG_RSA, HCF_ALG_ECC, HCF_ALG_DSA, + HCF_ALG_SM2, } HcfAlgValue; typedef enum { @@ -46,6 +48,7 @@ typedef enum { HCF_ALG_AES_128, HCF_ALG_AES_192, HCF_ALG_AES_256, + HCF_ALG_SM4_128, HCF_ALG_3DES_192, HCF_ALG_MODE_NONE, @@ -82,6 +85,7 @@ typedef enum { // digest HCF_OPENSSL_DIGEST_NONE, HCF_OPENSSL_DIGEST_MD5, + HCF_OPENSSL_DIGEST_SM3, HCF_OPENSSL_DIGEST_SHA1, HCF_OPENSSL_DIGEST_SHA224, HCF_OPENSSL_DIGEST_SHA256, @@ -99,12 +103,17 @@ typedef enum { HCF_ALG_DSA_2048, HCF_ALG_DSA_3072, + //sm2 + HCF_ALG_SM2_256, + // 4.0 added: only for algName(NO SIZE) HCF_ALG_DSA_DEFAULT, HCF_ALG_RSA_DEFAULT, HCF_ALG_ECC_DEFAULT, HCF_ALG_AES_DEFAULT, + HCF_ALG_SM4_DEFAULT, HCF_ALG_3DES_DEFAULT, + HCF_ALG_SM2_DEFAULT, } HcfAlgParaValue; typedef struct { diff --git a/common/src/params_parser.c b/common/src/params_parser.c index 809fc6b353ad694e9048566225658bd42b5cc44e..edf87768274e8a7e3c7dd8283408a425245d5758 100644 --- a/common/src/params_parser.c +++ b/common/src/params_parser.c @@ -30,6 +30,7 @@ static const HcfParaConfig PARAM_CONFIG[] = { {"AES128", HCF_ALG_KEY_TYPE, HCF_ALG_AES_128}, {"AES192", HCF_ALG_KEY_TYPE, HCF_ALG_AES_192}, {"AES256", HCF_ALG_KEY_TYPE, HCF_ALG_AES_256}, + {"SM4", HCF_ALG_KEY_TYPE, HCF_ALG_SM4_128}, {"3DES192", HCF_ALG_KEY_TYPE, HCF_ALG_3DES_192}, {"ECB", HCF_ALG_MODE, HCF_ALG_MODE_ECB}, @@ -62,6 +63,7 @@ static const HcfParaConfig PARAM_CONFIG[] = { {"NoHash", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_NONE}, {"MD5", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_MD5}, + {"SM3", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_SM3}, {"SHA1", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_SHA1}, {"SHA224", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_SHA224}, {"SHA256", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_SHA256}, @@ -69,6 +71,7 @@ static const HcfParaConfig PARAM_CONFIG[] = { {"SHA512", HCF_ALG_DIGEST, HCF_OPENSSL_DIGEST_SHA512}, {"MGF1_MD5", HCF_ALG_MGF1_DIGEST, HCF_OPENSSL_DIGEST_MD5}, + {"MGF1_SM3", HCF_ALG_MGF1_DIGEST, HCF_OPENSSL_DIGEST_SM3}, {"MGF1_SHA1", HCF_ALG_MGF1_DIGEST, HCF_OPENSSL_DIGEST_SHA1}, {"MGF1_SHA224", HCF_ALG_MGF1_DIGEST, HCF_OPENSSL_DIGEST_SHA224}, {"MGF1_SHA256", HCF_ALG_MGF1_DIGEST, HCF_OPENSSL_DIGEST_SHA256}, @@ -84,17 +87,22 @@ static const HcfParaConfig PARAM_CONFIG[] = { {"DSA2048", HCF_ALG_KEY_TYPE, HCF_ALG_DSA_2048}, {"DSA3072", HCF_ALG_KEY_TYPE, HCF_ALG_DSA_3072}, + {"SM2256", HCF_ALG_KEY_TYPE, HCF_ALG_SM2_256}, + {"RSA", HCF_ALG_TYPE, HCF_ALG_RSA_DEFAULT}, {"DSA", HCF_ALG_TYPE, HCF_ALG_DSA_DEFAULT}, {"ECC", HCF_ALG_TYPE, HCF_ALG_ECC_DEFAULT}, {"AES", HCF_ALG_TYPE, HCF_ALG_AES_DEFAULT}, + {"SM4", HCF_ALG_TYPE, HCF_ALG_SM4_DEFAULT}, {"3DES", HCF_ALG_TYPE, HCF_ALG_3DES_DEFAULT}, + {"SM2", HCF_ALG_TYPE, HCF_ALG_SM2_DEFAULT}, }; static const HcfAlgMap ALG_MAP[] = { {"DSA", HCF_ALG_DSA}, {"RSA", HCF_ALG_RSA}, {"ECC", HCF_ALG_ECC}, + {"SM2", HCF_ALG_SM2}, }; static const HcfParaConfig *FindConfig(const HcString* tag) diff --git a/frameworks/crypto_operation/cipher.c b/frameworks/crypto_operation/cipher.c index 318e73df263f5aa197219242a227000befb202b8..0e64a4774f1a456fd272292e17103523d11ff452 100644 --- a/frameworks/crypto_operation/cipher.c +++ b/frameworks/crypto_operation/cipher.c @@ -23,6 +23,8 @@ #include "memory.h" #include "cipher_rsa_openssl.h" #include "utils.h" +#include "sm4_openssl.h" +#include "cipher_sm2_openssl.h" typedef HcfResult (*HcfCipherGeneratorSpiCreateFunc)(CipherAttr *, HcfCipherGeneratorSpi **); @@ -42,9 +44,11 @@ typedef struct { } HcfCipherGenAbility; static const HcfCipherGenAbility CIPHER_ABILITY_SET[] = { - { HCF_ALG_RSA, { HcfCipherRsaCipherSpiCreate } }, + { HCF_ALG_RSA, { HcfCipherRsaCipherSpiCreate } }, { HCF_ALG_AES, { HcfCipherAesGeneratorSpiCreate } }, - { HCF_ALG_DES, { HcfCipherDesGeneratorSpiCreate } } + { HCF_ALG_SM4, { HcfCipherSm4GeneratorSpiCreate } }, + { HCF_ALG_DES, { HcfCipherDesGeneratorSpiCreate } }, + { HCF_ALG_SM2, { HcfCipherSm2CipherSpiCreate } } }; static void SetKeyType(HcfAlgParaValue value, void *cipher) @@ -57,12 +61,18 @@ static void SetKeyType(HcfAlgParaValue value, void *cipher) case HCF_ALG_AES_DEFAULT: cipherAttr->algo = HCF_ALG_AES; break; + case HCF_ALG_SM4_DEFAULT: + cipherAttr->algo = HCF_ALG_SM4; + break; case HCF_ALG_3DES_DEFAULT: cipherAttr->algo = HCF_ALG_DES; break; case HCF_ALG_RSA_DEFAULT: cipherAttr->algo = HCF_ALG_RSA; break; + case HCF_ALG_SM2_DEFAULT: + cipherAttr->algo = HCF_ALG_SM2; + break; default: LOGE("Invalid algo %u.", value); break; @@ -81,6 +91,9 @@ static void SetKeyLength(HcfAlgParaValue value, void *cipher) case HCF_ALG_AES_256: cipherAttr->algo = HCF_ALG_AES; break; + case HCF_ALG_SM4_128: + cipherAttr->algo = HCF_ALG_SM4; + break; case HCF_ALG_3DES_192: cipherAttr->algo = HCF_ALG_DES; break; @@ -93,6 +106,9 @@ static void SetKeyLength(HcfAlgParaValue value, void *cipher) case HCF_OPENSSL_RSA_8192: cipherAttr->algo = HCF_ALG_RSA; break; + case HCF_ALG_SM2_256: + cipherAttr->algo = HCF_ALG_SM2; + break; default: LOGE("Invalid algo %u.", value); break; diff --git a/frameworks/crypto_operation/mac.c b/frameworks/crypto_operation/mac.c index 22e1bb93741ed448b743c586e5bf0c6600197ef0..7f7e0436c0979ac9514a4d6fad553b588e5e3f3d 100644 --- a/frameworks/crypto_operation/mac.c +++ b/frameworks/crypto_operation/mac.c @@ -42,11 +42,12 @@ typedef struct { } HcfMacAbility; static const HcfMacAbility MAC_ABILITY_SET[] = { - { "SHA1", OpensslMacSpiCreate }, + { "SHA1", OpensslMacSpiCreate }, { "SHA224", OpensslMacSpiCreate }, { "SHA256", OpensslMacSpiCreate }, { "SHA384", OpensslMacSpiCreate }, { "SHA512", OpensslMacSpiCreate }, + { "SM3", OpensslMacSpiCreate }, }; static const char *GetMacClass(void) diff --git a/frameworks/crypto_operation/md.c b/frameworks/crypto_operation/md.c index ed231ce37bb8a61359b7f6d592a59b40768a35f4..fb85429c47a729809e79cabcfca5cc99476d21b5 100644 --- a/frameworks/crypto_operation/md.c +++ b/frameworks/crypto_operation/md.c @@ -49,6 +49,7 @@ static const HcfMdAbility MD_ABILITY_SET[] = { { "SHA384", OpensslMdSpiCreate }, { "SHA512", OpensslMdSpiCreate }, { "MD5", OpensslMdSpiCreate }, + { "SM3", OpensslMdSpiCreate }, }; static const char *GetMdClass(void) diff --git a/frameworks/crypto_operation/signature.c b/frameworks/crypto_operation/signature.c index d84ee23cfa08513e4c705181df4e61a1cf38ffd8..631354a9832df99e32e641c9053710cdde1c36fd 100644 --- a/frameworks/crypto_operation/signature.c +++ b/frameworks/crypto_operation/signature.c @@ -20,6 +20,7 @@ #include "config.h" #include "dsa_openssl.h" #include "ecdsa_openssl.h" +#include "sm2_openssl.h" #include "log.h" #include "memory.h" #include "params_parser.h" @@ -61,13 +62,15 @@ typedef struct { static const HcfSignGenAbility SIGN_GEN_ABILITY_SET[] = { { HCF_ALG_ECC, HcfSignSpiEcdsaCreate }, { HCF_ALG_RSA, HcfSignSpiRsaCreate }, - { HCF_ALG_DSA, HcfSignSpiDsaCreate } + { HCF_ALG_DSA, HcfSignSpiDsaCreate }, + { HCF_ALG_SM2, HcfSignSpiSm2Create } }; static const HcfVerifyGenAbility VERIFY_GEN_ABILITY_SET[] = { { HCF_ALG_ECC, HcfVerifySpiEcdsaCreate }, { HCF_ALG_RSA, HcfVerifySpiRsaCreate }, - { HCF_ALG_DSA, HcfVerifySpiDsaCreate } + { HCF_ALG_DSA, HcfVerifySpiDsaCreate }, + { HCF_ALG_SM2, HcfVerifySpiSm2Create } }; static HcfSignSpiCreateFunc FindSignAbility(HcfSignatureParams *params) @@ -104,6 +107,9 @@ static void SetKeyTypeDefault(HcfAlgParaValue value, HcfSignatureParams *params case HCF_ALG_DSA_DEFAULT: paramsObj->algo = HCF_ALG_DSA; break; + case HCF_ALG_SM2_DEFAULT: + paramsObj->algo = HCF_ALG_SM2; + break; default: LOGE("Invalid algo %u.", value); break; @@ -133,6 +139,9 @@ static void SetKeyType(HcfAlgParaValue value, HcfSignatureParams *paramsObj) case HCF_ALG_DSA_3072: paramsObj->algo = HCF_ALG_DSA; break; + case HCF_ALG_SM2_256: + paramsObj->algo = HCF_ALG_SM2; + break; default: LOGE("there is not matched algorithm."); break; diff --git a/frameworks/key/asy_key_generator.c b/frameworks/key/asy_key_generator.c index 1c3be94632253810d2bd6b3ae4e35d3cfc3afcfa..a24a57084b556c5b1a58d86051ae5571fc576f19 100644 --- a/frameworks/key/asy_key_generator.c +++ b/frameworks/key/asy_key_generator.c @@ -24,6 +24,7 @@ #include "detailed_ecc_key_params.h" #include "dsa_asy_key_generator_openssl.h" #include "ecc_asy_key_generator_openssl.h" +#include "sm2_asy_key_generator_openssl.h" #include "params_parser.h" #include "rsa_asy_key_generator_openssl.h" #include "log.h" @@ -63,7 +64,8 @@ typedef struct { static const HcfAsyKeyGenAbility ASY_KEY_GEN_ABILITY_SET[] = { { HCF_ALG_RSA, HcfAsyKeyGeneratorSpiRsaCreate }, { HCF_ALG_ECC, HcfAsyKeyGeneratorSpiEccCreate }, - { HCF_ALG_DSA, HcfAsyKeyGeneratorSpiDsaCreate } + { HCF_ALG_DSA, HcfAsyKeyGeneratorSpiDsaCreate }, + { HCF_ALG_SM2, HcfAsyKeyGeneratorSpiSm2Create } }; typedef struct { @@ -87,7 +89,8 @@ static const KeyTypeAlg KEY_TYPE_MAP[] = { { HCF_OPENSSL_RSA_8192, HCF_RSA_KEY_SIZE_8192, HCF_ALG_RSA }, { HCF_ALG_DSA_1024, HCF_DSA_KEY_SIZE_1024, HCF_ALG_DSA }, { HCF_ALG_DSA_2048, HCF_DSA_KEY_SIZE_2048, HCF_ALG_DSA }, - { HCF_ALG_DSA_3072, HCF_DSA_KEY_SIZE_3072, HCF_ALG_DSA } + { HCF_ALG_DSA_3072, HCF_DSA_KEY_SIZE_3072, HCF_ALG_DSA }, + { HCF_ALG_SM2_256, HCF_ALG_SM2_256, HCF_ALG_SM2} }; static bool IsDsaCommParamsSpecValid(HcfDsaCommParamsSpec *paramsSpec) { diff --git a/frameworks/key/sym_key_generator.c b/frameworks/key/sym_key_generator.c index 5f75a7b6345c4e46f5f84558370229749caada96..4a5b430ab022a732e998ce1b048115bf39c1f8de 100644 --- a/frameworks/key/sym_key_generator.c +++ b/frameworks/key/sym_key_generator.c @@ -28,6 +28,7 @@ #define AES_KEY_SIZE_128 128 #define AES_KEY_SIZE_192 192 #define AES_KEY_SIZE_256 256 +#define SM4_KEY_SIZE_128 128 #define DES_KEY_SIZE_192 192 typedef HcfResult (*SymKeyGeneratorSpiCreateFunc)(SymKeyAttr *, HcfSymKeyGeneratorSpi **); @@ -49,6 +50,7 @@ typedef struct { static const SymKeyGenAbility SYMKEY_ABILITY_SET[] = { { HCF_ALG_AES, { HcfSymKeyGeneratorSpiCreate }}, + { HCF_ALG_SM4, { HcfSymKeyGeneratorSpiCreate }}, { HCF_ALG_DES, { HcfSymKeyGeneratorSpiCreate }} }; @@ -83,6 +85,9 @@ static void SetKeyLength(HcfAlgParaValue value, void *attr) keyAttr->algo = HCF_ALG_AES; keyAttr->keySize = AES_KEY_SIZE_256; break; + case HCF_ALG_SM4_128: + keyAttr->algo = HCF_ALG_SM4; + keyAttr->keySize = SM4_KEY_SIZE_128; case HCF_ALG_3DES_192: keyAttr->algo = HCF_ALG_DES; keyAttr->keySize = DES_KEY_SIZE_192; diff --git a/plugin/openssl_plugin/common/inc/aes_openssl_common.h b/plugin/openssl_plugin/common/inc/aes_openssl_common.h index be339aa60a229dae89ee919f3165b03ce4d9671e..e0fd5d53ea3705972987e3483c961dbf97eb5b28 100644 --- a/plugin/openssl_plugin/common/inc/aes_openssl_common.h +++ b/plugin/openssl_plugin/common/inc/aes_openssl_common.h @@ -22,6 +22,7 @@ #include "detailed_iv_params.h" #include "detailed_ccm_params.h" #include "detailed_gcm_params.h" +#include "sm4_openssl.h" typedef struct { EVP_CIPHER_CTX *ctx; diff --git a/plugin/openssl_plugin/common/inc/openssl_adapter.h b/plugin/openssl_plugin/common/inc/openssl_adapter.h index 631a5157aaaa42fa07d5ac581b3dc1d9d7c96da4..463fa95f6f91e350f66598f4c26660b17a564c5a 100644 --- a/plugin/openssl_plugin/common/inc/openssl_adapter.h +++ b/plugin/openssl_plugin/common/inc/openssl_adapter.h @@ -103,6 +103,7 @@ int Openssl_EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t size_t tbslen); EVP_PKEY *Openssl_EVP_PKEY_new(void); +int Openssl_EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); int Openssl_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); void Openssl_EVP_PKEY_free(EVP_PKEY *pkey); @@ -120,6 +121,9 @@ int Openssl_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outl int Openssl_EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); int Openssl_EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_CTX_encrypt_ctrl(EVP_PKEY_CTX* ctx); +int Openssl_EVP_PKEY_CTX_decrypt_ctrl(EVP_PKEY_CTX* ctx); + EVP_PKEY_CTX *Openssl_EVP_PKEY_CTX_new_id(int id, ENGINE *e); int Openssl_EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); int Openssl_EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits); @@ -188,6 +192,7 @@ const EVP_MD *Openssl_EVP_sha256(void); const EVP_MD *Openssl_EVP_sha384(void); const EVP_MD *Openssl_EVP_sha512(void); const EVP_MD *Openssl_EVP_md5(void); +const EVP_MD *Openssl_EVP_sm3(void); int Openssl_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size); int Openssl_EVP_MD_CTX_size(const EVP_MD_CTX *ctx); int Openssl_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); @@ -229,6 +234,12 @@ const EVP_CIPHER *Openssl_EVP_aes_256_ccm(void); const EVP_CIPHER *Openssl_EVP_aes_128_gcm(void); const EVP_CIPHER *Openssl_EVP_aes_192_gcm(void); const EVP_CIPHER *Openssl_EVP_aes_256_gcm(void); +const EVP_CIPHER *Openssl_EVP_sm4_ecb(void); +const EVP_CIPHER *Openssl_EVP_sm4_cbc(void); +const EVP_CIPHER *Openssl_EVP_sm4_cfb(void); +const EVP_CIPHER *Openssl_EVP_sm4_cfb128(void); +const EVP_CIPHER *Openssl_EVP_sm4_ctr(void); +const EVP_CIPHER *Openssl_EVP_sm4_ofb(void); const EVP_CIPHER *Openssl_EVP_des_ede3_ecb(void); const EVP_CIPHER *Openssl_EVP_des_ede3_cbc(void); const EVP_CIPHER *Openssl_EVP_des_ede3_ofb(void); diff --git a/plugin/openssl_plugin/common/inc/openssl_class.h b/plugin/openssl_plugin/common/inc/openssl_class.h index 0847695157a844c6fb1a3de613da6ae2f6707d23..fcaf9423d878fe7e1635a3b09c4e7c67d6e5f05a 100644 --- a/plugin/openssl_plugin/common/inc/openssl_class.h +++ b/plugin/openssl_plugin/common/inc/openssl_class.h @@ -95,8 +95,33 @@ typedef struct { } HcfOpensslDsaKeyPair; #define OPENSSL_DSA_KEYPAIR_CLASS "OPENSSL.DSA.KEY_PAIR" +typedef struct { + HcfPubKey base; + + int32_t curveId; + + EC_KEY *ecKey; +} HcfOpensslSm2PubKey; +#define HCF_OPENSSL_SM2_PUB_KEY_CLASS "OPENSSL.SM2.PUB_KEY" + +typedef struct { + HcfPriKey base; + + int32_t curveId; + + EC_KEY *ecKey; +} HcfOpensslSm2PriKey; +#define HCF_OPENSSL_SM2_PRI_KEY_CLASS "OPENSSL.SM2.PRI_KEY" + +typedef struct { + HcfKeyPair base; +} HcfOpensslSm2KeyPair; +#define HCF_OPENSSL_SM2_KEY_PAIR_CLASS "OPENSSL.SM2.KEY_PAIR" + #define OPENSSL_RSA_CIPHER_CLASS "OPENSSL.RSA.CIPHER" #define OPENSSL_3DES_CIPHER_CLASS "OPENSSL.3DES.CIPHER" #define OPENSSL_AES_CIPHER_CLASS "OPENSSL.AES.CIPHER" +#define OPENSSL_SM4_CIPHER_CLASS "OPENSSL.SM4.CIPHER" +#define OPENSSL_SM2_CIPHER_CLASS "OPENSSL.SM2.CIPHER" #endif diff --git a/plugin/openssl_plugin/common/inc/sm2_openssl_common.h b/plugin/openssl_plugin/common/inc/sm2_openssl_common.h new file mode 100644 index 0000000000000000000000000000000000000000..14a994c889ad033702bdf3413006e1f192cf0bae --- /dev/null +++ b/plugin/openssl_plugin/common/inc/sm2_openssl_common.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HCF_SM2_OPENSSL_COMMON_H +#define HCF_SM2_OPENSSL_COMMON_H + +#include "openssl/evp.h" +#include "result.h" +#include "stdbool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +EVP_PKEY *NewEvpPkeyBySm2(EC_KEY *sm2, bool withDuplicate); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/plugin/openssl_plugin/common/src/openssl_adapter.c b/plugin/openssl_plugin/common/src/openssl_adapter.c index 97794ba22777c13858f43d76fbaf3309ccbd1b92..7c501f4d3d988cfa45c627fd4ce39919b7a00f53 100644 --- a/plugin/openssl_plugin/common/src/openssl_adapter.c +++ b/plugin/openssl_plugin/common/src/openssl_adapter.c @@ -14,10 +14,15 @@ */ #include "openssl_adapter.h" - #include "log.h" #include "result.h" +static int EVP_PKEY_CTRL_SM2_ENCRYPT_C1C3C2 = 1; +//static int EVP_PKEY_CTRL_SM2_ENCRYPT_C1C2C3 = 0; + +# define EVP_PKEY_OP_ENCRYPT (1<<9) +# define EVP_PKEY_OP_DECRYPT (1<<10) + BIGNUM *Openssl_BN_dup(const BIGNUM *a) { return BN_dup(a); @@ -406,6 +411,16 @@ int Openssl_EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) return EVP_PKEY_decrypt_init(ctx); } +int Openssl_EVP_PKEY_CTX_encrypt_ctrl(EVP_PKEY_CTX* ctx) +{ + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SM2_ENCRYPT_C1C3C2, 1, NULL); +} + +int Openssl_EVP_PKEY_CTX_decrypt_ctrl(EVP_PKEY_CTX* ctx) +{ + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DECRYPT, EVP_PKEY_CTRL_SM2_ENCRYPT_C1C3C2, 1, NULL); +} + EVP_PKEY_CTX *Openssl_EVP_PKEY_CTX_new_id(int id, ENGINE *e) { return EVP_PKEY_CTX_new_id(id, e); @@ -718,6 +733,11 @@ const EVP_MD *Openssl_EVP_md5(void) return EVP_md5(); } +const EVP_MD *Openssl_EVP_sm3(void) +{ + return EVP_sm3(); +} + int Openssl_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) { return EVP_DigestFinal_ex(ctx, md, size); @@ -913,6 +933,36 @@ const EVP_CIPHER *Openssl_EVP_aes_256_gcm(void) return EVP_aes_256_gcm(); } +const EVP_CIPHER *Openssl_EVP_sm4_ecb(void) +{ + return EVP_sm4_ecb(); +} + +const EVP_CIPHER *Openssl_EVP_sm4_cbc(void) +{ + return EVP_sm4_cbc(); +} + +const EVP_CIPHER *Openssl_EVP_sm4_cfb(void) +{ + return EVP_sm4_cfb(); +} + +const EVP_CIPHER *Openssl_EVP_sm4_cfb128(void) +{ + return EVP_sm4_cfb128(); +} + +const EVP_CIPHER *Openssl_EVP_sm4_ctr(void) +{ + return EVP_sm4_ctr(); +} + +const EVP_CIPHER *Openssl_EVP_sm4_ofb(void) +{ + return EVP_sm4_ofb(); +} + EVP_CIPHER_CTX *Openssl_EVP_CIPHER_CTX_new(void) { return EVP_CIPHER_CTX_new(); @@ -972,4 +1022,9 @@ const EVP_CIPHER *Openssl_EVP_des_ede3_cfb1(void) const EVP_CIPHER *Openssl_EVP_des_ede3_cfb8(void) { return EVP_des_ede3_cfb8(); +} + +int Openssl_EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key) +{ + return EVP_PKEY_set1_EC_KEY(pkey, key); } \ No newline at end of file diff --git a/plugin/openssl_plugin/common/src/openssl_common.c b/plugin/openssl_plugin/common/src/openssl_common.c index 764d238bf186e9f5a130762b209f519d5fd8d307..3972c81e07aadd4959fbfd596a9b27ee35774e18 100644 --- a/plugin/openssl_plugin/common/src/openssl_common.c +++ b/plugin/openssl_plugin/common/src/openssl_common.c @@ -33,6 +33,7 @@ #define HCF_OPENSSL_DIGEST_NONE_STR "NONE" #define HCF_OPENSSL_DIGEST_MD5_STR "MD5" +#define HCF_OPENSSL_DIGEST_SM3_STR "SM3" #define HCF_OPENSSL_DIGEST_SHA1_STR "SHA1" #define HCF_OPENSSL_DIGEST_SHA224_STR "SHA224" #define HCF_OPENSSL_DIGEST_SHA256_STR "SHA256" @@ -51,6 +52,9 @@ HcfResult GetOpensslCurveId(int32_t keyLen, int32_t *returnCurveId) case HCF_ALG_ECC_256: *returnCurveId = NID_X9_62_prime256v1; break; + case HCF_ALG_SM2_256: + *returnCurveId = NID_sm2; + break; case HCF_ALG_ECC_384: *returnCurveId = NID_secp384r1; break; @@ -78,6 +82,9 @@ HcfResult GetOpensslDigestAlg(uint32_t alg, EVP_MD **digestAlg) case HCF_OPENSSL_DIGEST_MD5: *digestAlg = (EVP_MD *)EVP_md5(); break; + case HCF_OPENSSL_DIGEST_SM3: + *digestAlg = (EVP_MD *)EVP_sm3(); + break; case HCF_OPENSSL_DIGEST_SHA1: *digestAlg = (EVP_MD *)EVP_sha1(); break; @@ -111,6 +118,9 @@ HcfResult GetRsaSpecStringMd(const HcfAlgParaValue md, char **returnString) case HCF_OPENSSL_DIGEST_MD5: tmp = HCF_OPENSSL_DIGEST_MD5_STR; break; + case HCF_OPENSSL_DIGEST_SM3: + tmp = HCF_OPENSSL_DIGEST_SM3_STR; + break; case HCF_OPENSSL_DIGEST_SHA1: tmp = HCF_OPENSSL_DIGEST_SHA1_STR; break; diff --git a/plugin/openssl_plugin/common/src/sm2_openssl_common.c b/plugin/openssl_plugin/common/src/sm2_openssl_common.c new file mode 100644 index 0000000000000000000000000000000000000000..910ff1f3205b9ab6c66ad0f7f861373d996c23f6 --- /dev/null +++ b/plugin/openssl_plugin/common/src/sm2_openssl_common.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sm2_openssl_common.h" +#include "log.h" +#include "openssl_adapter.h" +#include "openssl_common.h" + +EVP_PKEY *NewEvpPkeyBySm2(EC_KEY *sm2, bool withDuplicate) +{ + if (sm2 == NULL) { + LOGE("RSA is NULL"); + return NULL; + } + EVP_PKEY *pKey = Openssl_EVP_PKEY_new(); + if (pKey == NULL) { + LOGE("EVP_PKEY_new fail"); + HcfPrintOpensslError(); + return NULL; + } + if (withDuplicate) { + if (Openssl_EVP_PKEY_set1_EC_KEY(pKey, sm2) != HCF_OPENSSL_SUCCESS) { + LOGE("EVP_PKEY_set1_EC_KEY fail"); + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return NULL; + } + } else { + if (Openssl_EVP_PKEY_assign_EC_KEY(pKey, sm2) != HCF_OPENSSL_SUCCESS) { + LOGE("EVP_PKEY_assign_EC_KEY fail"); + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return NULL; + } + } + return pKey; +} diff --git a/plugin/openssl_plugin/crypto_operation/cipher/inc/cipher_sm2_openssl.h b/plugin/openssl_plugin/crypto_operation/cipher/inc/cipher_sm2_openssl.h new file mode 100644 index 0000000000000000000000000000000000000000..d0a648273373cede78283bef769da86054e94a4e --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/cipher/inc/cipher_sm2_openssl.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HCF_CIPHER_SM2_OPENSSL_H +#define HCF_CIPHER_SM2_OPENSSL_H + +#include "cipher_factory_spi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +HcfResult HcfCipherSm2CipherSpiCreate(CipherAttr *params, HcfCipherGeneratorSpi **generator); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/cipher/inc/sm4_openssl.h b/plugin/openssl_plugin/crypto_operation/cipher/inc/sm4_openssl.h new file mode 100644 index 0000000000000000000000000000000000000000..b7c29539f21e5b649dda228dcb93b0ad6bfc7f0b --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/cipher/inc/sm4_openssl.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef HCF_SM4_OPENSSL_H +#define HCF_SM4_OPENSSL_H + +#include "cipher_factory_spi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +HcfResult HcfCipherSm4GeneratorSpiCreate(CipherAttr *attr, HcfCipherGeneratorSpi **generator); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm2_openssl.c b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm2_openssl.c new file mode 100644 index 0000000000000000000000000000000000000000..9dc5ae5df786ad4e5105dbb836950dd41dc5a464 --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm2_openssl.c @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cipher_sm2_openssl.h" +#include "securec.h" +#include "sm2_openssl_common.h" +#include "log.h" +#include "memory.h" +#include "openssl_adapter.h" +#include "openssl_class.h" +#include "openssl_common.h" +#include "stdbool.h" +#include "string.h" +#include "utils.h" + +static const char *EngineGetClass(void); + +typedef struct { + HcfCipherGeneratorSpi super; + + CipherAttr attr; + + CryptoStatus initFlag; + + EVP_PKEY_CTX *ctx; + + HcfBlob pSource; +} HcfCipherSm2GeneratorSpiImpl; + +static HcfResult CheckCipherInitParams(enum HcfCryptoMode opMode, HcfKey *key) +{ + switch (opMode) { + case ENCRYPT_MODE: + if (!IsClassMatch((HcfObjectBase *)key, HCF_OPENSSL_SM2_PUB_KEY_CLASS)) { + LOGE("Class not match"); + return HCF_INVALID_PARAMS; + } + break; + case DECRYPT_MODE: + if (!IsClassMatch((HcfObjectBase *)key, HCF_OPENSSL_SM2_PRI_KEY_CLASS)) { + LOGE("Class not match"); + return HCF_INVALID_PARAMS; + } + break; + default: + LOGE("Invalid opMode %u", opMode); + return HCF_INVALID_PARAMS; + } + + return HCF_SUCCESS; +} + +static HcfResult InitEvpPkeyCtx(HcfCipherSm2GeneratorSpiImpl *impl, HcfKey *key, enum HcfCryptoMode opMode) +{ + EC_KEY *ecKey = NULL; + + if (opMode == ENCRYPT_MODE) { + ecKey = Openssl_EC_KEY_dup(((HcfOpensslSm2PubKey *)key)->ecKey); + } else if (opMode == DECRYPT_MODE) { + ecKey = Openssl_EC_KEY_dup(((HcfOpensslSm2PriKey *)key)->ecKey); + } else { + LOGE("OpMode not match."); + return HCF_INVALID_PARAMS; + } + if (ecKey == NULL) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (ecKey == NULL) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + EVP_PKEY *pkey = NewEvpPkeyBySm2(ecKey, false); + if (pkey == NULL) { + LOGE("NewEvpPkeyBySm2 fail"); + HcfPrintOpensslError(); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (impl->ctx == NULL) { + LOGE("EVP_PKEY_CTX_new fail"); + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pkey); + return HCF_ERR_CRYPTO_OPERATION; + } + int32_t sslRet = HCF_OPENSSL_SUCCESS; + if (opMode == ENCRYPT_MODE) { + sslRet = Openssl_EVP_PKEY_encrypt_init(impl->ctx); + } else { + sslRet = Openssl_EVP_PKEY_decrypt_init(impl->ctx); + } + if (sslRet != HCF_OPENSSL_SUCCESS) { + LOGE("Init EVP_PKEY fail"); + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pkey); + Openssl_EVP_PKEY_CTX_free(impl->ctx); + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EVP_PKEY_free(pkey); + return HCF_SUCCESS; +} + +static HcfResult EngineInit(HcfCipherGeneratorSpi *self, enum HcfCryptoMode opMode, + HcfKey *key, HcfParamsSpec *params) +{ + (void)params; + if (self == NULL || key == NULL) { + LOGE("Param is invalid."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) { + LOGE("Class not match"); + return HCF_INVALID_PARAMS; + } + HcfCipherSm2GeneratorSpiImpl *impl = (HcfCipherSm2GeneratorSpiImpl *)self; + if (impl->initFlag != UNINITIALIZED) { + LOGE("The cipher has been initialize, don't init again."); + return HCF_INVALID_PARAMS; + } + + // check opMode is matched with Key + if (CheckCipherInitParams(opMode, key) != HCF_SUCCESS) { + LOGE("OpMode dismatch with keyType."); + return HCF_INVALID_PARAMS; + } + impl->attr.mode = (int32_t)opMode; + if (InitEvpPkeyCtx(impl, key, opMode) != HCF_SUCCESS) { + LOGE("InitEvpPkeyCtx fail"); + return HCF_ERR_CRYPTO_OPERATION; + } + + impl->initFlag = INITIALIZED; + return HCF_SUCCESS; +clearup: + FreeCipherData(&(impl->cipherData)); + return ret; +} + +static HcfResult EngineUpdate(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output) +{ + LOGE("Openssl don't support update"); + (void)self; + (void)input; + (void)output; + return HCF_NOT_SUPPORT; +} + +static HcfResult DoSm2Crypt(EVP_PKEY_CTX *ctx, HcfBlob *input, HcfBlob *output, int32_t mode) +{ + int32_t ret = HCF_OPENSSL_SUCCESS; + if (mode == ENCRYPT_MODE) { + ret = Openssl_EVP_PKEY_encrypt(ctx, output->data, &output->len, input->data, input->len); + } else if (mode == DECRYPT_MODE) { + ret = Openssl_EVP_PKEY_decrypt(ctx, output->data, &output->len, input->data, input->len); + } else { + LOGE("OpMode is invalid."); + return HCF_INVALID_PARAMS; + } + if (ret != HCF_OPENSSL_SUCCESS) { + LOGE("SM2 openssl error"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult EngineDoFinal(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output) +{ + if (self == NULL || input == NULL || input->data == NULL) { + LOGE("Param is invalid."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, EngineGetClass())) { + LOGE("Class not match"); + return HCF_INVALID_PARAMS; + } + HcfCipherSm2GeneratorSpiImpl *impl = (HcfCipherSm2GeneratorSpiImpl *)self; + if (impl->initFlag != INITIALIZED) { + LOGE("SM2Cipher has not been init"); + return HCF_INVALID_PARAMS; + } + CipherAttr attr = impl->attr; + output->len = 0; + output->data = NULL; + HcfResult ret = DoSm2Crypt(impl->ctx, input, output, attr.mode); + if (ret != HCF_SUCCESS) { + LOGE("GetOutLen fail."); + return HCF_ERR_CRYPTO_OPERATION; + } + LOGD("ouput data len is %zu.", output->len); + + output->data = (uint8_t *)HcfMalloc(sizeof(uint8_t) * output->len, 0); + ret = DoSm2Crypt(impl->ctx, input, output, attr.mode); + if (ret != HCF_SUCCESS) { + HcfFree(output->data); + output->data = NULL; + output->len = 0; + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static void EngineDestroySpiImpl(HcfObjectBase *generator) +{ + if (generator == NULL) { + return; + } + if (!IsClassMatch((HcfObjectBase *)generator, EngineGetClass())) { + LOGE("Class not match"); + return; + } + HcfCipherSm2GeneratorSpiImpl *impl = (HcfCipherSm2GeneratorSpiImpl *)generator; + Openssl_EVP_PKEY_CTX_free(impl->ctx); + impl->ctx = NULL; + HcfFree(impl->pSource.data); + impl->pSource.data = NULL; + HcfFree(impl); + impl = NULL; +} + +static const char *EngineGetClass(void) +{ + return OPENSSL_SM2_CIPHER_CLASS; +} + +HcfResult HcfCipherSm2CipherSpiCreate(CipherAttr *params, HcfCipherGeneratorSpi **generator) +{ + if (generator == NULL || params == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + HcfCipherSm2GeneratorSpiImpl *returnImpl = (HcfCipherSm2GeneratorSpiImpl *)HcfMalloc( + sizeof(HcfCipherSm2GeneratorSpiImpl), 0); + if (returnImpl == NULL) { + LOGE("Malloc sm2 cipher fail."); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(&returnImpl->attr, sizeof(CipherAttr), params, sizeof(CipherAttr)); + + returnImpl->super.init = EngineInit; + returnImpl->super.update = EngineUpdate; + returnImpl->super.doFinal = EngineDoFinal; + returnImpl->super.base.destroy = EngineDestroySpiImpl; + returnImpl->super.base.getClass = EngineGetClass; + returnImpl->initFlag = UNINITIALIZED; + *generator = (HcfCipherGeneratorSpi *)returnImpl; + LOGD("Sm2 Cipher create success."); + return HCF_SUCCESS; +} \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm4_openssl.c b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm4_openssl.c new file mode 100644 index 0000000000000000000000000000000000000000..6a5fb69e78dab9ca34c3ce10f3566587af03453c --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm4_openssl.c @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "securec.h" +#include "blob.h" +#include "log.h" +#include "memory.h" +#include "result.h" +#include "utils.h" +#include "aes_openssl_common.h" +#include "sm4_openssl.h" +#include "sym_common_defines.h" +#include "openssl_adapter.h" +#include "openssl_common.h" +#include "openssl_class.h" + +#define MAX_AAD_LEN 2048 +#define SM4_BLOCK_SIZE 16 +#define SM4_SIZE_128 16 + +typedef struct { + HcfCipherGeneratorSpi base; + CipherAttr attr; + CipherData *cipherData; +} HcfCipherSm4GeneratorSpiOpensslImpl; + +static const char *GetSm4GeneratorClass(void) +{ + return OPENSSL_SM4_CIPHER_CLASS; +} + +static const EVP_CIPHER *CipherEcbType(SymKeyImpl *symKey) +{ + switch (symKey->keyMaterial.len) { + case SM4_SIZE_128: + return Openssl_EVP_sm4_ecb(); + default: + break; + } + return Openssl_EVP_sm4_ecb(); +} + +static const EVP_CIPHER *CipherCbcType(SymKeyImpl *symKey) +{ + switch (symKey->keyMaterial.len) { + case SM4_SIZE_128: + return Openssl_EVP_sm4_cbc(); + default: + break; + } + return Openssl_EVP_sm4_cbc(); +} + +static const EVP_CIPHER *CipherCtrType(SymKeyImpl *symKey) +{ + switch (symKey->keyMaterial.len) { + case SM4_SIZE_128: + return Openssl_EVP_sm4_ctr(); + default: + break; + } + return Openssl_EVP_sm4_ctr(); +} + +static const EVP_CIPHER *CipherOfbType(SymKeyImpl *symKey) +{ + switch (symKey->keyMaterial.len) { + case SM4_SIZE_128: + return Openssl_EVP_sm4_ofb(); + default: + break; + } + return Openssl_EVP_sm4_ofb(); +} + +static const EVP_CIPHER *CipherCfbType(SymKeyImpl *symKey) +{ + switch (symKey->keyMaterial.len) { + case SM4_SIZE_128: + return Openssl_EVP_sm4_cfb(); + default: + break; + } + return Openssl_EVP_sm4_cfb(); +} + +static const EVP_CIPHER *CipherCfb128Type(SymKeyImpl *symKey) +{ + switch (symKey->keyMaterial.len) { + case SM4_SIZE_128: + return Openssl_EVP_sm4_cfb128(); + default: + break; + } + return Openssl_EVP_sm4_cfb128(); +} + +static const EVP_CIPHER *DefaultCiherType(SymKeyImpl *symKey) +{ + return CipherEcbType(symKey); +} + +static const EVP_CIPHER *GetCipherType(HcfCipherSm4GeneratorSpiOpensslImpl *impl, SymKeyImpl *symKey) +{ + switch (impl->attr.mode) { + case HCF_ALG_MODE_ECB: + return CipherEcbType(symKey); + case HCF_ALG_MODE_CBC: + return CipherCbcType(symKey); + case HCF_ALG_MODE_CTR: + return CipherCtrType(symKey); + case HCF_ALG_MODE_OFB: + return CipherOfbType(symKey); + case HCF_ALG_MODE_CFB: + return CipherCfbType(symKey); + case HCF_ALG_MODE_CFB128: + return CipherCfb128Type(symKey); + default: + break; + } + return DefaultCiherType(symKey); +} + +static HcfResult InitCipherData(enum HcfCryptoMode opMode, CipherData **cipherData) +{ + HcfResult ret = HCF_INVALID_PARAMS; + + *cipherData = (CipherData *)HcfMalloc(sizeof(CipherData), 0); + if (*cipherData == NULL) { + LOGE("malloc failed."); + return HCF_ERR_MALLOC; + } + + (*cipherData)->enc = opMode; + (*cipherData)->ctx = Openssl_EVP_CIPHER_CTX_new(); + if ((*cipherData)->ctx == NULL) { + HcfPrintOpensslError(); + LOGE("Failed to allocate ctx memroy."); + goto clearup; + } + + ret = HCF_SUCCESS; + return ret; +clearup: + FreeCipherData(cipherData); + return ret; +} + +static HcfResult EngineCipherInit(HcfCipherGeneratorSpi* self, enum HcfCryptoMode opMode, + HcfKey* key, HcfParamsSpec* params) +{ + if ((self == NULL) || (key == NULL)) { /* params maybe is null */ + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((const HcfObjectBase*)self, GetSm4GeneratorClass())) { + LOGE("Class is not match."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((const HcfObjectBase*)key, OPENSSL_SYM_KEY_CLASS)) { + LOGE("Class is not match."); + return HCF_INVALID_PARAMS; + } + + HcfCipherSm4GeneratorSpiOpensslImpl* cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl*)self; + SymKeyImpl* keyImpl = (SymKeyImpl*)key; + int32_t enc = (opMode == ENCRYPT_MODE) ? 1 : 0; + + if (keyImpl->keyMaterial.len < SM4_SIZE_128) { + LOGE("Init failed, the input key size is smaller than keySize specified in cipher."); + return HCF_INVALID_PARAMS; + } + if (InitCipherData(opMode, &(cipherImpl->cipherData)) != HCF_SUCCESS) { + LOGE("InitCipherData failed"); + return HCF_INVALID_PARAMS; + } + HcfResult ret = HCF_ERR_CRYPTO_OPERATION; + CipherData* data = cipherImpl->cipherData; + if (Openssl_EVP_CipherInit(data->ctx, GetCipherType(cipherImpl), NULL, NULL, enc) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("Cipher init failed."); + goto clearup; + } + if (Openssl_EVP_CipherInit(data->ctx, NULL, keyImpl->keyMaterial.data, GetIv(params), enc) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("Cipher init key and iv failed."); + goto clearup; + } + int32_t padding = (cipherImpl->attr.paddingMode == HCF_ALG_NOPADDING) ? 0 : EVP_PADDING_PKCS7; + if (Openssl_EVP_CIPHER_CTX_set_padding(data->ctx, padding) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("Set padding failed."); + goto clearup; + } + return HCF_SUCCESS; +clearup: + FreeCipherData(&(cipherImpl->cipherData)); + return ret; +} + +static HcfResult CommonUpdate(CipherData *data, HcfBlob *input, HcfBlob *output) +{ + int32_t ret = Openssl_EVP_CipherUpdate(data->ctx, output->data, (int *)&output->len, + input->data, input->len); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("cipher update failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult AllocateOutput(HcfBlob *input, HcfBlob *output, bool *isUpdateInput) +{ + uint32_t outLen = SM4_BLOCK_SIZE; + if (IsBlobValid(input)) { + outLen += input->len; + *isUpdateInput = true; + } + output->data = (uint8_t *)HcfMalloc(outLen, 0); + if (output->data == NULL) { + LOGE("malloc output failed!"); + return HCF_ERR_MALLOC; + } + output->len = outLen; + return HCF_SUCCESS; +} + +static HcfResult EngineUpdate(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output) +{ + if ((self == NULL) || (input == NULL) || (output == NULL)) { + LOGE("Invalid input parameter!"); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((const HcfObjectBase *)self, GetSm4GeneratorClass())) { + LOGE("Class is not match."); + return HCF_INVALID_PARAMS; + } + + HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self; + CipherData *data = cipherImpl->cipherData; + if (data == NULL) { + LOGE("cipherData is null!"); + return HCF_INVALID_PARAMS; + } + bool isUpdateInput = false; + HcfResult ret = AllocateOutput(input, output, &isUpdateInput); + if (ret != HCF_SUCCESS) { + LOGE("AllocateOutput failed!"); + goto clearup; + } + + int32_t ret = Openssl_EVP_CipherUpdate(data->ctx, output->data, (int*)&output->len, + input->data, input->len); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("Cipher update failed."); + res = HCF_ERR_CRYPTO_OPERATION; + goto clearup; + } + res = HCF_SUCCESS; +clearup: + if (res != HCF_SUCCESS) { + HcfBlobDataFree(output); + FreeCipherData(&(cipherImpl->cipherData)); + } + else { + FreeRedundantOutput(output); + } + return res; +} + +static HcfResult SM4DoFinal(CipherData* data, HcfBlob* input, HcfBlob* output) +{ + int32_t ret; + uint32_t len = 0; + + if (IsBlobValid(input)) { + ret = Openssl_EVP_CipherUpdate(data->ctx, output->data, (int*)&output->len, + input->data, input->len); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("Cipher update failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + len += output->len; + } + ret = Openssl_EVP_CipherFinal_ex(data->ctx, output->data + len, (int*)&output->len); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("Cipher final filed."); + return HCF_ERR_CRYPTO_OPERATION; + } + output->len += len; + return HCF_SUCCESS; +} + +static HcfResult EngineDoFinal(HcfCipherGeneratorSpi* self, HcfBlob* input, HcfBlob* output) +{ + if ((self == NULL) || (output == NULL)) { /* input maybe is null */ + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((const HcfObjectBase*)self, GetSm4GeneratorClass())) { + LOGE("Class is not match."); + return HCF_INVALID_PARAMS; + } + HcfCipherSm4GeneratorSpiOpensslImpl* cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl*)self; + CipherData* data = cipherImpl->cipherData; + if (data == NULL) { + LOGE("CipherData is null."); + return HCF_INVALID_PARAMS; + } + + HcfResult res = AllocateOutput(input, output); + if (res != HCF_SUCCESS) { + LOGE("AllocateOutput failed."); + goto clearup; + } + res = SM4DoFinal(data, input, output); + if (res != HCF_SUCCESS) { + LOGE("DesDoFinal failed."); + } +clearup: + if (res != HCF_SUCCESS) { + HcfBlobDataFree(output); + } + else { + FreeRedundantOutput(output); + } + FreeCipherData(&(cipherImpl->cipherData)); + return res; +} + +static void EngineSm4GeneratorDestroy(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetSm4GeneratorClass())) { + LOGE("Class is not match."); + return; + } + + HcfCipherSm4GeneratorSpiOpensslImpl *impl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self; + FreeCipherData(&(impl->cipherData)); + HcfFree(impl); +} + +HcfResult HcfCipherSm4GeneratorSpiCreate(CipherAttr *attr, HcfCipherGeneratorSpi **generator) +{ + if ((attr == NULL) || (generator == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + HcfCipherSm4GeneratorSpiOpensslImpl *returnImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)HcfMalloc( + sizeof(HcfCipherSm4GeneratorSpiOpensslImpl), 0); + if (returnImpl == NULL) { + LOGE("Failed to allocate returnImpl memroy!"); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(&returnImpl->attr, sizeof(CipherAttr), attr, sizeof(CipherAttr)); + returnImpl->base.init = EngineCipherInit; + returnImpl->base.update = EngineUpdate; + returnImpl->base.doFinal = EngineDoFinal; + returnImpl->base.base.destroy = EngineSm4GeneratorDestroy; + returnImpl->base.base.getClass = GetSm4GeneratorClass; + + *generator = (HcfCipherGeneratorSpi *)returnImpl; + return HCF_SUCCESS; +} diff --git a/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c b/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c index 98f66bdfe6a27aa8593c61204859216f8fe8b72d..ef056aa55bbfe9ba31148a0dedc32672d0f383bf 100644 --- a/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c @@ -58,6 +58,8 @@ static const EVP_MD *OpensslGetMacAlgoFromString(const char *mdName) return Openssl_EVP_sha384(); } else if (strcmp(mdName, "SHA512") == 0) { return Openssl_EVP_sha512(); + } else if (strcmp(mdName, "SM3") == 0){ + return Openssl_EVP_sm3(); } return NULL; } diff --git a/plugin/openssl_plugin/crypto_operation/md/src/md_openssl.c b/plugin/openssl_plugin/crypto_operation/md/src/md_openssl.c index f0f8607994cd27a6427e3d5721c9a35346eead9d..3e3785c841916713c563c62d4a932663b6d51337 100644 --- a/plugin/openssl_plugin/crypto_operation/md/src/md_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/md/src/md_openssl.c @@ -59,6 +59,8 @@ static const EVP_MD *OpensslGetMdAlgoFromString(const char *mdName) return Openssl_EVP_sha512(); } else if (strcmp(mdName, "MD5") == 0) { return Openssl_EVP_md5(); + } else if (strcmp(mdName, "SM3") == 0) { + return Openssl_EVP_sm3(); } return NULL; } diff --git a/plugin/openssl_plugin/crypto_operation/signature/inc/sm2_openssl.h b/plugin/openssl_plugin/crypto_operation/signature/inc/sm2_openssl.h new file mode 100644 index 0000000000000000000000000000000000000000..f86fa60687e8b3e7392e230787e7d3d04f8fc159 --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/signature/inc/sm2_openssl.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HCF_SM2_OPENSSL_H +#define HCF_SM2_OPENSSL_H + +#include "signature_spi.h" +#include "params_parser.h" +#include "result.h" + +#ifdef __cplusplus +extern "C" { +#endif + +HcfResult HcfSignSpiSm2Create(HcfSignatureParams *params, HcfSignSpi **returnObj); +HcfResult HcfVerifySpiSm2Create(HcfSignatureParams *params, HcfVerifySpi **returnObj); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/plugin/openssl_plugin/crypto_operation/signature/src/sm2_openssl.c b/plugin/openssl_plugin/crypto_operation/signature/src/sm2_openssl.c new file mode 100644 index 0000000000000000000000000000000000000000..3c84d1df2970a7bf839453e68c0ef983ee587dc6 --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/signature/src/sm2_openssl.c @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sm2_openssl.h" + +#include +#include + +#include "algorithm_parameter.h" +#include "openssl_adapter.h" +#include "openssl_class.h" +#include "openssl_common.h" +#include "log.h" +#include "memory.h" +#include "utils.h" + +#define OPENSSL_SM2_SIGN_CLASS "OPENSSL.SM2.SIGN" +#define OPENSSL_SM2_VERIFY_CLASS "OPENSSL.SM2.VERIFY" + +typedef struct { + HcfSignSpi base; + + const EVP_MD *digestAlg; + + EVP_MD_CTX *ctx; + + CryptoStatus status; +} HcfSignSpiSm2OpensslImpl; + +typedef struct { + HcfVerifySpi base; + + const EVP_MD *digestAlg; + + EVP_MD_CTX *ctx; + + CryptoStatus status; +} HcfVerifySpiSm2OpensslImpl; + +static bool IsDigestAlgValid(uint32_t alg) +{ + if ((alg == HCF_OPENSSL_DIGEST_SHA1) || (alg == HCF_OPENSSL_DIGEST_SHA224) || + (alg == HCF_OPENSSL_DIGEST_SHA256) ||(alg == HCF_OPENSSL_DIGEST_SHA384) || + (alg == HCF_OPENSSL_DIGEST_SHA512) || (alg == HCF_OPENSSL_DIGEST_SM3)) { + return true; + } else { + LOGE("Invalid digest num is %u.", alg); + return false; + } +} + +// export interfaces +static const char *GetSm2SignClass(void) +{ + return OPENSSL_SM2_SIGN_CLASS; +} + +static const char *GetSm2VerifyClass(void) +{ + return OPENSSL_SM2_VERIFY_CLASS; +} + +static void DestroySm2Sign(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetSm2SignClass())) { + return; + } + HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self; + Openssl_EVP_MD_CTX_free(impl->ctx); + impl->ctx = NULL; + HcfFree(impl); +} + +static void DestroySm2Verify(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetSm2VerifyClass())) { + return; + } + HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self; + Openssl_EVP_MD_CTX_free(impl->ctx); + impl->ctx = NULL; + HcfFree(impl); +} + +static HcfResult EngineSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey) +{ + (void)params; + if ((self == NULL) || (privateKey == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if ((!IsClassMatch((HcfObjectBase *)self, GetSm2SignClass())) || + (!IsClassMatch((HcfObjectBase *)privateKey, HCF_OPENSSL_SM2_PRI_KEY_CLASS))) { + return HCF_INVALID_PARAMS; + } + + HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self; + if (impl->status != UNINITIALIZED) { + LOGE("Repeated initialization is not allowed."); + return HCF_INVALID_PARAMS; + } + EC_KEY *ecKey = Openssl_EC_KEY_dup(((HcfOpensslSm2PriKey *)privateKey)->ecKey); + if (ecKey == NULL) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + EVP_PKEY *pKey = Openssl_EVP_PKEY_new(); + if (pKey == NULL) { + HcfPrintOpensslError(); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_PKEY_assign_EC_KEY(pKey, ecKey) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EC_KEY_free(ecKey); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_DigestSignInit(impl->ctx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EVP_PKEY_free(pKey); + impl->status = INITIALIZED; + return HCF_SUCCESS; +} + +static HcfResult EngineSignUpdate(HcfSignSpi *self, HcfBlob *data) +{ + if ((self == NULL) || (!IsBlobValid(data))) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSm2SignClass())) { + return HCF_INVALID_PARAMS; + } + HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self; + if (impl->status == UNINITIALIZED) { + LOGE("Sign object has not been initialized."); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_DigestSignUpdate(impl->ctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->status = READY; + return HCF_SUCCESS; +} + +static HcfResult EngineSignDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData) +{ + if ((self == NULL) || (returnSignatureData == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSm2SignClass())) { + return HCF_INVALID_PARAMS; + } + + HcfSignSpiSm2OpensslImpl *impl = (HcfSignSpiSm2OpensslImpl *)self; + if (IsBlobValid(data)) { + if (Openssl_EVP_DigestSignUpdate(impl->ctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->status = READY; + } + if (impl->status != READY) { + LOGE("The message has not been transferred."); + return HCF_INVALID_PARAMS; + } + size_t maxLen; + if (Openssl_EVP_DigestSignFinal(impl->ctx, NULL, &maxLen) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + uint8_t *outData = (uint8_t *)HcfMalloc(maxLen, 0); + if (outData == NULL) { + LOGE("Failed to allocate outData memory!"); + return HCF_ERR_MALLOC; + } + size_t actualLen = maxLen; + if (Openssl_EVP_DigestSignFinal(impl->ctx, outData, &actualLen) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + HcfFree(outData); + return HCF_ERR_CRYPTO_OPERATION; + } + if (actualLen > maxLen) { + LOGE("signature data too long."); + HcfFree(outData); + return HCF_ERR_CRYPTO_OPERATION; + } + + returnSignatureData->data = outData; + returnSignatureData->len = (uint32_t)actualLen; + return HCF_SUCCESS; +} + +static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey) +{ + (void)params; + if ((self == NULL) || (publicKey == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if ((!IsClassMatch((HcfObjectBase *)self, GetSm2VerifyClass())) || + (!IsClassMatch((HcfObjectBase *)publicKey, HCF_OPENSSL_SM2_PUB_KEY_CLASS))) { + return HCF_INVALID_PARAMS; + } + + HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self; + if (impl->status != UNINITIALIZED) { + LOGE("Repeated initialization is not allowed."); + return HCF_INVALID_PARAMS; + } + EC_KEY *ecKey = Openssl_EC_KEY_dup(((HcfOpensslSm2PubKey *)publicKey)->ecKey); + if (ecKey == NULL) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + EVP_PKEY *pKey = Openssl_EVP_PKEY_new(); + if (pKey == NULL) { + HcfPrintOpensslError(); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_PKEY_assign_EC_KEY(pKey, ecKey) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EC_KEY_free(ecKey); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_DigestVerifyInit(impl->ctx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EVP_PKEY_free(pKey); + impl->status = INITIALIZED; + return HCF_SUCCESS; +} + +static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data) +{ + if ((self == NULL) || (!IsBlobValid(data))) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSm2VerifyClass())) { + return HCF_INVALID_PARAMS; + } + + HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self; + if (impl->status == UNINITIALIZED) { + LOGE("Verify object has not been initialized."); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_DigestVerifyUpdate(impl->ctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->status = READY; + return HCF_SUCCESS; +} + +static bool EngineVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData) +{ + if ((self == NULL) || (!IsBlobValid(signatureData))) { + LOGE("Invalid input parameter."); + return false; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSm2VerifyClass())) { + return false; + } + + HcfVerifySpiSm2OpensslImpl *impl = (HcfVerifySpiSm2OpensslImpl *)self; + if (IsBlobValid(data)) { + if (Openssl_EVP_DigestVerifyUpdate(impl->ctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return false; + } + impl->status = READY; + } + if (impl->status != READY) { + LOGE("The message has not been transferred."); + return false; + } + if (Openssl_EVP_DigestVerifyFinal(impl->ctx, signatureData->data, signatureData->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return false; + } + return true; +} + +HcfResult HcfSignSpiSm2Create(HcfSignatureParams *params, HcfSignSpi **returnObj) +{ + if ((params == NULL) || (returnObj == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsDigestAlgValid(params->md)) { + return HCF_INVALID_PARAMS; + } + EVP_MD *opensslAlg = NULL; + int32_t ret = GetOpensslDigestAlg(params->md, &opensslAlg); + if (ret != HCF_SUCCESS || opensslAlg == NULL) { + LOGE("Failed to Invalid digest!"); + return HCF_INVALID_PARAMS; + } + + HcfSignSpiSm2OpensslImpl *returnImpl = (HcfSignSpiSm2OpensslImpl *)HcfMalloc( + sizeof(HcfSignSpiSm2OpensslImpl), 0); + if (returnImpl == NULL) { + LOGE("Failed to allocate returnImpl memroy!"); + return HCF_ERR_MALLOC; + } + returnImpl->base.base.getClass = GetSm2SignClass; + returnImpl->base.base.destroy = DestroySm2Sign; + returnImpl->base.engineInit = EngineSignInit; + returnImpl->base.engineUpdate = EngineSignUpdate; + returnImpl->base.engineSign = EngineSignDoFinal; + returnImpl->digestAlg = opensslAlg; + returnImpl->status = UNINITIALIZED; + returnImpl->ctx = Openssl_EVP_MD_CTX_new(); + if (returnImpl->ctx == NULL) { + LOGE("Failed to allocate ctx memory!"); + HcfFree(returnImpl); + return HCF_ERR_MALLOC; + } + + *returnObj = (HcfSignSpi *)returnImpl; + return HCF_SUCCESS; +} + +HcfResult HcfVerifySpiSm2Create(HcfSignatureParams *params, HcfVerifySpi **returnObj) +{ + if ((params == NULL) || (returnObj == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsDigestAlgValid(params->md)) { + return HCF_INVALID_PARAMS; + } + EVP_MD *opensslAlg = NULL; + int32_t ret = GetOpensslDigestAlg(params->md, &opensslAlg); + if (ret != HCF_SUCCESS || opensslAlg == NULL) { + LOGE("Failed to Invalid digest!"); + return HCF_INVALID_PARAMS; + } + + HcfVerifySpiSm2OpensslImpl *returnImpl = (HcfVerifySpiSm2OpensslImpl *)HcfMalloc( + sizeof(HcfVerifySpiSm2OpensslImpl), 0); + if (returnImpl == NULL) { + LOGE("Failed to allocate returnImpl memroy!"); + return HCF_ERR_MALLOC; + } + returnImpl->base.base.getClass = GetSm2VerifyClass; + returnImpl->base.base.destroy = DestroySm2Verify; + returnImpl->base.engineInit = EngineVerifyInit; + returnImpl->base.engineUpdate = EngineVerifyUpdate; + returnImpl->base.engineVerify = EngineVerifyDoFinal; + returnImpl->digestAlg = opensslAlg; + returnImpl->status = UNINITIALIZED; + returnImpl->ctx = Openssl_EVP_MD_CTX_new(); + if (returnImpl->ctx == NULL) { + LOGE("Failed to allocate ctx memory!"); + HcfFree(returnImpl); + return HCF_ERR_MALLOC; + } + + *returnObj = (HcfVerifySpi *)returnImpl; + return HCF_SUCCESS; +} diff --git a/plugin/openssl_plugin/key/asy_key_generator/inc/sm2_asy_key_generator_openssl.h b/plugin/openssl_plugin/key/asy_key_generator/inc/sm2_asy_key_generator_openssl.h new file mode 100644 index 0000000000000000000000000000000000000000..9c0840dfc3a29163c0b4db21a30a69ae3070e889 --- /dev/null +++ b/plugin/openssl_plugin/key/asy_key_generator/inc/sm2_asy_key_generator_openssl.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HCF_SM2_ASY_KEY_GENERATOR_OPENSSL_H +#define HCF_SM2_ASY_KEY_GENERATOR_OPENSSL_H + +#include "asy_key_generator_spi.h" +#include "params_parser.h" +#include "result.h" + +#ifdef __cplusplus +extern "C" { +#endif + +HcfResult HcfAsyKeyGeneratorSpiSm2Create(HcfAsyKeyGenParams *params, HcfAsyKeyGeneratorSpi **returnObj); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/sm2_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/sm2_asy_key_generator_openssl.c new file mode 100644 index 0000000000000000000000000000000000000000..84f77cc0c444f3059351010ace3836d6458119ac --- /dev/null +++ b/plugin/openssl_plugin/key/asy_key_generator/src/sm2_asy_key_generator_openssl.c @@ -0,0 +1,503 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sm2_asy_key_generator_openssl.h" + +#include "securec.h" + +#include "log.h" +#include "memory.h" +#include "openssl_adapter.h" +#include "openssl_class.h" +#include "openssl_common.h" +#include "utils.h" + +#define OPENSSL_SM2_KEY_GENERATOR_CLASS "OPENSSL.SM2.KEY_GENERATOR_CLASS" +#define OPENSSL_SM2_ALGORITHM "SM2" +#define OPENSSL_SM2_PUB_KEY_FORMAT "X.509" +#define OPENSSL_SM2_PRI_KEY_FORMAT "PKCS#8" + +typedef struct { + HcfAsyKeyGeneratorSpi base; + + int32_t curveId; +} HcfAsyKeyGeneratorSpiOpensslSm2Impl; + +static HcfResult NewEcKeyPair(int32_t curveId, EC_KEY **returnEcKey) +{ + EC_KEY *ecKey = Openssl_EC_KEY_new_by_curve_name(curveId); + if (ecKey == NULL) { + LOGE("new ec key failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EC_KEY_generate_key(ecKey) <= 0) { + LOGE("generate ec key failed."); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EC_KEY_check_key(ecKey) <= 0) { + LOGE("check key fail."); + Openssl_EC_KEY_free(ecKey); + return HCF_ERR_CRYPTO_OPERATION; + } + *returnEcKey = ecKey; + return HCF_SUCCESS; +} + + +static const char *GetSm2KeyPairGeneratorClass(void) +{ + return OPENSSL_SM2_KEY_GENERATOR_CLASS; +} + +static const char *GetSm2KeyPairClass(void) +{ + return HCF_OPENSSL_SM2_KEY_PAIR_CLASS; +} + +static const char *GetSm2PubKeyClass(void) +{ + return HCF_OPENSSL_SM2_PUB_KEY_CLASS; +} + +static const char *GetSm2PriKeyClass(void) +{ + return HCF_OPENSSL_SM2_PRI_KEY_CLASS; +} + +static void DestroySm2KeyPairGenerator(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetSm2KeyPairGeneratorClass())) { + return; + } + HcfFree(self); +} + +static void DestroySm2PubKey(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetSm2PubKeyClass())) { + return; + } + HcfOpensslSm2PubKey *impl = (HcfOpensslSm2PubKey *)self; + Openssl_EC_KEY_free(impl->ecKey); + impl->ecKey = NULL; + HcfFree(impl); +} + +static void DestroySm2PriKey(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetSm2PriKeyClass())) { + return; + } + HcfOpensslSm2PriKey *impl = (HcfOpensslSm2PriKey *)self; + Openssl_EC_KEY_free(impl->ecKey); + impl->ecKey = NULL; + HcfFree(impl); +} + +static void DestroySm2KeyPair(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetSm2KeyPairClass())) { + return; + } + HcfOpensslSm2KeyPair *impl = (HcfOpensslSm2KeyPair *)self; + if (impl->base.pubKey != NULL) { + DestroySm2PubKey((HcfObjectBase *)impl->base.pubKey); + impl->base.pubKey = NULL; + } + if (impl->base.priKey != NULL) { + DestroySm2PriKey((HcfObjectBase *)impl->base.priKey); + impl->base.priKey = NULL; + } + HcfFree(impl); +} + +static const char *GetSm2PubKeyAlgorithm(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, HCF_OPENSSL_SM2_PUB_KEY_CLASS)) { + return NULL; + } + return OPENSSL_SM2_ALGORITHM; +} + +static const char *GetSm2PriKeyAlgorithm(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, HCF_OPENSSL_SM2_PRI_KEY_CLASS)) { + return NULL; + } + return OPENSSL_SM2_ALGORITHM; +} + +static const char *GetSm2PubKeyFormat(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, HCF_OPENSSL_SM2_PUB_KEY_CLASS)) { + return NULL; + } + return OPENSSL_SM2_PUB_KEY_FORMAT; +} + +static const char *GetSm2PriKeyFormat(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, HCF_OPENSSL_SM2_PRI_KEY_CLASS)) { + return NULL; + } + return OPENSSL_SM2_PRI_KEY_FORMAT; +} + +static HcfResult GetSm2PubKeyEncoded(HcfKey *self, HcfBlob *returnBlob) +{ + if ((self == NULL) || (returnBlob == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, HCF_OPENSSL_SM2_PUB_KEY_CLASS)) { + return HCF_INVALID_PARAMS; + } + + HcfOpensslSm2PubKey *impl = (HcfOpensslSm2PubKey *)self; + if (impl->curveId != 0) { + LOGE("have a curveId"); + Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_NAMED_CURVE); + } else { + Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_EXPLICIT_CURVE); + } + + unsigned char *returnData = NULL; + LOGE("Begin trans"); + int returnDataLen = Openssl_i2d_EC_PUBKEY(impl->ecKey, &returnData); + LOGE("SM2 i2d complete"); + if (returnDataLen <= 0) { + LOGE("i2d_EC_PUBKEY fail"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + LOGD("SM2 pubKey i2d success"); + returnBlob->data = returnData; + returnBlob->len = returnDataLen; + return HCF_SUCCESS; +} + +static HcfResult GetSm2PriKeyEncoded(HcfKey *self, HcfBlob *returnBlob) +{ + if ((self == NULL) || (returnBlob == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, HCF_OPENSSL_SM2_PRI_KEY_CLASS)) { + return HCF_INVALID_PARAMS; + } + + HcfOpensslSm2PriKey *impl = (HcfOpensslSm2PriKey *)self; + if (impl->curveId != 0) { + LOGD("have a curveId"); + Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_NAMED_CURVE); + } else { + Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_EXPLICIT_CURVE); + } + // keep consistence of 3.2 + Openssl_EC_KEY_set_enc_flags(impl->ecKey, EC_PKEY_NO_PUBKEY); + // if the convert key has no pubKey, it will generate pub key automatically, + // and set the no pubKey flag to ensure the consistency of blob. + unsigned char *returnData = NULL; + int returnDataLen = Openssl_i2d_ECPrivateKey(impl->ecKey, &returnData); + if (returnDataLen <= 0) { + LOGE("i2d_ECPrivateKey fail."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + LOGD("SM2 priKey i2d success"); + returnBlob->data = returnData; + returnBlob->len = returnDataLen; + return HCF_SUCCESS; +} + +static void Sm2PriKeyClearMem(HcfPriKey *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSm2PriKeyClass())) { + return; + } + HcfOpensslSm2PriKey *impl = (HcfOpensslSm2PriKey *)self; + Openssl_EC_KEY_free(impl->ecKey); + impl->ecKey = NULL; +} + +static HcfResult PackSm2PubKey(int32_t curveId, EC_KEY *ecKey, HcfOpensslSm2PubKey **returnObj) +{ + HcfOpensslSm2PubKey *returnPubKey = (HcfOpensslSm2PubKey *)HcfMalloc(sizeof(HcfOpensslSm2PubKey), 0); + if (returnPubKey == NULL) { + LOGE("Failed to allocate returnPubKey memory!"); + return HCF_ERR_MALLOC; + } + + returnPubKey->base.base.base.destroy = DestroySm2PubKey; + returnPubKey->base.base.base.getClass = GetSm2PubKeyClass; + returnPubKey->base.base.getAlgorithm = GetSm2PubKeyAlgorithm; + returnPubKey->base.base.getEncoded = GetSm2PubKeyEncoded; + returnPubKey->base.base.getFormat = GetSm2PubKeyFormat; + returnPubKey->curveId = curveId; + returnPubKey->ecKey = ecKey; + + *returnObj = returnPubKey; + return HCF_SUCCESS; +} + +static HcfResult PackSm2PriKey(int32_t curveId, EC_KEY *ecKey, HcfOpensslSm2PriKey **returnObj) +{ + HcfOpensslSm2PriKey *returnPriKey = (HcfOpensslSm2PriKey *)HcfMalloc(sizeof(HcfOpensslSm2PriKey), 0); + if (returnPriKey == NULL) { + LOGE("Failed to allocate returnPriKey memory!"); + return HCF_ERR_MALLOC; + } + + returnPriKey->base.base.base.destroy = DestroySm2PriKey; + returnPriKey->base.base.base.getClass = GetSm2PriKeyClass; + returnPriKey->base.base.getAlgorithm = GetSm2PriKeyAlgorithm; + returnPriKey->base.base.getEncoded = GetSm2PriKeyEncoded; + returnPriKey->base.base.getFormat = GetSm2PriKeyFormat; + returnPriKey->base.clearMem = Sm2PriKeyClearMem; + returnPriKey->curveId = curveId; + returnPriKey->ecKey = ecKey; + + *returnObj = returnPriKey; + return HCF_SUCCESS; +} + +static HcfResult PackSm2KeyPair(HcfOpensslSm2PubKey *pubKey, HcfOpensslSm2PriKey *priKey, + HcfOpensslSm2KeyPair **returnObj) +{ + HcfOpensslSm2KeyPair *returnKeyPair = (HcfOpensslSm2KeyPair *)HcfMalloc(sizeof(HcfOpensslSm2KeyPair), 0); + if (returnKeyPair == NULL) { + LOGE("Failed to allocate returnKeyPair memory!"); + return HCF_ERR_MALLOC; + } + returnKeyPair->base.base.getClass = GetSm2KeyPairClass; + returnKeyPair->base.base.destroy = DestroySm2KeyPair; + returnKeyPair->base.pubKey = (HcfPubKey *)pubKey; + returnKeyPair->base.priKey = (HcfPriKey *)priKey; + + *returnObj = returnKeyPair; + return HCF_SUCCESS; +} + +static HcfResult ConvertEcPubKey(int32_t curveId, HcfBlob *pubKeyBlob, HcfOpensslSm2PubKey **returnPubKey) +{ + const unsigned char *tmpData = (const unsigned char *)(pubKeyBlob->data); + EC_KEY *ecKey = Openssl_d2i_EC_PUBKEY(NULL, &tmpData, pubKeyBlob->len); + if (ecKey == NULL) { + LOGE("d2i_EC_PUBKEY fail."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult res = PackSm2PubKey(curveId, ecKey, returnPubKey); + if (res != HCF_SUCCESS) { + LOGE("CreateSm2PubKey failed."); + Openssl_EC_KEY_free(ecKey); + return res; + } + return HCF_SUCCESS; +} + +static HcfResult ConvertEcPriKey(int32_t curveId, HcfBlob *priKeyBlob, HcfOpensslSm2PriKey **returnPriKey) +{ + const unsigned char *tmpData = (const unsigned char *)(priKeyBlob->data); + EC_KEY *ecKey = Openssl_d2i_ECPrivateKey(NULL, &tmpData, priKeyBlob->len); + if (ecKey == NULL) { + LOGE("d2i_ECPrivateKey fail"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult res = PackSm2PriKey(curveId, ecKey, returnPriKey); + if (res != HCF_SUCCESS) { + Openssl_EC_KEY_free(ecKey); + return res; + } + return HCF_SUCCESS; +} + +static HcfResult EngineConvertSm2Key(HcfAsyKeyGeneratorSpi *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob, + HcfBlob *priKeyBlob, HcfKeyPair **returnKeyPair) +{ + (void)params; + if ((self == NULL) || (returnKeyPair == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSm2KeyPairGeneratorClass())) { + return HCF_INVALID_PARAMS; + } + bool pubKeyValid = IsBlobValid(pubKeyBlob); + bool priKeyValid = IsBlobValid(priKeyBlob); + if ((!pubKeyValid) && (!priKeyValid)) { + LOGE("The private key and public key cannot both be NULL."); + return HCF_INVALID_PARAMS; + } + + HcfAsyKeyGeneratorSpiOpensslSm2Impl *impl = (HcfAsyKeyGeneratorSpiOpensslSm2Impl *)self; + HcfResult res = HCF_SUCCESS; + HcfOpensslSm2PubKey *pubKey = NULL; + HcfOpensslSm2PriKey *priKey = NULL; + HcfOpensslSm2KeyPair *keyPair = NULL; + do { + if (pubKeyValid) { + res = ConvertEcPubKey(impl->curveId, pubKeyBlob, &pubKey); + if (res != HCF_SUCCESS) { + break; + } + } + if (priKeyValid) { + res = ConvertEcPriKey(impl->curveId, priKeyBlob, &priKey); + if (res != HCF_SUCCESS) { + break; + } + } + res = PackSm2KeyPair(pubKey, priKey, &keyPair); + } while (0); + if (res != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + HcfObjDestroy(priKey); + return res; + } + + *returnKeyPair = (HcfKeyPair *)keyPair; + return HCF_SUCCESS; +} + +static HcfResult CreateAndAssignKeyPair(const HcfAsyKeyGeneratorSpiOpensslSm2Impl *impl, EC_KEY *ecKey, HcfKeyPair **returnObj) +{ + EC_KEY *ecPriKey = EC_KEY_dup(ecKey); + if (ecPriKey == NULL) { + LOGE("copy ecKey fail."); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfOpensslSm2PriKey *priKey = NULL; + HcfResult res = PackSm2PriKey(impl->curveId, ecPriKey, &priKey); + if (res != HCF_SUCCESS) { + Openssl_EC_KEY_free(ecPriKey); + return res; + } + HcfOpensslSm2PubKey *pubKey = NULL; + EC_KEY *ecPubKey = EC_KEY_dup(ecKey); + if (ecPubKey == NULL) { + LOGE("copy ecKey fail."); + HcfObjDestroy(priKey); + return HCF_ERR_CRYPTO_OPERATION; + } + res = PackSm2PubKey(impl->curveId, ecPubKey, &pubKey); + if (res != HCF_SUCCESS) { + HcfObjDestroy(priKey); + Openssl_EC_KEY_free(ecPubKey); + return res; + } + + HcfOpensslSm2KeyPair *returnKeyPair = (HcfOpensslSm2KeyPair *)HcfMalloc(sizeof(HcfOpensslSm2KeyPair), 0); + if (returnKeyPair == NULL) { + LOGE("Failed to allocate returnKeyPair memory!"); + HcfObjDestroy(pubKey); + HcfObjDestroy(priKey); + return HCF_ERR_MALLOC; + } + returnKeyPair->base.base.getClass = GetSm2KeyPairClass; + returnKeyPair->base.base.destroy = DestroySm2KeyPair; + returnKeyPair->base.pubKey = (HcfPubKey *)pubKey; + returnKeyPair->base.priKey = (HcfPriKey *)priKey; + + *returnObj = (HcfKeyPair *)returnKeyPair; + return HCF_SUCCESS; +} + +static HcfResult EngineGenerateKeyPair(HcfAsyKeyGeneratorSpi *self, HcfKeyPair **returnObj) +{ + if ((self == NULL) || (returnObj == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSm2KeyPairGeneratorClass())) { + return HCF_INVALID_PARAMS; + } + + HcfAsyKeyGeneratorSpiOpensslSm2Impl *impl = (HcfAsyKeyGeneratorSpiOpensslSm2Impl *)self; + EC_KEY *ecKey = NULL; + HcfResult res = NewEcKeyPair(impl->curveId, &ecKey); + if (res != HCF_SUCCESS) { + return res; + } + res = CreateAndAssignKeyPair(impl, ecKey, returnObj); + Openssl_EC_KEY_free(ecKey); + if (res != HCF_SUCCESS) { + LOGE("CreateAndAssignKeyPair failed."); + return res; + } + return HCF_SUCCESS; +} + +HcfResult HcfAsyKeyGeneratorSpiSm2Create(HcfAsyKeyGenParams *params, HcfAsyKeyGeneratorSpi **returnObj) +{ + if (params == NULL || returnObj == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + int32_t curveId = 0; + if (params->bits != 0) { + if (GetOpensslCurveId(params->bits, &curveId) != HCF_SUCCESS) { + return HCF_INVALID_PARAMS; + } + } + + HcfAsyKeyGeneratorSpiOpensslSm2Impl *returnImpl = (HcfAsyKeyGeneratorSpiOpensslSm2Impl *)HcfMalloc( + sizeof(HcfAsyKeyGeneratorSpiOpensslSm2Impl), 0); + if (returnImpl == NULL) { + LOGE("Failed to allocate returnImpl memroy!"); + return HCF_ERR_MALLOC; + } + returnImpl->base.base.getClass = GetSm2KeyPairGeneratorClass; + returnImpl->base.base.destroy = DestroySm2KeyPairGenerator; + returnImpl->base.engineConvertKey = EngineConvertSm2Key; + returnImpl->base.engineGenerateKeyPair = EngineGenerateKeyPair; + returnImpl->curveId = curveId; + + *returnObj = (HcfAsyKeyGeneratorSpi *)returnImpl; + return HCF_SUCCESS; +} diff --git a/plugin/openssl_plugin/key/sym_key_generator/src/sym_key_openssl.c b/plugin/openssl_plugin/key/sym_key_generator/src/sym_key_openssl.c index 3e1ed3e3fd8efef51962279a3f49906fda84bde5..38fcc9a5bceda83ef79ec190b18a38bceca54eb6 100644 --- a/plugin/openssl_plugin/key/sym_key_generator/src/sym_key_openssl.c +++ b/plugin/openssl_plugin/key/sym_key_generator/src/sym_key_openssl.c @@ -26,6 +26,7 @@ #define MAX_KEY_LEN 4096 #define KEY_BIT 8 #define AES_ALG_NAME "AES" +#define SM4_ALG_NAME "SM4" #define DES_ALG_NAME "3DES" typedef struct { @@ -195,10 +196,10 @@ static char *GetAlgoName(HcfSymKeyGeneratorSpiOpensslImpl *impl) LOGE("algoName malloc failed!"); return NULL; } - int32_t aesSize = strlen(AES_ALG_NAME); - int32_t desSize = strlen(DES_ALG_NAME); + HcfAlgValue type = impl->attr.algo; if (type == HCF_ALG_AES) { + int32_t aesSize = strlen(AES_ALG_NAME); if (strcpy_s(algoName, MAX_KEY_STR_SIZE, AES_ALG_NAME) != EOK) { LOGE("aes algoName strcpy_s failed!"); goto clearup; @@ -207,7 +208,18 @@ static char *GetAlgoName(HcfSymKeyGeneratorSpiOpensslImpl *impl) LOGE("aes algoName size strcpy_s failed!"); goto clearup; } + } else if (type == HCF_ALG_SM4) { + int32_t sm4Size = strlen(SM4_ALG_NAME); + if (strcpy_s(algoName, MAX_KEY_STR_SIZE, SM4_ALG_NAME) != EOK) { + LOGE("sm4 algoName strcpy_s failed!"); + goto clearup; + } + if (strcpy_s(algoName + sm4Size, MAX_KEY_STR_SIZE - sm4Size, keySizeChar) != EOK) { + LOGE("sm4 algoName size strcpy_s failed!"); + goto clearup; + } } else if (type == HCF_ALG_DES) { + int32_t desSize = strlen(DES_ALG_NAME); if (strcpy_s(algoName, MAX_KEY_STR_SIZE, DES_ALG_NAME) != EOK) { LOGE("des algoName strcpy_s failed!"); goto clearup; diff --git a/plugin/plugin.gni b/plugin/plugin.gni index 528d9c9bdadde504c1640dad0af2f5f7565ef9f0..70b222071252f446d7157e0fb8d7fa355f952db9 100644 --- a/plugin/plugin.gni +++ b/plugin/plugin.gni @@ -34,18 +34,21 @@ plugin_signature_files = [ "${plugin_path}/openssl_plugin/crypto_operation/signature/src/dsa_openssl.c", "${plugin_path}/openssl_plugin/crypto_operation/signature/src/ecdsa_openssl.c", "${plugin_path}/openssl_plugin/crypto_operation/signature/src/signature_rsa_openssl.c", + "${plugin_path}/openssl_plugin/crypto_operation/signature/src/sm2_openssl.c", ] plugin_common_files = [ "${plugin_path}/openssl_plugin/common/src/openssl_adapter.c", "${plugin_path}/openssl_plugin/common/src/openssl_common.c", "${plugin_path}/openssl_plugin/common/src/rsa_openssl_common.c", + "${plugin_path}/openssl_plugin/common/src/sm2_openssl_common.c", ] plugin_asy_key_generator_files = [ "${plugin_path}/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c", "${plugin_path}/openssl_plugin/key/asy_key_generator/src/ecc_asy_key_generator_openssl.c", "${plugin_path}/openssl_plugin/key/asy_key_generator/src/rsa_asy_key_generator_openssl.c", + "${plugin_path}/openssl_plugin/key/asy_key_generator/src/sm2_asy_key_generator_openssl.c", ] plugin_key_agreement_files = [ "${plugin_path}/openssl_plugin/crypto_operation/key_agreement/src/ecdh_openssl.c" ] @@ -59,6 +62,8 @@ plugin_cipher_files = [ "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_3des_openssl.c", "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_aes_openssl.c", "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_aes_common.c", + "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_sm4_openssl.c", + "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_sm2_openssl.c", ] plugin_hmac_files = diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 5488118d8a102a973e9dd7548b80fe91c3186369..3a7b7bf7bbaf129b68990dcca2cb28bfd4ae31b1 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -54,6 +54,9 @@ ohos_unittest("crypto_framework_test") { "src/crypto_x509_cert_chain_validator_test.cpp", "src/crypto_x509_certificate_test.cpp", "src/crypto_x509_crl_test.cpp", + "src/crypto_md_sm3_test.cpp", + "src/cryto_sm4_cipher_test.cpp" + "src/crypto_sm3_mac_test.cpp", ] sources += framework_files + plugin_files diff --git a/test/unittest/src/crypto_md_sm3_test.cpp b/test/unittest/src/crypto_md_sm3_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2dffe480289d6cfe47949d95c6833cd8b9334e59 --- /dev/null +++ b/test/unittest/src/crypto_md_sm3_test.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "securec.h" + +#include "md.h" +#include "md_openssl.h" + +#include "log.h" +#include "memory.h" + +using namespace std; +using namespace testing::ext; + +namespace { + +class CryptoMd_SM3Test : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + + +constexpr uint32_t SM3_LEN = 32; + + +void CryptoMd_SM3Test::SetUpTestCase() {} +void CryptoMd_SM3Test::TearDownTestCase() {} + +void CryptoMd_SM3Test::SetUp() // add init here, this will be called before test. +{ +} + +void CryptoMd_SM3Test::TearDown() // add destroy here, this will be called when test case done. +{ +} + + +HWTEST_F(CryptoMd_SM3Test, CryptoFrameworkMd_SM3_CreateTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfResult ret = HcfMdCreate("SM3", nullptr); + EXPECT_NE(ret, HCF_SUCCESS); +} + +HWTEST_F(CryptoMd_SM3Test, CryptoFrameworkMd_SM3_AlgoSuppTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMd *mdObj = nullptr; + HcfResult ret = HcfMdCreate("SM3", &mdObj); + ASSERT_EQ(ret, HCF_SUCCESS); + ASSERT_NE(mdObj, nullptr); + HcfObjDestroy(mdObj); +} + +HWTEST_F(CryptoMd_SM3Test, CryptoFrameworkMd_SM3_AlgoNameTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMd *mdObj = nullptr; + HcfResult ret = HcfMdCreate("SM3", &mdObj); + ASSERT_EQ(ret, HCF_SUCCESS); + ASSERT_NE(mdObj, nullptr); + // test api functions + const char *algoName = mdObj->getAlgoName(mdObj); + int32_t cmpRes = strcmp(algoName, "SM3"); + EXPECT_EQ(cmpRes, HCF_SUCCESS); + HcfObjDestroy(mdObj); +} + +HWTEST_F(CryptoMd_SM3Test, CryptoFrameworkMd_SM3_UpdateTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMd *mdObj = nullptr; + HcfResult ret = HcfMdCreate("SM3", &mdObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // define input and output data in blob form + HcfBlob *inBlob = nullptr; + // test api functions + ret = mdObj->update(mdObj, inBlob); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(mdObj); +} + +HWTEST_F(CryptoMd_SM3Test, CryptoFrameworkMd_SM3_UpdateTest002, TestSize.Level0) +{ + // create a SM3 obj + HcfMd *mdObj = nullptr; + HcfResult ret = HcfMdCreate("SM3", &mdObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // set input and output buf + uint8_t testData[] = "My test data"; + // define input and output data in blob form + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + // test api functions + ret = mdObj->update(mdObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(mdObj); +} + + +HWTEST_F(CryptoMd_SM3Test, CryptoFrameworkMd_SM3_DoFinalTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMd *mdObj = nullptr; + HcfResult ret = HcfMdCreate("SM3", &mdObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // set input and output buf + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api functions + ret = mdObj->doFinal(mdObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(mdObj); +} + +HWTEST_F(CryptoMd_SM3Test, CryptoFrameworkMd_SM3_DoFinalTest002, TestSize.Level0) +{ + // create a SM3 obj + HcfMd *mdObj = nullptr; + HcfResult ret = HcfMdCreate("SM3", &mdObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // set input and output buf + uint8_t testData[] = "My test data"; + // define input and output data in blob form + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api functions + ret = mdObj->update(mdObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = mdObj->doFinal(mdObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(mdObj); +} + +HWTEST_F(CryptoMd_SM3Test, CryptoFrameworkMd_SM3_LenTest001, TestSize.Level0) +{ + // create a API obj with SM3 + HcfMd *mdObj = nullptr; + HcfResult ret = HcfMdCreate("SM3", &mdObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // test api functions + uint32_t len = mdObj->getMdLength(mdObj); + EXPECT_EQ(len, SM3_LEN); + HcfObjDestroy(mdObj); +} + +HWTEST_F(CryptoMd_SM3Test, CryptoFrameworkMd_SM3_AlgoTest002, TestSize.Level0) +{ + // create a API obj with SM3 + HcfMd *mdObj = nullptr; + HcfResult ret = HcfMdCreate("SM3", &mdObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // set input and output buf + uint8_t testData[] = "My test data"; + // define input and output data in blob form + struct HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + struct HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api functions + ret = mdObj->update(mdObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = mdObj->doFinal(mdObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + uint32_t len = mdObj->getMdLength(mdObj); + EXPECT_EQ(len, SM3_LEN); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(mdObj); +} + +} \ No newline at end of file diff --git a/test/unittest/src/crypto_sm3_mac_test.cpp b/test/unittest/src/crypto_sm3_mac_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..658bc88f7fc42b4efaabae20ba7047f6a9caa294 --- /dev/null +++ b/test/unittest/src/crypto_sm3_mac_test.cpp @@ -0,0 +1,682 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "securec.h" + +#include "mac.h" +#include "sym_key_generator.h" +#include "mac_openssl.h" + +#include "log.h" +#include "memory.h" + +using namespace std; +using namespace testing::ext; + +namespace { +class CryptoMac_Sm3_Test : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +constexpr uint32_t MAX_MAC_BLOB_LEN = 5000; +constexpr uint32_t INVALID_LEN = 0; +constexpr uint32_t SM3_LEN = 32; + +static char g_testBigData[] = "VqRH5dzdeeturr5zN5vE77DtqjV7kNKbDJqk4mNqyYRTXymhjR\r\n" +"Yz8c2pNvJiCxyFwvLvWfPh2Y2eDAuxbdm2Dt4UzKJtNqEpNYKVZLiyH4a4MhR4BpFhvhJVHy2ALbYq2rW\r\n" +"LqJfNzA6v8kHNaFypNDMgX35kifyCiYkq85XUKDJCdewUzCZ2N8twC8Z9kL37K67bkL35VYFZSXyrNTdV\r\n" +"pB6kqPjwZYrjx5tXzMMgJW8ePqmAhZUVjtPGXTLVt8BUnaVRuWjD97xjS3VH9EwFeyrqJ46B92rkuGexY\r\n" +"cjXuvhHTnQNPbYfake7KMEWG2wgGLmZmjnakULhFgjt6TQhvCWMJAHYn8Zgczd3C3HkPrQgUXJgAiwf3r\r\n" +"jJbgbBpQkkbcfMBZZ3SSLe2J9jw6MkdEf3eBQX9rFVQSgBQgZ9KEW8XLb5kCTcyhRZPBbiHD4qQRyrwKT\r\n" +"mnGZqP5Aru6GDkhFk78jfjtk35HyB7AY7UZXkczRfVYAxa5Mk256MhAHkE3uAvPZTyY7N3qk9U7cLTrce\r\n" +"wJLH6wrymrMvQWgpvrBevMghnURZUcZAWUznDn56WnwGAzYAWmJqdXqAfcvgZwCFTjxdiaEZGpEyUrcS8\r\n" +"nr48ZeXS5aytz5Y7RnU5SxcHbgF8PerWVdftxmghPAvGkQ6f3dcXr9w9bbGqg5KJHyQCxabp8bjZpyFdb\r\n" +"VTq8DpQ6AJjxdjn8cuLTf9giGFxDjtQncicUdqP7YvVDr5AFgWc83cddyryVLZEBGAFfqbbKWF9KnPjRZ\r\n" +"AbuZ7SqrkxhQHu87Hxh3xHUHB8Lb3DGZ4vhnqaLnJBxFK8Ve4F2FfbgfHfQtALFDUWp6dSz8Hvdpj4CGw\r\n" +"FaSb8b5hTemaQRguYAqaUwJVvZ7G2AwkFnV9PHUngmybAFxg8HMAT3K7yAiQJWWqPxdGq8jXPAqZFNkGu\r\n" +"2mnJ5xfnY3z63PFk6TXU9Ga2YmHvtycXxwqMBEctQRa3zVWGVSrh3NF6jXa\r\n"; + +void CryptoMac_Sm3_Test::SetUpTestCase() {} +void CryptoMac_Sm3_Test::TearDownTestCase() {} + +void CryptoMac_Sm3_Test::SetUp() // add init here, this will be called before test. +{ +} + +void CryptoMac_Sm3_Test::TearDown() // add destroy here, this will be called when test case done. +{ +} + +static void PrintfBlobInHex(uint8_t *data, size_t dataLen) +{ + for (size_t i = 0; i < dataLen; i++) { + printf("%02hhX", data[i]); + } + printf("\n"); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_CreateTest002, TestSize.Level0) +{ + HcfResult ret = HcfMacCreate("SM3", nullptr); + EXPECT_NE(ret, HCF_SUCCESS); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_AlgoSuppTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(macObj, nullptr); + HcfObjDestroy(macObj); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_AlgoSuppTest002, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SHA3", &macObj); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(macObj, nullptr); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_AlgoSuppTest003, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate(nullptr, &macObj); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(macObj, nullptr); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_AlgoNameTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(macObj, nullptr); + // test api functions + const char *algoName = macObj->getAlgoName(macObj); + int32_t cmpRes = strcmp(algoName, "SM3"); + EXPECT_EQ(cmpRes, HCF_SUCCESS); + HcfObjDestroy(macObj); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_InitTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // set a nullptr key + HcfSymKey *key = nullptr; + // test api functions + ret = macObj->init(macObj, key); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(macObj); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_InitTest002, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // create a symKey generator + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES128", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // get sym key from preset keyBlob + uint8_t testKey[] = "abcdefghijklmnop"; + uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->convertSymKey(generator, &keyMaterialBlob, &key); + // test api functions + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_UpdateTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // set input and output buf + uint8_t testData[] = "My test data"; + // define input and output data in blob form + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + // test api functions + ret = macObj->update(macObj, &inBlob); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(macObj); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_UpdateTest002, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // cteate key generator and set key text + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES128", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // get sym key from preset keyBlob + uint8_t testKey[] = "abcdefghijklmnop"; + uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->convertSymKey(generator, &keyMaterialBlob, &key); + // define input and output data in blob form + HcfBlob *inBlob = nullptr; + // test api functions + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->update(macObj, inBlob); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_UpdateTest003, TestSize.Level0) +{ + // create a API obj with SM3 + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // cteate key generator and set key text + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES128", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // get sym key from preset keyBlob + uint8_t testKey[] = "abcdefghijklmnop"; + uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->convertSymKey(generator, &keyMaterialBlob, &key); + // set input and output buf + uint8_t testData[] = "My test data"; + // define input and output data in blob form + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + // test api functions + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->update(macObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_DoFinalTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // set input and output buf + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api functions + ret = macObj->doFinal(macObj, &outBlob); + EXPECT_NE(ret, HCF_SUCCESS); + // destroy the API obj and blob data + HcfObjDestroy(macObj); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_DoFinalTest002, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // cteate key generator and set key text + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES128", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // get sym key from preset keyBlob + uint8_t testKey[] = "abcdefghijklmnop"; + uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->convertSymKey(generator, &keyMaterialBlob, &key); + printf("get symkey finish"); + // set input and output buf + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api functions + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + printf("test init finish"); + ret = macObj->doFinal(macObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + printf("test dofinal finish"); + PrintfBlobInHex(outBlob.data, outBlob.len); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + printf("HcfBlobDataClearAndFree finish"); + HcfObjDestroy(macObj); + printf("HcfObjDestroy macObj finish"); + HcfObjDestroy(key); + printf("HcfObjDestroy key finish"); + HcfObjDestroy(generator); + printf("test finish"); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_DoFinalTest003, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // cteate key generator + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES128", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // get sym key from preset keyBlob + uint8_t testKey[] = "abcdefghijklmnop"; + uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->convertSymKey(generator, &keyMaterialBlob, &key); + // set input and output buf + uint8_t testData[] = "My test data"; + // define input and output data in blob form + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api functions + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->update(macObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->doFinal(macObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_DoFinalTest004, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // cteate key generator + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES128", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // get sym key from preset keyBlob + uint8_t testKey[] = "abcdefghijklmnop"; + uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->convertSymKey(generator, &keyMaterialBlob, &key); + // define input and output data in blob form + HcfBlob inBlob = {0}; + inBlob.data = reinterpret_cast(g_testBigData); + inBlob.len = strnlen(g_testBigData, MAX_MAC_BLOB_LEN); + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api functions + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->update(macObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->doFinal(macObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + PrintfBlobInHex(outBlob.data, outBlob.len); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_LenTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // test api functions + uint32_t len = macObj->getMacLength(macObj); + EXPECT_EQ(len, INVALID_LEN); + HcfObjDestroy(macObj); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_LenTest002, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // cteate key generator + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES128", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // get sym key from preset keyBlob + uint8_t testKey[] = "abcdefghijklmnop"; + uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->convertSymKey(generator, &keyMaterialBlob, &key); + // test api functions + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + uint32_t len = macObj->getMacLength(macObj); + EXPECT_EQ(len, SM3_LEN); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_AlgoTest001, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // create a symKey generator + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES128", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // set key data and convert it to key obj + uint8_t testKey[] = "abcdefghijklmnop"; + uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->convertSymKey(generator, &keyMaterialBlob, &key); + // set input and output blob + uint8_t testData[] = "My test data"; + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api funcitons + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->update(macObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->doFinal(macObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + uint32_t len = macObj->getMacLength(macObj); + EXPECT_EQ(len, SM3_LEN); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_AlgoTest002, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // create a symKey generator + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES192", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // set key data and convert it to key obj + //uint8_t testKey[] = "abcdefghijklmnop"; + //uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + //HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->generateSymKey(generator, &key); + // set input and output blob + uint8_t testData[] = "My test data"; + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api funcitons + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->update(macObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->doFinal(macObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + uint32_t len = macObj->getMacLength(macObj); + EXPECT_EQ(len, SM3_LEN); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_AlgoTest003, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // create a symKey generator + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES256", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // set key data and convert it to key obj + //uint8_t testKey[] = "abcdefghijklmnop"; + //uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + //HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->generateSymKey(generator, &key); + // set input and output blob + uint8_t testData[] = "My test data"; + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api funcitons + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->update(macObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->doFinal(macObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + uint32_t len = macObj->getMacLength(macObj); + EXPECT_EQ(len, SM3_LEN); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_AlgoTest004, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // create a symKey generator + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("3DES192", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // set key data and convert it to key obj + //uint8_t testKey[] = "abcdefghijklmnop"; + //uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + //HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->generateSymKey(generator, &key); + // set input and output blob + uint8_t testData[] = "My test data"; + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api funcitons + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->update(macObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->doFinal(macObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + uint32_t len = macObj->getMacLength(macObj); + EXPECT_EQ(len, SM3_LEN); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, CryptoFrameworkHmac_sm3_AlgoTest005, TestSize.Level0) +{ + // create a SM3 obj + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + // create a symKey generator + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // set key data and convert it to key obj + //uint8_t testKey[] = "abcdefghijklmnop"; + //uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + //HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->generateSymKey(generator, &key); + // set input and output blob + uint8_t testData[] = "My test data"; + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api funcitons + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->update(macObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->doFinal(macObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + uint32_t len = macObj->getMacLength(macObj); + EXPECT_EQ(len, SM3_LEN); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +static const char *GetInvalidMac_sm3_Class(void) +{ + return "INVALID_MAC_CLASS"; +} + +HWTEST_F(CryptoMac_Sm3_Test, InvalidInputMac_sm3_Test001, TestSize.Level0) +{ + HcfResult ret = OpensslMacSpiCreate("SM3", nullptr); + EXPECT_NE(ret, HCF_SUCCESS); + HcfMacSpi *spiObj = nullptr; + ret = OpensslMacSpiCreate(nullptr, &spiObj); + EXPECT_NE(ret, HCF_SUCCESS); +} + +HWTEST_F(CryptoMac_Sm3_Test, NullParamMac_sm3_Test001, TestSize.Level0) +{ + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + ret = macObj->init(nullptr, nullptr); + EXPECT_NE(ret, HCF_SUCCESS); + ret = macObj->update(nullptr, nullptr); + EXPECT_NE(ret, HCF_SUCCESS); + ret = macObj->doFinal(nullptr, nullptr); + EXPECT_NE(ret, HCF_SUCCESS); + uint32_t len = macObj->getMacLength(nullptr); + EXPECT_EQ(len, HCF_OPENSSL_INVALID_MAC_LEN); + const char *algoName = macObj->getAlgoName(nullptr); + EXPECT_EQ(algoName, nullptr); + macObj->base.destroy(nullptr); + HcfObjDestroy(macObj); +} + +HWTEST_F(CryptoMac_Sm3_Test, InvalidFrameworkClassMac_sm3_Test001, TestSize.Level0) +{ + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("SM3", &macObj); + ASSERT_EQ(ret, HCF_SUCCESS); + HcfMac invalidMacObj = {{0}}; + invalidMacObj.base.getClass = GetInvalidMac_sm3_Class; + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("AES128", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + uint8_t testKey[] = "abcdefghijklmnop"; + uint32_t testKeyLen = sizeof(testKey) / sizeof(testKey[0]); + HcfSymKey *key = nullptr; + HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->convertSymKey(generator, &keyMaterialBlob, &key); + uint8_t testData[] = "My test data"; + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + ret = macObj->init(&invalidMacObj, key); + EXPECT_NE(ret, HCF_SUCCESS); + ret = macObj->update(&invalidMacObj, &inBlob); + EXPECT_NE(ret, HCF_SUCCESS); + ret = macObj->doFinal(&invalidMacObj, &outBlob); + EXPECT_NE(ret, HCF_SUCCESS); + uint32_t len = macObj->getMacLength(&invalidMacObj); + EXPECT_EQ(len, HCF_OPENSSL_INVALID_MAC_LEN); + const char *algoName = macObj->getAlgoName(&invalidMacObj); + EXPECT_EQ(algoName, nullptr); + HcfBlobDataClearAndFree(&outBlob); + macObj->base.destroy(&(invalidMacObj.base)); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoMac_Sm3_Test, InvalidSpiClassMac_sm3_Test001, TestSize.Level0) +{ + HcfMacSpi *spiObj = nullptr; + HcfMacSpi invalidSpi = {{0}}; + invalidSpi.base.getClass = GetInvalidMac_sm3_Class; + // create a symKey generator + HcfSymKeyGenerator *generator = nullptr; + HcfResult ret = HcfSymKeyGeneratorCreate("AES128", &generator); + ASSERT_EQ(ret, HCF_SUCCESS); + // set key data and convert it to key obj + uint8_t testKey[] = "abcdefghijklmnop"; + uint32_t testKeyLen = 16; + HcfSymKey *key = nullptr; + HcfBlob keyMaterialBlob = {.data = reinterpret_cast(testKey), .len = testKeyLen}; + generator->convertSymKey(generator, &keyMaterialBlob, &key); + // set input and output blob + uint8_t testData[] = "My test data"; + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + ret = OpensslMacSpiCreate("SM3", &spiObj); + EXPECT_EQ(ret, HCF_SUCCESS); + ASSERT_NE(spiObj, nullptr); + (void)spiObj->base.destroy(nullptr); + (void)spiObj->base.destroy(&(invalidSpi.base)); + ret = spiObj->engineInitMac(&invalidSpi, key); + EXPECT_NE(ret, HCF_SUCCESS); + ret = spiObj->engineUpdateMac(&invalidSpi, &inBlob); + EXPECT_NE(ret, HCF_SUCCESS); + ret = spiObj->engineDoFinalMac(&invalidSpi, &outBlob); + EXPECT_NE(ret, HCF_SUCCESS); + uint32_t len = spiObj->engineGetMacLength(&invalidSpi); + EXPECT_EQ(len, INVALID_LEN); + HcfObjDestroy(spiObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} +} \ No newline at end of file diff --git a/test/unittest/src/cryto_sm4_cipher_test.cpp b/test/unittest/src/cryto_sm4_cipher_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ff607b1c3cb2d196457611bb7088b7d753d5d90b --- /dev/null +++ b/test/unittest/src/cryto_sm4_cipher_test.cpp @@ -0,0 +1,973 @@ + +#include +#include +#include +#include "securec.h" + +#include "aes_openssl.h" +#include "blob.h" +#include "cipher.h" +#include "detailed_iv_params.h" +#include "detailed_gcm_params.h" +#include "detailed_ccm_params.h" +#include "log.h" +#include "memory.h" +#include "sym_common_defines.h" +#include "sym_key_generator.h" + +using namespace std; +using namespace testing::ext; + +namespace { + +class CryptoSm4CipherTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void CryptoSm4CipherTest::SetUpTestCase() {} + +void CryptoSm4CipherTest::TearDownTestCase() {} + +void CryptoSm4CipherTest::SetUp() // add init here, this will be called before test. +{ +} + +void CryptoSm4CipherTest::TearDown() // add destroy here, this will be called when test case done. +{ +} + +static int32_t GenerateSymKey(const char *algoName, HcfSymKey **key) +{ + HcfSymKeyGenerator *generator = nullptr; + + int32_t ret = HcfSymKeyGeneratorCreate(algoName, &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!"); + return ret; + } + + ret = generator->generateSymKey(generator, key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + } + HcfObjDestroy((HcfObjectBase *)generator); + return ret; +} + + +static int32_t AesEncrypt(HcfCipher *cipher, HcfSymKey *key, HcfParamsSpec *params, + uint8_t *cipherText, int *cipherTextLen) +{ + uint8_t plainText[] = "this is test!"; + HcfBlob input = {.data = (uint8_t *)plainText, .len = 13}; + HcfBlob output = {}; + int32_t maxLen = *cipherTextLen; + int32_t ret = cipher->init(cipher, ENCRYPT_MODE, (HcfKey *)key, params); + if (ret != 0) { + LOGE("init failed! %d", ret); + return ret; + } + + ret = cipher->update(cipher, &input, &output); + if (ret != 0) { + LOGE("update failed!"); + return ret; + } + *cipherTextLen = output.len; + if (output.data != nullptr) { + if (memcpy_s(cipherText, maxLen, output.data, output.len) != EOK) { + HcfBlobDataFree(&output); + return -1; + } + HcfBlobDataFree(&output); + } + + ret = cipher->doFinal(cipher, nullptr, &output); + if (ret != 0) { + LOGE("doFinal failed!"); + return ret; + } + if (output.data != nullptr) { + if (memcpy_s(cipherText + *cipherTextLen, maxLen - *cipherTextLen, output.data, output.len) != EOK) { + HcfBlobDataFree(&output); + return -1; + } + *cipherTextLen += output.len; + HcfBlobDataFree(&output); + } + + PrintfHex("ciphertext", cipherText, *cipherTextLen); + return 0; +} + +static int32_t AesDecrypt(HcfCipher *cipher, HcfSymKey *key, HcfParamsSpec *params, + uint8_t *cipherText, int cipherTextLen) +{ + uint8_t plainText[] = "this is test!"; + HcfBlob input = {.data = (uint8_t *)cipherText, .len = cipherTextLen}; + HcfBlob output = {}; + int32_t maxLen = cipherTextLen; + int32_t ret = cipher->init(cipher, DECRYPT_MODE, (HcfKey *)key, params); + if (ret != 0) { + LOGE("init failed! %d", ret); + return ret; + } + + ret = cipher->update(cipher, &input, &output); + if (ret != 0) { + LOGE("update failed!"); + return ret; + } + cipherTextLen = output.len; + if (output.data != nullptr) { + if (memcpy_s(cipherText, maxLen, output.data, output.len) != EOK) { + HcfBlobDataFree(&output); + return -1; + } + HcfBlobDataFree(&output); + } + + ret = cipher->doFinal(cipher, nullptr, &output); + if (ret != 0) { + LOGE("doFinal failed!"); + return ret; + } + if (output.data != nullptr) { + if (memcpy_s(cipherText + cipherTextLen, maxLen - cipherTextLen, output.data, output.len) != EOK) { + HcfBlobDataFree(&output); + return -1; + } + cipherTextLen += output.len; + HcfBlobDataFree(&output); + } + + PrintfHex("plainText", cipherText, cipherTextLen); + if (cipherTextLen != sizeof(plainText) - 1) { + return -1; + } + return memcmp(cipherText, plainText, cipherTextLen); +} + +/* +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest001, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CBC|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest002, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CBC|PKCS5", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest003, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CBC|PKCS7", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest004, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[CIPHER_TEXT_LEN] = { 0 }; + int cipherTextLen = CIPHER_TEXT_LEN; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = GenerateSymKey("SM4", &key); + if (ret != 0) { + LOGE("GenerateSymKey failed!"); + goto CLEAR_UP; + } + + // CBC, CTR, OFB, CFB enc/dec success, + // GCM, CCM enc/dec failed with params set to nullptr. + ret = HcfCipherCreate("SM4|ECB|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + } + +CLEAR_UP: + HcfObjDestroy(key); + HcfObjDestroy(cipher); + EXPECT_NE(ret, 0); +} + + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest005, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[CIPHER_TEXT_LEN] = { 0 }; + int cipherTextLen = CIPHER_TEXT_LEN; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = GenerateSymKey("SM4", &key); + if (ret != 0) { + LOGE("GenerateSymKey failed!"); + goto CLEAR_UP; + } + + // CBC, CTR, OFB, CFB enc/dec success, + // GCM, CCM enc/dec failed with params set to nullptr. + ret = HcfCipherCreate("SM4|ECB|PKCS5", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + } + +CLEAR_UP: + HcfObjDestroy(key); + HcfObjDestroy(cipher); + EXPECT_NE(ret, 0); +} + + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest006, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[CIPHER_TEXT_LEN] = { 0 }; + int cipherTextLen = CIPHER_TEXT_LEN; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = GenerateSymKey("SM4", &key); + if (ret != 0) { + LOGE("GenerateSymKey failed!"); + goto CLEAR_UP; + } + + // CBC, CTR, OFB, CFB enc/dec success, + // GCM, CCM enc/dec failed with params set to nullptr. + ret = HcfCipherCreate("SM4|ECB|PKCS7", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + } + +CLEAR_UP: + HcfObjDestroy(key); + HcfObjDestroy(cipher); + EXPECT_NE(ret, 0); +} +*/ + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest007, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CTR|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest008, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CTR|PKCS5", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest009, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CTR|PKCS7", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest0010, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|OFB|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest0011, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|OFB|PKCS5", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest0012, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|OFB|PKCS7", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + + + + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest0013, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CFB|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest0014, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CFB|PKCS5", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest0015, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CFB|PKCS7", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + + + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest0016, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CFB128|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest0017, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CFB128|PKCS5", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSm4CipherTest, CryptoSm4CipherTest0018, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = HcfSymKeyGeneratorCreate("SM4", &generator); + if (ret != 0) { + LOGE("HcfSymKeyGeneratorCreate failed!%d", ret); + goto CLEAR_UP; + } + + ret = generator->generateSymKey(generator, &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4|CFB128|PKCS7", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("AesEncrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("AesDecrypt failed! %d", ret); + goto CLEAR_UP; + } +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + HcfObjDestroy((HcfObjectBase *)generator); + EXPECT_NE(ret, 0); +} + +} \ No newline at end of file diff --git a/test/unittest/src/openssl_adapter_mock.c b/test/unittest/src/openssl_adapter_mock.c index a4ce0e96a9ab69b2efb99acc2e41969058a3d384..37faa745cdf88ea3fdc1e0d7fd82ede8039f0887 100644 --- a/test/unittest/src/openssl_adapter_mock.c +++ b/test/unittest/src/openssl_adapter_mock.c @@ -24,6 +24,12 @@ static uint32_t g_callNum = 0; static bool g_isRecordCallNum = false; static bool g_isNeedSpecialMock = false; +static int EVP_PKEY_CTRL_SM2_ENCRYPT_C1C3C2 = 1; +//static int EVP_PKEY_CTRL_SM2_ENCRYPT_C1C2C3 = 0; + +# define EVP_PKEY_OP_ENCRYPT (1<<9) +# define EVP_PKEY_OP_DECRYPT (1<<10) + static bool Is_Need_Mock(void) { if (!g_isRecordCallNum) { @@ -577,6 +583,14 @@ EVP_PKEY *Openssl_EVP_PKEY_new(void) return EVP_PKEY_new(); } +int Openssl_EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key) +{ + if (Is_Need_Mock()) { + return -1; + } + return EVP_PKEY_set1_EC_KEY(pkey, key); +} + int Openssl_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { if (Is_Need_Mock()) { @@ -660,6 +674,16 @@ int Openssl_EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) return EVP_PKEY_decrypt_init(ctx); } +int Openssl_EVP_PKEY_CTX_encrypt_ctrl(EVP_PKEY_CTX* ctx) +{ + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SM2_ENCRYPT_C1C3C2, 1, NULL); +} + +int Openssl_EVP_PKEY_CTX_decrypt_ctrl(EVP_PKEY_CTX* ctx) +{ + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DECRYPT, EVP_PKEY_CTRL_SM2_ENCRYPT_C1C3C2, 1, NULL); +} + void Openssl_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { EVP_PKEY_CTX_free(ctx); @@ -1064,6 +1088,14 @@ const EVP_MD *Openssl_EVP_md5(void) return EVP_md5(); } +const EVP_MD *Openssl_EVP_sm3(void) +{ + if (Is_Need_Mock()) { + return NULL; + } + return EVP_sm3(); +} + int Openssl_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) { if (Is_Need_Mock()) { @@ -1370,6 +1402,54 @@ const EVP_CIPHER *Openssl_EVP_aes_256_gcm(void) return EVP_aes_256_gcm(); } +const EVP_CIPHER *Openssl_EVP_sm4_ecb(void) +{ + if (Is_Need_Mock()) { + return NULL; + } + return EVP_sm4_ecb(); +} + +const EVP_CIPHER *Openssl_EVP_sm4_cbc(void) +{ + if (Is_Need_Mock()) { + return NULL; + } + return EVP_sm4_cbc(); +} + +const EVP_CIPHER *Openssl_EVP_sm4_ofb(void) +{ + if (Is_Need_Mock()) { + return NULL; + } + return EVP_sm4_ofb(); +} + +const EVP_CIPHER *Openssl_EVP_sm4_ctr(void) +{ + if (Is_Need_Mock()) { + return NULL; + } + return EVP_sm4_ctr(); +} + +const EVP_CIPHER *Openssl_EVP_sm4_cfb(void) +{ + if (Is_Need_Mock()) { + return NULL; + } + return EVP_sm4_cfb(); +} + +const EVP_CIPHER *Openssl_EVP_sm4_cfb128(void) +{ + if (Is_Need_Mock()) { + return NULL; + } + return EVP_sm4_cfb128(); +} + EVP_CIPHER_CTX *Openssl_EVP_CIPHER_CTX_new(void) { if (Is_Need_Mock()) { @@ -1403,6 +1483,7 @@ int Openssl_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *pt return EVP_CIPHER_CTX_ctrl(ctx, type, arg, ptr); } + int Openssl_EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { if (Is_Need_Mock()) {