diff --git a/config/json/feature.json b/config/json/feature.json index 474a9112..5b08e57f 100644 --- a/config/json/feature.json +++ b/config/json/feature.json @@ -174,7 +174,6 @@ "sm9": { "sm9_crypt": null, "sm9_sign": null, - "sm9_exch": null, "deps": ["sm3"] }, "kem": { @@ -1366,7 +1365,7 @@ ] }, "sm9": { - ".features": ["sm9_crypt", "sm9_sign", "sm9_exch"], + ".features": ["sm9_crypt", "sm9_sign"], ".srcs": [ "crypto/sm9/src/*.c" ], diff --git a/config/macro_config/hitls_config_layer_crypto.h b/config/macro_config/hitls_config_layer_crypto.h index 05ac62c3..3e163ece 100644 --- a/config/macro_config/hitls_config_layer_crypto.h +++ b/config/macro_config/hitls_config_layer_crypto.h @@ -535,7 +535,7 @@ #endif #endif -#if defined(HITLS_CRYPTO_SM9_SIGN) || defined(HITLS_CRYPTO_SM9_CRYPT) || defined(HITLS_CRYPTO_SM9_EXCH) +#if defined(HITLS_CRYPTO_SM9_SIGN) || defined(HITLS_CRYPTO_SM9_CRYPT) #ifndef HITLS_CRYPTO_SM9 #define HITLS_CRYPTO_SM9 #endif @@ -551,9 +551,6 @@ #ifndef HITLS_CRYPTO_SM9_CRYPT #define HITLS_CRYPTO_SM9_CRYPT #endif - #ifndef HITLS_CRYPTO_SM9_EXCH - #define HITLS_CRYPTO_SM9_EXCH - #endif #ifndef HITLS_CRYPTO_SM9_CHECK #define HITLS_CRYPTO_SM9_CHECK #endif diff --git a/crypto/codecsdata/src/crypt_encode.c b/crypto/codecsdata/src/crypt_encode.c index d75d381d..cbf63c81 100644 --- a/crypto/codecsdata/src/crypt_encode.c +++ b/crypto/codecsdata/src/crypt_encode.c @@ -72,7 +72,10 @@ static int32_t DecodeAsn1Template(const uint8_t *encode, uint32_t encodeLen, BSL return CRYPT_DECODE_ASN1_BUFF_LEN_ZERO; } } - + if (tmpEnc != encode + encodeLen) { // to ensure all input is consumed. + BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ASN1_BUFF_FAILED); + return CRYPT_DECODE_ASN1_BUFF_FAILED; + } return CRYPT_SUCCESS; } diff --git a/crypto/eal/src/eal_pkey_method.c b/crypto/eal/src/eal_pkey_method.c index 4c9e436a..f8b8fe3b 100644 --- a/crypto/eal/src/eal_pkey_method.c +++ b/crypto/eal/src/eal_pkey_method.c @@ -505,11 +505,7 @@ static const EAL_PkeyMethod METHODS[] = { NULL, // verifyData #endif NULL, // recover -#ifdef HITLS_CRYPTO_SM9_EXCH - CRYPT_SM9_ComputeShareKey, // computeShareKey -#else NULL, // computeShareKey -#endif #ifdef HITLS_CRYPTO_SM9_CRYPT CRYPT_SM9_Encrypt, // encrypt CRYPT_SM9_Decrypt, // decrypt diff --git a/crypto/ecc/src/asm/ecp_sm2_armv8.S b/crypto/ecc/src/asm/ecp_sm2_armv8.S index c6a53e61..5f65081b 100644 --- a/crypto/ecc/src/asm/ecp_sm2_armv8.S +++ b/crypto/ecc/src/asm/ecp_sm2_armv8.S @@ -1705,7 +1705,6 @@ AARCH64_PACIASP add x15, x15,:lo12:.Lpoly+24 // p[3] ldr x15, [x15] - orr x16, x4, x5 orr x19, x6, x7 orr x25, x16, x19 @@ -1888,6 +1887,7 @@ AARCH64_PACIASP ldp x16, x17,[x23] ldp x19, x20,[x23, #16] ldp x8, x9,[x22, #0] + ldp x10, x11,[x22, #16] cmp x24, #0 csel x16, x4, x16,ne @@ -1904,12 +1904,12 @@ AARCH64_PACIASP stp x8, x9,[x21, #0] stp x10, x11,[x21, #16] - ldp x10, x11,[x22, #16] ldp x4, x5,[sp, #32] ldp x6, x7,[sp, #48] ldp x16, x17,[x23, #32] ldp x19, x20,[x23, #48] ldp x8, x9,[x22, #32] + ldp x10, x11,[x22, #48] cmp x24, #0 csel x16, x4, x16,ne diff --git a/crypto/ecc/src/asm_ecp_sm2.c b/crypto/ecc/src/asm_ecp_sm2.c index 196eb310..83838a7c 100644 --- a/crypto/ecc/src/asm_ecp_sm2.c +++ b/crypto/ecc/src/asm_ecp_sm2.c @@ -306,6 +306,10 @@ static int32_t ECP_Sm2WnafMul(SM2_point *r, const BN_BigNum *k, SM2_point p) BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL); return CRYPT_MEM_ALLOC_FAIL; } + if (recodeK->size == 0) { + ECC_ReCodeFree(recodeK); + return CRYPT_SUCCESS; + } SM2_point doublePoint; SM2_point precomputed[PRECOMPUTED_TABLE_SIZE] ALIGN64; ECP_Sm2ToMont(precomputed[0].x, p.x); @@ -468,6 +472,7 @@ int32_t ECP_Sm2PointMulAdd(ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, co ECP_Sm2FromMont(k2Pt.z, k2Pt.z); GOTO_ERR_IF_EX(ECP_Sm2Array2Point(r, &k2Pt), ret); ERR: + BSL_SAL_CleanseData(k1Uint, SM2_LIMBS * sizeof(BN_UINT)); return ret; } diff --git a/crypto/ecc/src/ecp_simple.c b/crypto/ecc/src/ecp_simple.c index 0d8af904..c0217e49 100644 --- a/crypto/ecc/src/ecp_simple.c +++ b/crypto/ecc/src/ecp_simple.c @@ -207,7 +207,7 @@ int32_t ECP_PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const EC for (i = bits - 1; i > 0; i--) { GOTO_ERR_IF(para->method->pointDouble(para, r, r), ret); GOTO_ERR_IF(para->method->pointAddAffine(para, t, r, base), ret); - mask = BN_GetBit(k, i - 1) ? 0 : BN_MASK; + mask = (BN_UINT)BN_GetBit(k, i - 1) - 1; // The last bit must be 1, and r must be updated to the latest data. GOTO_ERR_IF(ECP_PointCopyWithMask(r, t, r, mask), ret); } @@ -910,7 +910,6 @@ static int32_t GetFormatAndCheckLen(const uint8_t *data, uint32_t dataLen, CRYPT uint32_t curveBytes) { if (dataLen < curveBytes + 1) { - BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); return CRYPT_ECC_ERR_POINT_CODE; } uint8_t pc = data[0]; @@ -923,7 +922,6 @@ static int32_t GetFormatAndCheckLen(const uint8_t *data, uint32_t dataLen, CRYPT if (pc == 0x04) { // uncompressed if (dataLen != (curveBytes << 1) + 1) { - BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); return CRYPT_ECC_ERR_POINT_CODE; } *format = CRYPT_POINT_UNCOMPRESSED; @@ -931,21 +929,18 @@ static int32_t GetFormatAndCheckLen(const uint8_t *data, uint32_t dataLen, CRYPT } else if (pc == 0x02 || pc == 0x03) { // compressed if (dataLen != curveBytes + 1) { - BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); return CRYPT_ECC_ERR_POINT_CODE; } *format = CRYPT_POINT_COMPRESSED; return CRYPT_SUCCESS; } else if (pc == 0x06 || pc == 0x07) { - // hybriid + // hybrid if (dataLen != (curveBytes << 1) + 1) { - BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); return CRYPT_ECC_ERR_POINT_CODE; } *format = CRYPT_POINT_HYBRID; return CRYPT_SUCCESS; } - BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_POINT_CODE); return CRYPT_ECC_ERR_POINT_CODE; } @@ -963,8 +958,8 @@ int32_t ECC_DecodePoint(const ECC_Para *para, ECC_Point *pt, const uint8_t *data int32_t ret; uint32_t curveBytes = BN_Bytes(para->p); CRYPT_PKEY_PointFormat format = CRYPT_POINT_UNCOMPRESSED; + RETURN_RET_IF_ERR(GetFormatAndCheckLen(data, dataLen, &format, curveBytes), ret); bool pcBit = ((data[0] & 0x01) == 1); // Parity check. If it's odd, return true. If it's even, return false. - GOTO_ERR_IF(GetFormatAndCheckLen(data, dataLen, &format, curveBytes), ret); GOTO_ERR_IF(BN_SetLimb(&pt->z, 1), ret); if (format == CRYPT_POINT_COMPRESSED) { diff --git a/crypto/rsa/src/rsa_ctrl.c b/crypto/rsa/src/rsa_ctrl.c index 7f7c0518..1db005ec 100644 --- a/crypto/rsa/src/rsa_ctrl.c +++ b/crypto/rsa/src/rsa_ctrl.c @@ -496,7 +496,10 @@ static int32_t RsaSetIso9796_2(CRYPT_RSA_Ctx *ctx, BSL_Param *param) uint32_t len = sizeof(padPara.mdId); int32_t ret = CRYPT_SUCCESS; GOTO_ERR_IF(BSL_PARAM_GetValue(temp, CRYPT_PARAM_RSA_MD_ID, BSL_PARAM_TYPE_INT32, &padPara.mdId, &len), ret); - + if (MdIdCheckSha1Sha2(padPara.mdId) == false) { + BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID); + return CRYPT_EAL_ERR_ALGID; + } void *mdProvCtx = NULL; void *libCtx = LIBCTX_FROM_RSA_CTX(ctx); EAL_MdMethod *mdMeth = EAL_MdFindMethodEx(padPara.mdId, libCtx, MDATTR_FROM_RSA_CTX(ctx), diff --git a/crypto/sm4/include/crypt_sm4.h b/crypto/sm4/include/crypt_sm4.h index 1bd73457..3cf36bb9 100644 --- a/crypto/sm4/include/crypt_sm4.h +++ b/crypto/sm4/include/crypt_sm4.h @@ -223,8 +223,8 @@ int32_t CRYPT_SM4_CBC_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *ou * @param ctx [IN] sm4 Context * @param in [IN] Data to be encrypted * @param out [OUT] Encrypted data - * @param len [IN] Length of the encrypted data - * @param iv [IN] Set IV + * @param len [IN] Number of blocks to be encrypted + * @param iv [IN/OUT] IV (counter), updated after encryption * * @return Success: CRYPT_SUCCESS * Other error codes are returned if the operation fails. @@ -235,9 +235,9 @@ int32_t CRYPT_SM4_CTR_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *ou * @brief SM4 CTR mode decryption (optimized). * @param ctx [IN] sm4 Context * @param in [IN] Data to be decrypted - * @param out [OUT] decrypted data - * @param len [IN] Length of the decrypted data - * @param iv [IN] Set IV + * @param out [OUT] Decrypted data + * @param len [IN] Number of blocks to be decrypted + * @param iv [IN/OUT] IV (counter), updated after decryption * * @return Success: CRYPT_SUCCESS * Other error codes are returned if the operation fails. diff --git a/crypto/sm9/include/crypt_sm9.h b/crypto/sm9/include/crypt_sm9.h index fc1c5845..2f8741aa 100644 --- a/crypto/sm9/include/crypt_sm9.h +++ b/crypto/sm9/include/crypt_sm9.h @@ -29,7 +29,7 @@ extern "C" { * @brief SM9 Context Structure * * Encapsulates all key materials and state information required for - * signature, encryption, and key exchange operations. + * signature and encryption operations. */ struct SM9_Ctx_st { uint8_t sig_msk[SM9_SIG_SYS_PRIKEY_BYTES]; @@ -45,9 +45,6 @@ struct SM9_Ctx_st { uint8_t user_id[256]; uint32_t user_id_len; - uint8_t keyex_r[SM9_CURVE_MODULE_BYTES]; - uint8_t keyex_R[SM9_KEYEX_RA_BYTES]; - uint32_t has_sig_sys : 1; uint32_t has_sig_usr : 1; uint32_t has_sig_g : 1; @@ -74,17 +71,9 @@ int32_t SM9_GenEncUserKey(SM9_Ctx *ctx, const uint8_t *user_id, uint32_t id_len) int32_t SM9_SetEncUserKey(SM9_Ctx *ctx, uint8_t *user_id, uint32_t id_len, uint8_t *dek); int32_t SM9_EncryptCtx(const SM9_Ctx *ctx, const uint8_t *user_id, uint32_t id_len, - const uint8_t *msg, uint32_t mlen, uint8_t *rand, uint8_t *cipher, uint32_t *clen); + const uint8_t *msg, uint32_t mlen, uint8_t *cipher, uint32_t *clen); int32_t SM9_DecryptCtx(const SM9_Ctx *ctx, const uint8_t *cipher, uint32_t clen, uint8_t *msg, uint32_t *mlen); -int32_t SM9_KeyExchangeInit(SM9_Ctx *ctx, uint8_t *peer_id, uint32_t peer_id_len, - int32_t is_initiator, uint8_t *rand, uint8_t *R); -int32_t SM9_KeyExchangeConfirm(SM9_Ctx *ctx, uint8_t *peer_id, uint32_t peer_id_len, - int32_t is_initiator, uint8_t *peer_R, uint32_t klen, - uint8_t *shared_key, uint8_t *confirm_value); -int32_t SM9_KeyExchangeVerify(SM9_Ctx *ctx, uint8_t *peer_id, uint32_t peer_id_len, - int32_t is_initiator, uint8_t *peer_R, uint8_t *peer_confirm); - #ifdef __cplusplus } #endif diff --git a/crypto/sm9/include/crypt_sm9_eal.h b/crypto/sm9/include/crypt_sm9_eal.h index bd25c929..26027f48 100644 --- a/crypto/sm9/include/crypt_sm9_eal.h +++ b/crypto/sm9/include/crypt_sm9_eal.h @@ -20,7 +20,6 @@ * This file provides EAL-compatible interfaces for SM9 algorithms including: * - Digital signature (sign/verify) * - Public key encryption (encrypt/decrypt) - * - Key exchange protocol */ #ifndef CRYPT_SM9_EAL_H @@ -171,17 +170,6 @@ int32_t CRYPT_SM9_Decrypt(const CRYPT_SM9_Ctx *ctx, const uint8_t *data, uint32_t dataLen, uint8_t *out, uint32_t *outLen); -/** - * @brief SM9 key exchange (compute shared key) - * @param selfCtx [IN] Local SM9 context (with encryption user key) - * @param peerCtx [IN] Peer SM9 context (with encryption system public key and user ID) - * @param out [OUT] Shared key output buffer - * @param outLen [IN/OUT] Buffer size / actual key length - * @return CRYPT_SUCCESS on success, error code otherwise - */ -int32_t CRYPT_SM9_ComputeShareKey(const CRYPT_SM9_Ctx *selfCtx, const CRYPT_SM9_Ctx *peerCtx, - uint8_t *out, uint32_t *outLen); - /** * @brief Control function for SM9 operations * @param ctx [IN/OUT] SM9 context diff --git a/crypto/sm9/include/sm9.h b/crypto/sm9/include/sm9.h index f8db7f91..18ad3cc5 100644 --- a/crypto/sm9/include/sm9.h +++ b/crypto/sm9/include/sm9.h @@ -40,6 +40,14 @@ void SM9_Hash_Data(const uint8_t *data, uint32_t len, uint8_t *digest); */ int32_t sm9_rand(uint8_t *p, uint32_t len); +/** + * @brief Check if key is in valid range [1, N-1] + * @param key Key bytes (big-endian) + * @param len Key length in bytes (must be SM9_CURVE_MODULE_BYTES) + * @return CRYPT_SUCCESS if valid, error code otherwise + */ +void SM9_ModifyKeyRange(uint8_t *key); + /*----------------------SM9 algorithem length define--------------------------*/ #define SM9_CURVE_MODULE_BYTES 32 @@ -57,26 +65,13 @@ int32_t sm9_rand(uint8_t *p, uint32_t len); #define SM9_SIGNATURE_BYTES (3*SM9_CURVE_MODULE_BYTES) -#define SM9_KEYEX_RA_BYTES (2*SM9_CURVE_MODULE_BYTES) -#define SM9_KEYEX_RB_BYTES (2*SM9_CURVE_MODULE_BYTES) +#define SM9_ENC_OVERHEAD_BYTES (3*SM9_CURVE_MODULE_BYTES) #define SM9_OPT_DM_MODE0 0x00 #define SM9_OPT_DM_MODE1 0x04 #define SM9_OPT_DM_MODE2 0x02 #define SM9_OPT_DM_MODE3 0x06 -/*----------------------SM9 algorithem error code-----------------------------*/ -#define SM9_OK 0 // OK -#define SM9_ERR_ID_UNUSEABLE 0x3F01 // Current ID cannot use -#define SM9_ERR_RND_UNUSEABLE 0x3F02 // Current rand number cannot use -#define SM9_ERR_BAD_INPUT 0x3F03 -#define SM9_ERR_VERIFY_FAILED 0x3F04 -#define SM9_ERR_INVALID_POINT 0x3F05 -#define SM9_ERR_MAC_FAILED 0x3F06 -#define SM9_ERR_INPUT 0x3F07 -#define SM9_ERR_MODE_UNUSEABLE 0x3F0E -#define SM9_ERR_NODEINFO 0x3F0A -#define SM9_ERR_UNSUPPORT 0x3F0F /*============================================================================*/ @@ -175,84 +170,6 @@ int32_t SM9_Alg_Dec( uint8_t *msg, uint32_t *mlen); -int32_t SM9_Alg_KeyEx_InitA( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *ra, - uint8_t *da, - uint8_t *mpk, - uint8_t *RA); - -int32_t SM9_Alg_KeyEx_InitB( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *rb, - uint8_t *db, - uint8_t *mpk, - uint8_t *RB); - -// User A confirms and generates shared key SK_A and confirmation value SA -// This function only generates, does not verify SB -int32_t SM9_Alg_KeyEx_ConfirmA( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *ra, - uint8_t *RA, - uint8_t *RB, - uint8_t *da, - uint8_t *mpk, - uint32_t klen, - uint8_t *SK, // Output: Shared key - uint8_t *SA); // Output: Confirmation value SA for User A - -// User B confirms and generates shared key SK_B and confirmation value SB -// This function only generates, does not verify SA -int32_t SM9_Alg_KeyEx_ConfirmB( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *rb, - uint8_t *RA, - uint8_t *RB, - uint8_t *db, - uint8_t *mpk, - uint32_t klen, - uint8_t *SK, // Output: Shared key - uint8_t *SB); // Output: Confirmation value SB for User B - -// User B verifies SA received from User A (standalone verification function) -int32_t SM9_Alg_KeyEx_VerifySA( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *rb, - uint8_t *RA, - uint8_t *RB, - uint8_t *db, - uint8_t *mpk, - uint8_t *SA); // Input: SA received from User A - -// User A verifies SB received from User B (standalone verification function) -int32_t SM9_Alg_KeyEx_VerifySB( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *ra, - uint8_t *RA, - uint8_t *RB, - uint8_t *da, - uint8_t *mpk, - uint8_t *SB); // Input: SB received from User B - #ifdef __cplusplus } #endif diff --git a/crypto/sm9/src/sm9.c b/crypto/sm9/src/sm9.c index b23ce29c..4259f773 100644 --- a/crypto/sm9/src/sm9.c +++ b/crypto/sm9/src/sm9.c @@ -24,7 +24,7 @@ #include "crypt_util_rand.h" #include "crypt_errno.h" #include - +#include "bsl_bytes.h" /***************************Compiler-Switches**********************************/ #define SM9_ALG_RND_ENABLE @@ -37,8 +37,6 @@ #define SM9_ENC_SYS_ENABLE #define SM9_ENC_USR_ENABLE -#define SM9_KEYEX_ENABLE - #define SM9_HByteLen 40 #define SM9_HWordLen (SM9_HByteLen/4) @@ -47,10 +45,8 @@ #define SM9_C3_ByteLen (BNByteLen) /*******************************Static Global *********************************/ -static uint8_t SM9_HID_Sign[1] = {0x01}; -static uint8_t SM9_HID_Enc[1] = {0x03}; - -static uint8_t g_RandBuf[BNByteLen] __attribute__((used)); +static const uint8_t SM9_HID_Sign[1] = {0x01}; +static const uint8_t SM9_HID_Enc[1] = {0x03}; /******************************************************************************/ /* SM3 Adaptation Layer for SM9 */ @@ -117,6 +113,16 @@ int32_t sm9_rand(uint8_t *p, uint32_t len) return CRYPT_RandEx(NULL, p, len); } +void SM9_ModifyKeyRange(uint8_t *key) +{ + uint32_t bn[BNWordLen]; + SM9_Bn_ReadBytes(bn, key); + SM9_Fn_LastRes(bn); + bn_add_int(bn, bn, 1, BNWordLen); + SM9_Fn_LastRes(bn); + SM9_Fp_WriteBytes(key, bn); + BSL_SAL_CleanseData(bn, sizeof(bn)); +} /******************************************************************************/ void _ibc_alg_rand(uint8_t *r, uint32_t len) // static @@ -133,7 +139,7 @@ static void _ibc_write_fpbytes(uint8_t *dst, uint32_t *src) BNToByte(src, BNWordLen, dst, &bytelen); } -static void _sm9_hash_h(uint32_t *pwH, uint8_t tag, const uint8_t * msg, uint32_t mlen, uint8_t *add, uint32_t alen) +static void _sm9_hash_h(uint32_t *pwH, uint8_t tag, const uint8_t * msg, uint32_t mlen, const uint8_t *add, uint32_t alen) { SM9_Hash_Ctx ctx; uint8_t ct[4] = {0x00, 0x00, 0x00, 0x01}; @@ -163,7 +169,7 @@ static void _sm9_hash_h(uint32_t *pwH, uint8_t tag, const uint8_t * msg, uint32_ bn_add_int(pwH, pwH, 1, BNWordLen); } -static void SM9_Hash_H1(uint32_t *pwH, const uint8_t *msg, uint32_t mlen, uint8_t *add, uint32_t alen) +static void SM9_Hash_H1(uint32_t *pwH, const uint8_t *msg, uint32_t mlen, const uint8_t *add, uint32_t alen) { _sm9_hash_h(pwH, 0x01, msg, mlen, add, alen); } @@ -222,9 +228,9 @@ int32_t SM9_Alg_Pair(uint8_t *g, uint8_t *p1, uint8_t *p2) // Output to bytes SM9_Fp12_WriteBytes(g, &Fp12_G); - return SM9_OK; + return CRYPT_SUCCESS; #else - return SM9_ERR_UNSUPPORT; + return CRYPT_SM9_ERR_NOT_SUPPORT; #endif /* SM9_PAIR_ENABLE */ } @@ -251,9 +257,9 @@ int32_t SM9_Alg_MSKG(uint8_t *ks, uint8_t *mpk) // Convert System PubKey to bytes(in NormMode) SM9_Ecp2_A_WriteBytes(mpk, &Point_PK); - return SM9_OK; + return CRYPT_SUCCESS; #else - return SM9_ERR_UNSUPPORT; + return CRYPT_SM9_ERR_NOT_SUPPORT; #endif /* SM9_SIG_SYS_ENABLE */ } @@ -272,7 +278,7 @@ int32_t SM9_Alg_USKG(const uint8_t *id, uint32_t ilen, uint8_t *ks, uint8_t *ds) SM9_Fn_Add(BN_t1, BN_t1, BN_t2); // Check t1 != 0 if (SM9_Bn_IsZero(BN_t1)) - return SM9_ERR_ID_UNUSEABLE; + return CRYPT_SM9_ERR_KEY_ERR; // Compute t2 = ks*(t1^-1) BN_GetInv_Mont(BN_t1, BN_t1, sm9_sys_para.EC_N, sm9_sys_para.N_Mc, sm9_sys_para.N_R2, sm9_sys_para.wsize); bn_mont_mul(BN_t2, BN_t1, BN_t2, sm9_sys_para.EC_N, sm9_sys_para.N_Mc, sm9_sys_para.wsize); @@ -282,9 +288,9 @@ int32_t SM9_Alg_USKG(const uint8_t *id, uint32_t ilen, uint8_t *ks, uint8_t *ds) // Convert User PriKey to bytes(in NormMode) SM9_Ecp_A_WriteBytes(ds, &Ecp_ds); - return SM9_OK; + return CRYPT_SUCCESS; #else - return SM9_ERR_UNSUPPORT; + return CRYPT_SM9_ERR_NOT_SUPPORT; #endif /* SM9_SIG_SYS_ENABLE */ } @@ -300,19 +306,11 @@ static int32_t _sm9_alg_sign( SM9_Fp12 Fp12_g; SM9_ECP2_A Ecp2_P; - // Read Random number r(in NormMode) + // Read Random number r(in NormMode), ensure r in [1, N-1] SM9_Bn_ReadBytes(BN_r, r); - SM9_Fn_LastRes(BN_r); - - while (SM9_Bn_IsZero(BN_r)==1) { - int32_t ret = sm9_rand(r, BNByteLen); - if (ret != CRYPT_SUCCESS) { - return SM9_ERR_RND_UNUSEABLE; - } - SM9_Bn_ReadBytes(BN_r, r); - SM9_Fn_LastRes(BN_r); - } + bn_add_int(BN_r, BN_r, 1, BNWordLen); + SM9_Fn_LastRes(BN_r); // Get System Element g and compute g^r if (g) // If g is given @@ -338,13 +336,13 @@ static int32_t _sm9_alg_sign( // l = (r-h) mod N (l should not be zero) SM9_Fn_Sub(BN_r, BN_r, BN_h); if (SM9_Bn_IsZero(BN_r)) - return SM9_ERR_RND_UNUSEABLE; + return CRYPT_SM9_ERR_SIGN_FAILED; // Read User Prikey and convert to MontMode SM9_Ecp_A_ReadBytes(Ecp_s, ds); // S = l * dsA SM9_Ecp_KP(Ecp_s, Ecp_s, BN_r); - return SM9_OK; + return CRYPT_SUCCESS; } #endif /* SM9_SIG_USR_ENABLE */ @@ -367,24 +365,25 @@ int32_t SM9_Sign( int32_t len; #ifndef SM9_ALG_RND_ENABLE - r = g_RandBuf; + uint8_t randBuf[BNByteLen]; + r = randBuf; _ibc_alg_rand(r, BNByteLen); #endif // SM9_ALG_RND_ENABLE ret = _sm9_alg_sign(msg, mlen, ds, r, g, mpk, BN_h, &Ecp_s); - if (ret != SM9_OK) + if (ret != CRYPT_SUCCESS) return ret; // Output Signature to bytes _ibc_write_fpbytes(sign, BN_h); len = SM9_Fp_ECP_A_WriteBytesWithPC(sign + sm9_sys_para.wsize * WordByteLen, opt, &Ecp_s); if (len < 0) - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; *slen = len + sm9_sys_para.wsize*WordByteLen; - return SM9_OK; + return CRYPT_SUCCESS; #else - return SM9_ERR_UNSUPPORT; + return CRYPT_SM9_ERR_NOT_SUPPORT; #endif /* SM9_SIG_USR_ENABLE */ } @@ -459,8 +458,8 @@ static int32_t _sm9_alg_vefiry( SM9_Hash_H2(BN_h1, msg, mlen, pbW, 12 * BNByteLen); // Verify h2 ?= h if (bn_equal(BN_h1, BN_h, BNWordLen)) - return SM9_OK; - return SM9_ERR_VERIFY_FAILED; + return CRYPT_SUCCESS; + return CRYPT_SM9_VERIFY_FAIL; } #endif /* SM9_SIG_USR_ENABLE */ @@ -481,14 +480,18 @@ int32_t SM9_Verify( if (opt == SM9_OPT_DM_MODE1) { if (slen != SM9_SIGNATURE_BYTES + 1) - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } else { if (slen != SM9_SIGNATURE_BYTES) - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } // Read Signature(h,s) and convert s to MontMode SM9_Bn_ReadBytes(BN_h, sign); + // h must be in [1, N-1] + if (SM9_Bn_IsZero(BN_h) || bn_cmp(BN_h, sm9_sys_para.EC_N, sm9_sys_para.wsize) >= 0) { + return CRYPT_SM9_VERIFY_FAIL; + } sign += sm9_sys_para.wsize*WordByteLen; if (SM9_Fp_ECP_A_ReadBytesWithPC(&Ecp_s, opt, sign)) return -1; @@ -523,9 +526,9 @@ int32_t SM9_Alg_MEKG(uint8_t *ke, uint8_t *mpk) // Convert System PubKey to bytes(in NormMode) SM9_Ecp_A_WriteBytes(mpk, &Point_PK); - return SM9_OK; + return CRYPT_SUCCESS; #else - return SM9_ERR_UNSUPPORT; + return CRYPT_SM9_ERR_NOT_SUPPORT; #endif /* SM9_ENC_SYS_ENABLE */ } @@ -544,7 +547,7 @@ int32_t SM9_Alg_UEKG(const uint8_t *id, uint32_t ilen, uint8_t *ke, uint8_t *de) bn_mod_add(BN_t1, BN_t1, BN_t2, sm9_sys_para.EC_N, sm9_sys_para.wsize); // Check t1 != 0 if (bn_is_zero(BN_t1, sm9_sys_para.wsize)) - return SM9_ERR_ID_UNUSEABLE; + return CRYPT_SM9_ERR_KEY_ERR; // Compute t2 = ks*(t1^-1) BN_GetInv_Mont(BN_t1, BN_t1, sm9_sys_para.EC_N, sm9_sys_para.N_Mc, sm9_sys_para.N_R2, sm9_sys_para.wsize); bn_mont_mul(BN_t2, BN_t1, BN_t2, sm9_sys_para.EC_N, sm9_sys_para.N_Mc, sm9_sys_para.wsize); @@ -554,9 +557,9 @@ int32_t SM9_Alg_UEKG(const uint8_t *id, uint32_t ilen, uint8_t *ke, uint8_t *de) // Convert User PriKey to bytes(in NormMode) SM9_Ecp2_A_WriteBytes(de, &Ecp2_ds); - return SM9_OK; + return CRYPT_SUCCESS; #else - return SM9_ERR_UNSUPPORT; + return CRYPT_SM9_ERR_NOT_SUPPORT; #endif /* SM9_ENC_SYS_ENABLE */ } @@ -595,8 +598,11 @@ static void _sm9_enc_init(SM9_CTX *ctx, const uint8_t *id, uint32_t ilen, uint8_ SM9_Fp12 Fp12_g; uint8_t pbW[12 * BNByteLen]; - // Read Random number r(in NormMode) + // Read Random number r(in NormMode), ensure r in [1, N-1] SM9_Bn_ReadBytes(BN_r, r); + SM9_Fn_LastRes(BN_r); + bn_add_int(BN_r, BN_r, 1, BNWordLen); + SM9_Fn_LastRes(BN_r); // Read System PubKey to JPoint in MontMode SM9_Ecp_A_ReadBytes(&Ecp_P, mpk); @@ -705,7 +711,8 @@ int32_t SM9_Alg_Enc(const uint8_t *msg, uint32_t mlen, uint8_t mkey[SM9_Hash_Size]; #ifndef SM9_ALG_RND_ENABLE - r = g_RandBuf; + uint8_t randBuf[BNByteLen]; + r = randBuf; _ibc_alg_rand(r, BNByteLen); #endif // SM9_ALG_RND_ENABLE @@ -720,24 +727,33 @@ int32_t SM9_Alg_Enc(const uint8_t *msg, uint32_t mlen, C2 = C3 + SM9_C3_ByteLen; if ((C2 > msg) && (C2 < msg + mlen)) - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; _sm9_enc_init(&sm9_ctx, id, ilen, r, g, mpk, C1); SM9_Mac_Init(&sm9_ctx); _sm9_pke_kdf(&sm9_ctx, msg, mlen, C2); + SM9_Mac_Update(&sm9_ctx, C2, mlen); + // K1 is all zeros if C2 == msg after XOR, must reject per GM/T 0044-2016 A6 a.1 + // ConstTimeMemcmp returns non-zero when equal + if (mlen > 0 && ConstTimeMemcmp(C2, msg, mlen) != 0) { + BSL_SAL_CleanseData(mkey, SM9_Hash_Size); + return CRYPT_SM9_ERR_ENCRYPT_FAILED; + } + _sm9_pke_kdf(&sm9_ctx, 0, 0, mkey); SM9_Mac_Final(&sm9_ctx, mkey, SM9_Hash_Size, C3); if (elen) *elen = mlen + SM9_C1_ByteLen + SM9_C3_ByteLen; - return SM9_OK; + BSL_SAL_CleanseData(mkey, SM9_Hash_Size); + return CRYPT_SUCCESS; #else - return SM9_ERR_UNSUPPORT; + return CRYPT_SM9_ERR_NOT_SUPPORT; #endif /* SM9_ENC_USR_ENABLE */ } @@ -755,7 +771,7 @@ int32_t SM9_Dec_Init(SM9_CTX *ctx, const uint8_t *de, const uint8_t *id, uint32_ // Check C1 is a point if (SM9_Ecp_A_Check(&Ecp_P)) - return SM9_ERR_INVALID_POINT; + return CRYPT_SM9_ERR_DECRYPT_FAILED; // w'=e(C1, de) SM9_Alg_Pair_Mont(&Fp12_g, &Ecp_P, &Ecp2_D); @@ -764,7 +780,7 @@ int32_t SM9_Dec_Init(SM9_CTX *ctx, const uint8_t *de, const uint8_t *id, uint32_ SM9_Hash_KDF_Init(ctx, C1, pbW, id, ilen); ctx->enc.bytes = 0; - return SM9_OK; + return CRYPT_SUCCESS; } int32_t SM9_Alg_Dec(const uint8_t *enc, uint32_t elen, @@ -778,12 +794,11 @@ int32_t SM9_Alg_Dec(const uint8_t *enc, uint32_t elen, const uint8_t *C3; uint8_t k[2 * SM9_Hash_Size]; uint8_t mac[SM9_C3_ByteLen]; - uint32_t i; uint32_t len; int32_t ret; if (elen < SM9_C1_ByteLen + SM9_C3_ByteLen) - return SM9_ERR_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; len = elen - SM9_C1_ByteLen - SM9_C3_ByteLen; C1 = enc; @@ -791,542 +806,26 @@ int32_t SM9_Alg_Dec(const uint8_t *enc, uint32_t elen, C2 = C3 + SM9_C3_ByteLen; ret = SM9_Dec_Init(&sm9_ctx, de, id, ilen, C1); - if (ret != SM9_OK) + if (ret != CRYPT_SUCCESS) return ret; SM9_Mac_Init(&sm9_ctx); - SM9_Mac_Update(&sm9_ctx, C2, len); _sm9_pke_kdf(&sm9_ctx, 0, len, k); SM9_Mac_Final(&sm9_ctx, k, SM9_Hash_Size, mac); + // Compute MAC(K2', C2) and Compare to C3 - // Compute MAC(K2', C2) and Compare to C3 - for (i = 0; i < SM9_C3_ByteLen; i++) { - if (mac[i] != C3[i]) - return SM9_ERR_MAC_FAILED; + if (ConstTimeMemcmp(mac, C3, SM9_C3_ByteLen) == 0) { + return CRYPT_SM9_ERR_DECRYPT_FAILED; } - _sm9_pke_kdf(&sm9_ctx, C2, len, msg); if (mlen) *mlen = elen - SM9_C1_ByteLen - SM9_C3_ByteLen; - return SM9_OK; + return CRYPT_SUCCESS; #else - return SM9_ERR_UNSUPPORT; + return CRYPT_SM9_ERR_NOT_SUPPORT; #endif /* SM9_ENC_USR_ENABLE */ } -/******************************************************************************/ -/* SM9 Key Exchange */ -/******************************************************************************/ - -#ifdef SM9_KEYEX_ENABLE - -// Key derivation function for key exchange -static void _sm9_keyex_kdf(uint8_t *Z, uint32_t Zlen, uint32_t klen, uint8_t *K) -{ - SM9_Hash_Ctx ctx; - uint8_t ct[4]; - uint32_t cnt = 1; - uint32_t rcnt = klen / SM9_Hash_Size; - uint32_t rbit = klen % SM9_Hash_Size; - uint32_t i; - - for (i = 0; i < rcnt; i++) { - ct[0] = (cnt & 0xFF000000) >> 24; - ct[1] = (cnt & 0x00FF0000) >> 16; - ct[2] = (cnt & 0x0000FF00) >> 8; - ct[3] = cnt & 0x000000FF; - - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, Z, Zlen); - SM9_Hash_Update(&ctx, ct, 4); - SM9_Hash_Final(&ctx, K + i * SM9_Hash_Size); - cnt++; - } - - if (rbit) { - uint8_t tmp[SM9_Hash_Size]; - ct[0] = (cnt & 0xFF000000) >> 24; - ct[1] = (cnt & 0x00FF0000) >> 16; - ct[2] = (cnt & 0x0000FF00) >> 8; - ct[3] = cnt & 0x000000FF; - - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, Z, Zlen); - SM9_Hash_Update(&ctx, ct, 4); - SM9_Hash_Final(&ctx, tmp); - memcpy(K + rcnt * SM9_Hash_Size, tmp, rbit); - } -} - -// Compute hash for key exchange confirmation -__attribute__((unused)) static void _sm9_keyex_hash(uint8_t tag, uint8_t *Z, uint32_t Zlen, uint8_t *hash) -{ - SM9_Hash_Ctx ctx; - uint8_t Ztag[1]; - - Ztag[0] = tag; - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, Ztag, 1); - SM9_Hash_Update(&ctx, Z, Zlen); - SM9_Hash_Final(&ctx, hash); -} - -int32_t SM9_Alg_KeyEx_InitA( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *ra, - uint8_t *da, - uint8_t *mpk, - uint8_t *RA) -{ -#ifdef SM9_KEYEX_ENABLE - uint32_t BN_ra[BNWordLen]; - SM9_ECP_A Ecp_QB; - SM9_ECP_A Ecp_RA; - uint32_t BN_h1[BNWordLen]; - - (void)ida; - (void)ilen_a; - (void)da; - - // Read random number ra - SM9_Bn_ReadBytes(BN_ra, ra); - SM9_Fn_LastRes(BN_ra); - if (SM9_Bn_IsZero(BN_ra)) - return SM9_ERR_RND_UNUSEABLE; - - // Read system public key (for encryption system, mpk is on G1) - SM9_Ecp_A_ReadBytes(&Ecp_QB, mpk); - - // Compute h1 = H1(IDB||hid, N) - Note: use IDB for QB! Must use same HID as key generation - SM9_Hash_H1(BN_h1, idb, ilen_b, SM9_HID_Enc, 1); - - // Compute QB = [h1]P1 + Ppub - SM9_Fp_ECP_KPAddAToA(&Ecp_QB, &sm9_sys_para.EC_Fp_G_Mont, BN_h1, &Ecp_QB, &sm9_sys_para); - - // Compute RA = [ra]QB - SM9_Ecp_KP(&Ecp_RA, &Ecp_QB, BN_ra); - - // Output RA - SM9_Ecp_A_WriteBytes(RA, &Ecp_RA); - - return SM9_OK; -#else - return SM9_ERR_UNSUPPORT; -#endif -} - -int32_t SM9_Alg_KeyEx_InitB( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *rb, - uint8_t *db, - uint8_t *mpk, - uint8_t *RB) -{ -#ifdef SM9_KEYEX_ENABLE - uint32_t BN_rb[BNWordLen]; - SM9_ECP_A Ecp_QA; - SM9_ECP_A Ecp_RB; - uint32_t BN_h1[BNWordLen]; - - (void)idb; - (void)ilen_b; - (void)db; - - // Read random number rb - SM9_Bn_ReadBytes(BN_rb, rb); - SM9_Fn_LastRes(BN_rb); - if (SM9_Bn_IsZero(BN_rb)) - return SM9_ERR_RND_UNUSEABLE; - - // Read system public key (for encryption system, mpk is on G1) - SM9_Ecp_A_ReadBytes(&Ecp_QA, mpk); - - // Compute h1 = H1(IDA||hid, N) - Note: use IDA for QA! Must use same HID as key generation - SM9_Hash_H1(BN_h1, ida, ilen_a, SM9_HID_Enc, 1); - - // Compute QA = [h1]P1 + Ppub - SM9_Fp_ECP_KPAddAToA(&Ecp_QA, &sm9_sys_para.EC_Fp_G_Mont, BN_h1, &Ecp_QA, &sm9_sys_para); - - // Compute RB = [rb]QA - SM9_Ecp_KP(&Ecp_RB, &Ecp_QA, BN_rb); - - // Output RB - SM9_Ecp_A_WriteBytes(RB, &Ecp_RB); - - return SM9_OK; -#else - return SM9_ERR_UNSUPPORT; -#endif -} - -int32_t SM9_Alg_KeyEx_ConfirmA( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *ra, - uint8_t *RA, - uint8_t *RB, - uint8_t *da, - uint8_t *mpk, - uint32_t klen, - uint8_t *SK, - uint8_t *SA) -{ -#ifdef SM9_KEYEX_ENABLE - uint32_t BN_ra[BNWordLen]; - SM9_ECP2_A Ecp2_dA; - SM9_ECP_A Ecp_RB; - SM9_Fp12 Fp12_g1, Fp12_g2, Fp12_g3; - uint8_t g1_bytes[12 * BNByteLen]; - uint8_t g2_bytes[12 * BNByteLen]; - uint8_t g3_bytes[12 * BNByteLen]; - uint8_t Z[2048]; - uint32_t Zlen = 0; - uint8_t inner_hash[SM9_Hash_Size]; - SM9_Hash_Ctx ctx; - - // Read random number ra - SM9_Bn_ReadBytes(BN_ra, ra); - - // Read user private key dA (for encryption system, it's on G2) - SM9_Ecp2_A_ReadBytes(&Ecp2_dA, da); - - // Read RB (G1 point) - SM9_Ecp_A_ReadBytes(&Ecp_RB, RB); - - // User A computes (according to the diagram): - // g1 = e(Ppub, P2)^rA - SM9_ECP_A Ecp_Ppub; - SM9_Ecp_A_ReadBytes(&Ecp_Ppub, mpk); - SM9_Alg_Pair_Mont(&Fp12_g1, &Ecp_Ppub, &sm9_sys_para.EC_Fp2_G_Mont); - SM9_Fp12_Exp(&Fp12_g1, &Fp12_g1, BN_ra); - - // g2 = e(RB, dA) - SM9_Alg_Pair_Mont(&Fp12_g2, &Ecp_RB, &Ecp2_dA); - - // g3 = g2^rA - SM9_Fp12_Exp(&Fp12_g3, &Fp12_g2, BN_ra); - - // Convert to bytes - SM9_Fp12_WriteBytes(g1_bytes, &Fp12_g1); - SM9_Fp12_WriteBytes(g2_bytes, &Fp12_g2); - SM9_Fp12_WriteBytes(g3_bytes, &Fp12_g3); - - // Compute inner_hash = Hash(g2 || g3 || IDA || IDB || RA || RB) - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, g2_bytes, 12 * BNByteLen); - SM9_Hash_Update(&ctx, g3_bytes, 12 * BNByteLen); - SM9_Hash_Update(&ctx, ida, ilen_a); - SM9_Hash_Update(&ctx, idb, ilen_b); - SM9_Hash_Update(&ctx, RA, 2 * BNByteLen); - SM9_Hash_Update(&ctx, RB, 2 * BNByteLen); - SM9_Hash_Final(&ctx, inner_hash); - - // Compute Z = g1 || Hash(g2||g3||IDA||IDB||RA||RB) - // (according to diagram note: X=g1||Hash(g2||g3||IDA||IDB||RA||RB)) - memcpy(Z + Zlen, g1_bytes, 12 * BNByteLen); - Zlen += 12 * BNByteLen; - memcpy(Z + Zlen, inner_hash, SM9_Hash_Size); - Zlen += SM9_Hash_Size; - - // Derive shared key: SK = KDF(IDA||IDB||RA||RB||g1||g2||g3, klen) - _sm9_keyex_kdf(Z, Zlen, klen, SK); - - // Compute SA = Hash(0x82 || g1 || Hash(g2||g3||IDA||IDB||RA||RB)) - if (SA) { - uint8_t temp[1 + 12 * BNByteLen + SM9_Hash_Size]; - temp[0] = 0x82; - memcpy(temp + 1, g1_bytes, 12 * BNByteLen); - memcpy(temp + 1 + 12 * BNByteLen, inner_hash, SM9_Hash_Size); - - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, temp, 1 + 12 * BNByteLen + SM9_Hash_Size); - SM9_Hash_Final(&ctx, SA); - } - - return SM9_OK; -#else - return SM9_ERR_UNSUPPORT; -#endif -} - -int32_t SM9_Alg_KeyEx_ConfirmB( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *rb, - uint8_t *RA, - uint8_t *RB, - uint8_t *db, - uint8_t *mpk, - uint32_t klen, - uint8_t *SK, - uint8_t *SB) -{ -#ifdef SM9_KEYEX_ENABLE - uint32_t BN_rb[BNWordLen]; - SM9_ECP2_A Ecp2_dB; - SM9_ECP_A Ecp_RA; - SM9_Fp12 Fp12_g1, Fp12_g2, Fp12_g3; - uint8_t g1_bytes[12 * BNByteLen]; - uint8_t g2_bytes[12 * BNByteLen]; - uint8_t g3_bytes[12 * BNByteLen]; - uint8_t Z[2048]; - uint32_t Zlen = 0; - uint8_t inner_hash[SM9_Hash_Size]; - SM9_Hash_Ctx ctx; - - // Read random number rb - SM9_Bn_ReadBytes(BN_rb, rb); - - // Read user private key dB (for encryption system, it's on G2) - SM9_Ecp2_A_ReadBytes(&Ecp2_dB, db); - - // Read RA (G1 point) - SM9_Ecp_A_ReadBytes(&Ecp_RA, RA); - - // User B computes (according to the diagram): - // g1 = e(RA, dB) - SM9_Alg_Pair_Mont(&Fp12_g1, &Ecp_RA, &Ecp2_dB); - - // g2 = e(Ppub, P2)^rB - SM9_ECP_A Ecp_Ppub; - SM9_Ecp_A_ReadBytes(&Ecp_Ppub, mpk); - SM9_Alg_Pair_Mont(&Fp12_g2, &Ecp_Ppub, &sm9_sys_para.EC_Fp2_G_Mont); - SM9_Fp12_Exp(&Fp12_g2, &Fp12_g2, BN_rb); - - // g3 = g1^rB - SM9_Fp12_Exp(&Fp12_g3, &Fp12_g1, BN_rb); - - // Convert to bytes - SM9_Fp12_WriteBytes(g1_bytes, &Fp12_g1); - SM9_Fp12_WriteBytes(g2_bytes, &Fp12_g2); - SM9_Fp12_WriteBytes(g3_bytes, &Fp12_g3); - - // Compute inner_hash = Hash(g2 || g3 || IDA || IDB || RA || RB) - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, g2_bytes, 12 * BNByteLen); - SM9_Hash_Update(&ctx, g3_bytes, 12 * BNByteLen); - SM9_Hash_Update(&ctx, ida, ilen_a); - SM9_Hash_Update(&ctx, idb, ilen_b); - SM9_Hash_Update(&ctx, RA, 2 * BNByteLen); - SM9_Hash_Update(&ctx, RB, 2 * BNByteLen); - SM9_Hash_Final(&ctx, inner_hash); - - // Compute Z = g1 || Hash(g2||g3||IDA||IDB||RA||RB) - memcpy(Z + Zlen, g1_bytes, 12 * BNByteLen); - Zlen += 12 * BNByteLen; - memcpy(Z + Zlen, inner_hash, SM9_Hash_Size); - Zlen += SM9_Hash_Size; - - // Derive shared key: SK = KDF(Z, klen) - _sm9_keyex_kdf(Z, Zlen, klen, SK); - - // Compute SB = Hash(0x83 || g1 || Hash(g2||g3||IDA||IDB||RA||RB)) - if (SB) { - uint8_t temp[1 + 12 * BNByteLen + SM9_Hash_Size]; - - temp[0] = 0x83; - memcpy(temp + 1, g1_bytes, 12 * BNByteLen); - memcpy(temp + 1 + 12 * BNByteLen, inner_hash, SM9_Hash_Size); - - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, temp, 1 + 12 * BNByteLen + SM9_Hash_Size); - SM9_Hash_Final(&ctx, SB); - } - - return SM9_OK; -#else - return SM9_ERR_UNSUPPORT; -#endif -} - -// Verify SA received from User A (for User B to verify A's confirmation) -int32_t SM9_Alg_KeyEx_VerifySA( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *rb, - uint8_t *RA, - uint8_t *RB, - uint8_t *db, - uint8_t *mpk, - uint8_t *SA) -{ -#ifdef SM9_KEYEX_ENABLE - uint32_t BN_rb[BNWordLen]; - SM9_ECP2_A Ecp2_dB; - SM9_ECP_A Ecp_RA; - SM9_Fp12 Fp12_g1, Fp12_g2, Fp12_g3; - uint8_t g1_bytes[12 * BNByteLen]; - uint8_t g2_bytes[12 * BNByteLen]; - uint8_t g3_bytes[12 * BNByteLen]; - uint8_t inner_hash[SM9_Hash_Size]; - uint8_t expected_sa[SM9_Hash_Size]; - SM9_Hash_Ctx ctx; - uint32_t i; - - // Read random number rb - SM9_Bn_ReadBytes(BN_rb, rb); - - // Read user private key dB (for encryption system, it's on G2) - SM9_Ecp2_A_ReadBytes(&Ecp2_dB, db); - - // Read RA (G1 point) - SM9_Ecp_A_ReadBytes(&Ecp_RA, RA); - - // User B computes (same as in ConfirmB): - // g1 = e(RA, dB) - SM9_Alg_Pair_Mont(&Fp12_g1, &Ecp_RA, &Ecp2_dB); - - // g2 = e(Ppub, P2)^rB - SM9_ECP_A Ecp_Ppub; - SM9_Ecp_A_ReadBytes(&Ecp_Ppub, mpk); - SM9_Alg_Pair_Mont(&Fp12_g2, &Ecp_Ppub, &sm9_sys_para.EC_Fp2_G_Mont); - SM9_Fp12_Exp(&Fp12_g2, &Fp12_g2, BN_rb); - - // g3 = g1^rB - SM9_Fp12_Exp(&Fp12_g3, &Fp12_g1, BN_rb); - - // Convert to bytes - SM9_Fp12_WriteBytes(g1_bytes, &Fp12_g1); - SM9_Fp12_WriteBytes(g2_bytes, &Fp12_g2); - SM9_Fp12_WriteBytes(g3_bytes, &Fp12_g3); - - // Compute inner_hash = Hash(g2 || g3 || IDA || IDB || RA || RB) - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, g2_bytes, 12 * BNByteLen); - SM9_Hash_Update(&ctx, g3_bytes, 12 * BNByteLen); - SM9_Hash_Update(&ctx, ida, ilen_a); - SM9_Hash_Update(&ctx, idb, ilen_b); - SM9_Hash_Update(&ctx, RA, 2 * BNByteLen); - SM9_Hash_Update(&ctx, RB, 2 * BNByteLen); - SM9_Hash_Final(&ctx, inner_hash); - - // Compute expected SA = Hash(0x82 || g1 || Hash(g2||g3||IDA||IDB||RA||RB)) - { - uint8_t temp[1 + 12 * BNByteLen + SM9_Hash_Size]; - - temp[0] = 0x82; - memcpy(temp + 1, g1_bytes, 12 * BNByteLen); - memcpy(temp + 1 + 12 * BNByteLen, inner_hash, SM9_Hash_Size); - - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, temp, 1 + 12 * BNByteLen + SM9_Hash_Size); - SM9_Hash_Final(&ctx, expected_sa); - } - - // Verify SA - for (i = 0; i < SM9_Hash_Size; i++) { - if (SA[i] != expected_sa[i]) - return SM9_ERR_VERIFY_FAILED; - } - - return SM9_OK; -#else - return SM9_ERR_UNSUPPORT; -#endif -} - -// Verify SB received from User B (for User A to verify B's confirmation) -int32_t SM9_Alg_KeyEx_VerifySB( - uint8_t *ida, - uint32_t ilen_a, - uint8_t *idb, - uint32_t ilen_b, - uint8_t *ra, - uint8_t *RA, - uint8_t *RB, - uint8_t *da, - uint8_t *mpk, - uint8_t *SB) -{ -#ifdef SM9_KEYEX_ENABLE - uint32_t BN_ra[BNWordLen]; - SM9_ECP2_A Ecp2_dA; - SM9_ECP_A Ecp_RB; - SM9_Fp12 Fp12_g1, Fp12_g2, Fp12_g3; - uint8_t g1_bytes[12 * BNByteLen]; - uint8_t g2_bytes[12 * BNByteLen]; - uint8_t g3_bytes[12 * BNByteLen]; - uint8_t inner_hash[SM9_Hash_Size]; - uint8_t expected_sb[SM9_Hash_Size]; - SM9_Hash_Ctx ctx; - uint32_t i; - - // Read random number ra - SM9_Bn_ReadBytes(BN_ra, ra); - - // Read user private key dA (for encryption system, it's on G2) - SM9_Ecp2_A_ReadBytes(&Ecp2_dA, da); - - // Read RB (G1 point) - SM9_Ecp_A_ReadBytes(&Ecp_RB, RB); - - // User A computes (same as in ConfirmA): - // g1 = e(Ppub, P2)^rA - SM9_ECP_A Ecp_Ppub; - SM9_Ecp_A_ReadBytes(&Ecp_Ppub, mpk); - SM9_Alg_Pair_Mont(&Fp12_g1, &Ecp_Ppub, &sm9_sys_para.EC_Fp2_G_Mont); - SM9_Fp12_Exp(&Fp12_g1, &Fp12_g1, BN_ra); - - // g2 = e(RB, dA) - SM9_Alg_Pair_Mont(&Fp12_g2, &Ecp_RB, &Ecp2_dA); - - // g3 = g2^rA - SM9_Fp12_Exp(&Fp12_g3, &Fp12_g2, BN_ra); - - // Convert to bytes - SM9_Fp12_WriteBytes(g1_bytes, &Fp12_g1); - SM9_Fp12_WriteBytes(g2_bytes, &Fp12_g2); - SM9_Fp12_WriteBytes(g3_bytes, &Fp12_g3); - - // Compute inner_hash = Hash(g2 || g3 || IDA || IDB || RA || RB) - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, g2_bytes, 12 * BNByteLen); - SM9_Hash_Update(&ctx, g3_bytes, 12 * BNByteLen); - SM9_Hash_Update(&ctx, ida, ilen_a); - SM9_Hash_Update(&ctx, idb, ilen_b); - SM9_Hash_Update(&ctx, RA, 2 * BNByteLen); - SM9_Hash_Update(&ctx, RB, 2 * BNByteLen); - SM9_Hash_Final(&ctx, inner_hash); - - // Compute expected SB = Hash(0x83 || g1 || Hash(g2||g3||IDA||IDB||RA||RB)) - { - uint8_t temp[1 + 12 * BNByteLen + SM9_Hash_Size]; - - temp[0] = 0x83; - memcpy(temp + 1, g1_bytes, 12 * BNByteLen); - memcpy(temp + 1 + 12 * BNByteLen, inner_hash, SM9_Hash_Size); - - SM9_Hash_Init(&ctx); - SM9_Hash_Update(&ctx, temp, 1 + 12 * BNByteLen + SM9_Hash_Size); - SM9_Hash_Final(&ctx, expected_sb); - } - - // Verify SB - for (i = 0; i < SM9_Hash_Size; i++) { - if (SB[i] != expected_sb[i]) - return SM9_ERR_VERIFY_FAILED; - } - - return SM9_OK; -#else - return SM9_ERR_UNSUPPORT; -#endif -} - #endif // HITLS_CRYPTO_SM9 - -#endif /* SM9_KEYEX_ENABLE */ diff --git a/crypto/sm9/src/sm9_crypt.c b/crypto/sm9/src/sm9_crypt.c index 709f9b38..91d3b886 100644 --- a/crypto/sm9/src/sm9_crypt.c +++ b/crypto/sm9/src/sm9_crypt.c @@ -19,6 +19,7 @@ #include "crypt_sm9.h" #include "crypt_errno.h" #include "sm9.h" +#include "bsl_sal.h" #include /*============================================================================*/ @@ -26,54 +27,54 @@ int32_t SM9_SetEncMasterKey(SM9_Ctx *ctx, uint8_t *msk) { if (!ctx || !msk) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } memcpy(ctx->enc_msk, msk, SM9_ENC_SYS_PRIKEY_BYTES); int32_t ret = SM9_Alg_MEKG(ctx->enc_msk, ctx->enc_mpk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return ret; } ret = SM9_Get_Enc_G(ctx->enc_g, ctx->enc_mpk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return ret; } ctx->has_enc_sys = 1; ctx->has_enc_g = 1; - return SM9_OK; + return CRYPT_SUCCESS; } int32_t SM9_GenEncUserKey(SM9_Ctx *ctx, const uint8_t *user_id, uint32_t id_len) { if (!ctx || !user_id || id_len == 0 || id_len > 256) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } if (!ctx->has_enc_sys) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } memcpy(ctx->user_id, user_id, id_len); ctx->user_id_len = id_len; int32_t ret = SM9_Alg_UEKG(user_id, id_len, ctx->enc_msk, ctx->enc_dek); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return ret; } ctx->has_enc_usr = 1; - return SM9_OK; + return CRYPT_SUCCESS; } int32_t SM9_SetEncUserKey(SM9_Ctx *ctx, uint8_t *user_id, uint32_t id_len, uint8_t *dek) { if (!ctx || !user_id || id_len == 0 || id_len > 256 || !dek) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } memcpy(ctx->user_id, user_id, id_len); @@ -83,46 +84,43 @@ int32_t SM9_SetEncUserKey(SM9_Ctx *ctx, uint8_t *user_id, uint32_t id_len, uint8 ctx->has_enc_usr = 1; - return SM9_OK; + return CRYPT_SUCCESS; } /*============================================================================*/ /*============================================================================*/ int32_t SM9_EncryptCtx(const SM9_Ctx *ctx, const uint8_t *user_id, uint32_t id_len, - const uint8_t *msg, uint32_t mlen, uint8_t *rand, uint8_t *cipher, uint32_t *clen) + const uint8_t *msg, uint32_t mlen, uint8_t *cipher, uint32_t *clen) { - static uint8_t default_rand[32]; + uint8_t randBuf[32]; + int32_t ret; if (!ctx || !user_id || !msg || !cipher || !clen) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } if (!ctx->has_enc_sys) { - return SM9_ERR_BAD_INPUT; - } - - if (!rand) { - int32_t ret = sm9_rand(default_rand, sizeof(default_rand)); - if (ret != CRYPT_SUCCESS) { - return SM9_ERR_RND_UNUSEABLE; - } - rand = default_rand; + return CRYPT_SM9_ERR_BAD_INPUT; } const uint8_t *g_ptr = ctx->has_enc_g ? ctx->enc_g : NULL; - return SM9_Alg_Enc(msg, mlen, user_id, id_len, rand, g_ptr, ctx->enc_mpk, cipher, clen); + ret = sm9_rand(randBuf, sizeof(randBuf)); + if (ret != CRYPT_SUCCESS) { + return CRYPT_SM9_ERR_ENCRYPT_FAILED; + } + return SM9_Alg_Enc(msg, mlen, user_id, id_len, randBuf, g_ptr, ctx->enc_mpk, cipher, clen); } int32_t SM9_DecryptCtx(const SM9_Ctx *ctx, const uint8_t *cipher, uint32_t clen, uint8_t *msg, uint32_t *mlen) { if (!ctx || !cipher || !msg || !mlen) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } if (!ctx->has_enc_usr) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } return SM9_Alg_Dec(cipher, clen, ctx->enc_dek, ctx->user_id, ctx->user_id_len, msg, mlen); diff --git a/crypto/sm9/src/sm9_eal.c b/crypto/sm9/src/sm9_eal.c index 198974ca..60808505 100644 --- a/crypto/sm9/src/sm9_eal.c +++ b/crypto/sm9/src/sm9_eal.c @@ -109,25 +109,27 @@ int32_t CRYPT_SM9_Gen(CRYPT_SM9_Ctx *ctx) uint8_t sig_msk[SM9_SIG_SYS_PRIKEY_BYTES]; uint8_t enc_msk[SM9_ENC_SYS_PRIKEY_BYTES]; - /* Generate random master private key for signature */ + /* Generate random master private key for signature in [1, N-1] */ ret = sm9_rand(sig_msk, SM9_SIG_SYS_PRIKEY_BYTES); if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_ERR_KEY_ERR; } + SM9_ModifyKeyRange(sig_msk); ret = SM9_SetSignMasterKey(ctx, sig_msk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { BSL_SAL_CleanseData(sig_msk, SM9_SIG_SYS_PRIKEY_BYTES); return CRYPT_SM9_ERR_KEY_ERR; } - /* Generate random master private key for encryption */ + /* Generate random master private key for encryption in [1, N-1] */ ret = sm9_rand(enc_msk, SM9_ENC_SYS_PRIKEY_BYTES); if (ret != CRYPT_SUCCESS) { BSL_SAL_CleanseData(sig_msk, SM9_SIG_SYS_PRIKEY_BYTES); return CRYPT_SM9_ERR_KEY_ERR; } + SM9_ModifyKeyRange(enc_msk); ret = SM9_SetEncMasterKey(ctx, enc_msk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { BSL_SAL_CleanseData(sig_msk, SM9_SIG_SYS_PRIKEY_BYTES); BSL_SAL_CleanseData(enc_msk, SM9_ENC_SYS_PRIKEY_BYTES); return CRYPT_SM9_ERR_KEY_ERR; @@ -136,14 +138,14 @@ int32_t CRYPT_SM9_Gen(CRYPT_SM9_Ctx *ctx) /* If user ID is set, generate user keys */ if (ctx->user_id_len > 0) { ret = SM9_GenSignUserKey(ctx, ctx->user_id, ctx->user_id_len); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { BSL_SAL_CleanseData(sig_msk, SM9_SIG_SYS_PRIKEY_BYTES); BSL_SAL_CleanseData(enc_msk, SM9_ENC_SYS_PRIKEY_BYTES); return CRYPT_SM9_ERR_KEY_ERR; } ret = SM9_GenEncUserKey(ctx, ctx->user_id, ctx->user_id_len); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { BSL_SAL_CleanseData(sig_msk, SM9_SIG_SYS_PRIKEY_BYTES); BSL_SAL_CleanseData(enc_msk, SM9_ENC_SYS_PRIKEY_BYTES); return CRYPT_SM9_ERR_KEY_ERR; @@ -234,14 +236,14 @@ int32_t CRYPT_SM9_SetPubKeyEx(CRYPT_SM9_Ctx *ctx, const BSL_Param *param) } else if (masterPrvKey != NULL) { /* Generate master public key from master private key */ ret = SM9_Alg_MSKG(ctx->sig_msk, ctx->sig_mpk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_ERR_SIGN_FAILED; } } /* Generate sig_g from master public key */ ret = SM9_Get_Sig_G(ctx->sig_g, ctx->sig_mpk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_ERR_ENCRYPT_FAILED; } @@ -271,14 +273,14 @@ int32_t CRYPT_SM9_SetPubKeyEx(CRYPT_SM9_Ctx *ctx, const BSL_Param *param) } else if (masterPrvKey != NULL) { /* Generate master public key from master private key */ ret = SM9_Alg_MEKG(ctx->enc_msk, ctx->enc_mpk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_ERR_KEY_ERR; } } /* Generate enc_g from master public key */ ret = SM9_Get_Enc_G(ctx->enc_g, ctx->enc_mpk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_ERR_KEY_ERR; } @@ -316,10 +318,11 @@ int32_t CRYPT_SM9_SetPrvKeyEx(CRYPT_SM9_Ctx *ctx, const BSL_Param *param) userId = (const uint8_t *)p->value; userIdLen = p->valueLen; /* Store user ID in context */ - if (userIdLen <= sizeof(ctx->user_id)) { - memcpy(ctx->user_id, userId, userIdLen); - ctx->user_id_len = userIdLen; + if (userIdLen > sizeof(ctx->user_id)) { + return CRYPT_SM9_ERR_BAD_INPUT; } + memcpy(ctx->user_id, userId, userIdLen); + ctx->user_id_len = userIdLen; } else if (ctx->user_id_len > 0) { /* Use user ID from context if not provided in parameter */ userId = ctx->user_id; @@ -347,7 +350,7 @@ int32_t CRYPT_SM9_SetPrvKeyEx(CRYPT_SM9_Ctx *ctx, const BSL_Param *param) /* Generate signature user key from master key */ /* Note: SM9_GenSignUserKey will also save user_id to ctx, but we already saved it above */ ret = SM9_GenSignUserKey(ctx, userId, userIdLen); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_ERR_KEY_ERR; } @@ -359,7 +362,7 @@ int32_t CRYPT_SM9_SetPrvKeyEx(CRYPT_SM9_Ctx *ctx, const BSL_Param *param) /* Generate encryption user key from master key */ ret = SM9_GenEncUserKey(ctx, userId, userIdLen); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_ERR_KEY_ERR; } } @@ -494,11 +497,15 @@ int32_t CRYPT_SM9_Sign(const CRYPT_SM9_Ctx *ctx, int32_t mdId, return CRYPT_NULL_INPUT; } + if (*signLen < SM9_SIGNATURE_BYTES) { + return CRYPT_SM9_BUFF_LEN_NOT_ENOUGH; + } + /* SM9 signature always uses SM3, mdId is ignored for compatibility */ (void)mdId; int32_t ret = SM9_SignCtx(ctx, data, dataLen, NULL, sign); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_ERR_SIGN_FAILED; } @@ -529,7 +536,7 @@ int32_t CRYPT_SM9_Verify(const CRYPT_SM9_Ctx *ctx, int32_t mdId, } int32_t ret = SM9_VerifyCtx(ctx, ctx->user_id, ctx->user_id_len, data, dataLen, sign); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_VERIFY_FAIL; } @@ -549,9 +556,14 @@ int32_t CRYPT_SM9_Encrypt(const CRYPT_SM9_Ctx *ctx, return CRYPT_SM9_ERR_NO_USER_ID; } + uint32_t requiredLen = dataLen + SM9_ENC_OVERHEAD_BYTES; + if (requiredLen < dataLen || *outLen < requiredLen) { + return CRYPT_SM9_BUFF_LEN_NOT_ENOUGH; + } + uint32_t cipherLen = *outLen; - int32_t ret = SM9_EncryptCtx(ctx, ctx->user_id, ctx->user_id_len, data, dataLen, NULL, out, &cipherLen); - if (ret != SM9_OK) { + int32_t ret = SM9_EncryptCtx(ctx, ctx->user_id, ctx->user_id_len, data, dataLen, out, &cipherLen); + if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_ERR_ENCRYPT_FAILED; } @@ -567,9 +579,18 @@ int32_t CRYPT_SM9_Decrypt(const CRYPT_SM9_Ctx *ctx, return CRYPT_NULL_INPUT; } + if (dataLen < SM9_ENC_OVERHEAD_BYTES) { + return CRYPT_SM9_ERR_DECRYPT_FAILED; + } + + uint32_t plaintextLen = dataLen - SM9_ENC_OVERHEAD_BYTES; + if (*outLen < plaintextLen) { + return CRYPT_SM9_BUFF_LEN_NOT_ENOUGH; + } + uint32_t plainLen = *outLen; int32_t ret = SM9_DecryptCtx(ctx, data, dataLen, out, &plainLen); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return CRYPT_SM9_ERR_DECRYPT_FAILED; } @@ -577,147 +598,6 @@ int32_t CRYPT_SM9_Decrypt(const CRYPT_SM9_Ctx *ctx, return CRYPT_SUCCESS; } -int32_t CRYPT_SM9_ComputeShareKey(const CRYPT_SM9_Ctx *selfCtx, const CRYPT_SM9_Ctx *peerCtx, - uint8_t *out, uint32_t *outLen) -{ - if (selfCtx == NULL || peerCtx == NULL || out == NULL || outLen == NULL) { - return CRYPT_NULL_INPUT; - } - - if (*outLen == 0) { - return CRYPT_SM9_ERR_BAD_INPUT; - } - - /* Check if both contexts have required keys for key exchange (encryption keys) */ - if (!selfCtx->has_enc_usr || !selfCtx->has_enc_sys) { - return CRYPT_SM9_ERR_NO_USER_KEY; - } - - if (!peerCtx->has_enc_sys) { - return CRYPT_SM9_ERR_NO_MASTER_KEY; - } - - /* Check if both contexts have user IDs */ - if (selfCtx->user_id_len == 0 || peerCtx->user_id_len == 0) { - return CRYPT_SM9_ERR_NO_USER_ID; - } - - /* Determine initiator/responder roles by comparing user IDs (lexicographic order) */ - int32_t cmp = memcmp(selfCtx->user_id, peerCtx->user_id, - selfCtx->user_id_len < peerCtx->user_id_len ? selfCtx->user_id_len : peerCtx->user_id_len); - if (cmp == 0 && selfCtx->user_id_len != peerCtx->user_id_len) { - cmp = (selfCtx->user_id_len < peerCtx->user_id_len) ? -1 : 1; - } - - int32_t is_initiator = (cmp < 0) ? 1 : 0; /* Self is initiator if self_id < peer_id */ - - /* Create temporary contexts for the key exchange process */ - SM9_Ctx *tmpSelfCtx = (SM9_Ctx *)CRYPT_SM9_DupCtx(selfCtx); - SM9_Ctx *tmpPeerCtx = (SM9_Ctx *)CRYPT_SM9_DupCtx(peerCtx); - if (tmpSelfCtx == NULL || tmpPeerCtx == NULL) { - SM9_FreeCtx(tmpSelfCtx); - SM9_FreeCtx(tmpPeerCtx); - return CRYPT_MEM_ALLOC_FAIL; - } - - int32_t ret; - uint8_t RA[SM9_KEYEX_RA_BYTES]; - uint8_t RB[SM9_KEYEX_RB_BYTES]; - uint8_t SA[SM9_KEYEX_RA_BYTES]; - uint8_t SB[SM9_KEYEX_RB_BYTES]; - - /* Generate deterministic random seeds based on user IDs to ensure consistent key exchange */ - uint8_t seed_buffer[512 + 1]; /* Buffer to hold both user IDs */ - uint32_t seed_len = 0; - uint8_t hash[32]; - uint8_t rand_A[SM9_CURVE_MODULE_BYTES]; - uint8_t rand_B[SM9_CURVE_MODULE_BYTES]; - - /* Create seed for initiator: H(initiator_id || responder_id || "A") */ - if (is_initiator) { - memcpy(seed_buffer + seed_len, selfCtx->user_id, selfCtx->user_id_len); - seed_len += selfCtx->user_id_len; - memcpy(seed_buffer + seed_len, peerCtx->user_id, peerCtx->user_id_len); - seed_len += peerCtx->user_id_len; - } else { - memcpy(seed_buffer + seed_len, peerCtx->user_id, peerCtx->user_id_len); - seed_len += peerCtx->user_id_len; - memcpy(seed_buffer + seed_len, selfCtx->user_id, selfCtx->user_id_len); - seed_len += selfCtx->user_id_len; - } - seed_buffer[seed_len++] = 'A'; - SM9_Hash_Data(seed_buffer, seed_len, hash); - memcpy(rand_A, hash, SM9_CURVE_MODULE_BYTES); - - /* Create seed for responder: H(initiator_id || responder_id || "B") */ - seed_buffer[seed_len - 1] = 'B'; /* Replace 'A' with 'B' */ - SM9_Hash_Data(seed_buffer, seed_len, hash); - memcpy(rand_B, hash, SM9_CURVE_MODULE_BYTES); - - /* Step 1: Initiator generates R_initiator with deterministic rand */ - ret = SM9_KeyExchangeInit(tmpSelfCtx, tmpPeerCtx->user_id, tmpPeerCtx->user_id_len, - is_initiator, is_initiator ? rand_A : rand_B, is_initiator ? RA : RB); - if (ret != SM9_OK) { - SM9_FreeCtx(tmpSelfCtx); - SM9_FreeCtx(tmpPeerCtx); - return CRYPT_SM9_ERR_KEY_EXCHANGE_FAILED; - } - - /* Step 2: Responder generates R_responder with deterministic rand */ - ret = SM9_KeyExchangeInit(tmpPeerCtx, tmpSelfCtx->user_id, tmpSelfCtx->user_id_len, - !is_initiator, is_initiator ? rand_B : rand_A, is_initiator ? RB : RA); - if (ret != SM9_OK) { - SM9_FreeCtx(tmpSelfCtx); - SM9_FreeCtx(tmpPeerCtx); - return CRYPT_SM9_ERR_KEY_EXCHANGE_FAILED; - } - - /* Step 3: Self computes shared key and S_self */ - ret = SM9_KeyExchangeConfirm(tmpSelfCtx, tmpPeerCtx->user_id, tmpPeerCtx->user_id_len, - is_initiator, is_initiator ? RB : RA, *outLen, out, - is_initiator ? SA : SB); - if (ret != SM9_OK) { - SM9_FreeCtx(tmpSelfCtx); - SM9_FreeCtx(tmpPeerCtx); - return CRYPT_SM9_ERR_KEY_EXCHANGE_FAILED; - } - - /* Step 4: Peer computes shared key and S_peer (for verification) */ - uint8_t tmpKey[256]; - uint32_t tmpKeyLen = sizeof(tmpKey); - ret = SM9_KeyExchangeConfirm(tmpPeerCtx, tmpSelfCtx->user_id, tmpSelfCtx->user_id_len, - !is_initiator, is_initiator ? RA : RB, tmpKeyLen, tmpKey, - is_initiator ? SB : SA); - if (ret != SM9_OK) { - SM9_FreeCtx(tmpSelfCtx); - SM9_FreeCtx(tmpPeerCtx); - return CRYPT_SM9_ERR_KEY_EXCHANGE_FAILED; - } - - /* Step 5: Peer verifies S_self */ - ret = SM9_KeyExchangeVerify(tmpPeerCtx, tmpSelfCtx->user_id, tmpSelfCtx->user_id_len, - !is_initiator, is_initiator ? RA : RB, is_initiator ? SA : SB); - if (ret != SM9_OK) { - SM9_FreeCtx(tmpSelfCtx); - SM9_FreeCtx(tmpPeerCtx); - return CRYPT_SM9_ERR_KEY_EXCHANGE_FAILED; - } - - /* Step 6: Self verifies S_peer */ - ret = SM9_KeyExchangeVerify(tmpSelfCtx, tmpPeerCtx->user_id, tmpPeerCtx->user_id_len, - is_initiator, is_initiator ? RB : RA, is_initiator ? SB : SA); - if (ret != SM9_OK) { - SM9_FreeCtx(tmpSelfCtx); - SM9_FreeCtx(tmpPeerCtx); - return CRYPT_SM9_ERR_KEY_EXCHANGE_FAILED; - } - - SM9_FreeCtx(tmpSelfCtx); - SM9_FreeCtx(tmpPeerCtx); - - return CRYPT_SUCCESS; -} - int32_t CRYPT_SM9_Ctrl(CRYPT_SM9_Ctx *ctx, int32_t cmd, void *val, uint32_t valLen) { if (ctx == NULL) { @@ -725,14 +605,13 @@ int32_t CRYPT_SM9_Ctrl(CRYPT_SM9_Ctx *ctx, int32_t cmd, void *val, uint32_t valL } switch (cmd) { - case CRYPT_CTRL_SET_SM2_USER_ID: /* Reuse SM2's user ID control for SM9 */ + case CRYPT_CTRL_SET_SM9_USER_ID: if (val == NULL || valLen == 0 || valLen > sizeof(ctx->user_id)) { return CRYPT_SM9_ERR_BAD_INPUT; } memcpy(ctx->user_id, val, valLen); ctx->user_id_len = valLen; return CRYPT_SUCCESS; - default: return CRYPT_SM9_ERR_NOT_SUPPORT; } diff --git a/crypto/sm9/src/sm9_exch.c b/crypto/sm9/src/sm9_exch.c deleted file mode 100644 index 1ddb1e17..00000000 --- a/crypto/sm9/src/sm9_exch.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of the openHiTLS project. - * - * openHiTLS is licensed under the Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * - * http://license.coscl.org.cn/MulanPSL2 - * - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ - -#include "hitls_build.h" -#ifdef HITLS_CRYPTO_SM9 - -#include "crypt_sm9.h" -#include "crypt_errno.h" -#include "sm9.h" -#include "sm9_curve.h" -#include "sm9_pairing.h" -#include "sm9_fp.h" -#include - -int32_t SM9_KeyExchangeInit(SM9_Ctx *ctx, uint8_t *peer_id, uint32_t peer_id_len, - int32_t is_initiator, uint8_t *rand, uint8_t *R) -{ - if (!ctx || !peer_id || !R) { - return SM9_ERR_BAD_INPUT; - } - - if (!ctx->has_enc_usr || !ctx->has_enc_sys) { - return SM9_ERR_BAD_INPUT; - } - - int32_t ret; - if (rand) { - memcpy(ctx->keyex_r, rand, SM9_CURVE_MODULE_BYTES); - } else { - ret = sm9_rand(ctx->keyex_r, SM9_CURVE_MODULE_BYTES); - if (ret != CRYPT_SUCCESS) { - return SM9_ERR_RND_UNUSEABLE; - } - } - if (is_initiator) { - ret = SM9_Alg_KeyEx_InitA( - ctx->user_id, ctx->user_id_len, - peer_id, peer_id_len, - ctx->keyex_r, ctx->enc_dek, - ctx->enc_mpk, ctx->keyex_R); - } else { - ret = SM9_Alg_KeyEx_InitB( - peer_id, peer_id_len, - ctx->user_id, ctx->user_id_len, - ctx->keyex_r, ctx->enc_dek, - ctx->enc_mpk, ctx->keyex_R); - } - - if (ret == SM9_OK) { - memcpy(R, ctx->keyex_R, SM9_KEYEX_RA_BYTES); - } - - return ret; -} - -int32_t SM9_KeyExchangeConfirm(SM9_Ctx *ctx, uint8_t *peer_id, uint32_t peer_id_len, - int32_t is_initiator, uint8_t *peer_R, uint32_t klen, - uint8_t *shared_key, uint8_t *confirm_value) -{ - if (!ctx || !peer_id || !peer_R || !shared_key || !confirm_value) { - return SM9_ERR_BAD_INPUT; - } - - if (!ctx->has_enc_usr || !ctx->has_enc_sys) { - return SM9_ERR_BAD_INPUT; - } - - if (is_initiator) { - return SM9_Alg_KeyEx_ConfirmA( - ctx->user_id, ctx->user_id_len, - peer_id, peer_id_len, - ctx->keyex_r, ctx->keyex_R, peer_R, - ctx->enc_dek, ctx->enc_mpk, - klen, shared_key, confirm_value); - } else { - return SM9_Alg_KeyEx_ConfirmB( - peer_id, peer_id_len, - ctx->user_id, ctx->user_id_len, - ctx->keyex_r, peer_R, ctx->keyex_R, - ctx->enc_dek, ctx->enc_mpk, - klen, shared_key, confirm_value); - } -} - -int32_t SM9_KeyExchangeVerify(SM9_Ctx *ctx, uint8_t *peer_id, uint32_t peer_id_len, - int32_t is_initiator, uint8_t *peer_R, uint8_t *peer_confirm) -{ - if (!ctx || !peer_id || !peer_R || !peer_confirm) { - return SM9_ERR_BAD_INPUT; - } - - if (!ctx->has_enc_usr || !ctx->has_enc_sys) { - return SM9_ERR_BAD_INPUT; - } - - if (is_initiator) { - return SM9_Alg_KeyEx_VerifySB( - ctx->user_id, ctx->user_id_len, - peer_id, peer_id_len, - ctx->keyex_r, ctx->keyex_R, peer_R, - ctx->enc_dek, ctx->enc_mpk, - peer_confirm); - } else { - return SM9_Alg_KeyEx_VerifySA( - peer_id, peer_id_len, - ctx->user_id, ctx->user_id_len, - ctx->keyex_r, peer_R, ctx->keyex_R, - ctx->enc_dek, ctx->enc_mpk, - peer_confirm); - } -} - -#endif // HITLS_CRYPTO_SM9 diff --git a/crypto/sm9/src/sm9_sign.c b/crypto/sm9/src/sm9_sign.c index 081f0e59..295db3e6 100644 --- a/crypto/sm9/src/sm9_sign.c +++ b/crypto/sm9/src/sm9_sign.c @@ -43,54 +43,54 @@ void SM9_FreeCtx(SM9_Ctx *ctx) int32_t SM9_SetSignMasterKey(SM9_Ctx *ctx, uint8_t *msk) { if (!ctx || !msk) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } memcpy(ctx->sig_msk, msk, SM9_SIG_SYS_PRIKEY_BYTES); int32_t ret = SM9_Alg_MSKG(ctx->sig_msk, ctx->sig_mpk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return ret; } ret = SM9_Get_Sig_G(ctx->sig_g, ctx->sig_mpk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return ret; } ctx->has_sig_sys = 1; ctx->has_sig_g = 1; - return SM9_OK; + return CRYPT_SUCCESS; } int32_t SM9_GenSignUserKey(SM9_Ctx *ctx, const uint8_t *user_id, uint32_t id_len) { if (!ctx || !user_id || id_len == 0 || id_len > 256) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } if (!ctx->has_sig_sys) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } memcpy(ctx->user_id, user_id, id_len); ctx->user_id_len = id_len; int32_t ret = SM9_Alg_USKG(user_id, id_len, ctx->sig_msk, ctx->sig_dsk); - if (ret != SM9_OK) { + if (ret != CRYPT_SUCCESS) { return ret; } ctx->has_sig_usr = 1; - return SM9_OK; + return CRYPT_SUCCESS; } int32_t SM9_SetSignUserKey(SM9_Ctx *ctx, uint8_t *user_id, uint32_t id_len, uint8_t *dsk) { if (!ctx || !user_id || id_len == 0 || id_len > 256 || !dsk) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } memcpy(ctx->user_id, user_id, id_len); @@ -100,29 +100,29 @@ int32_t SM9_SetSignUserKey(SM9_Ctx *ctx, uint8_t *user_id, uint32_t id_len, uint ctx->has_sig_usr = 1; - return SM9_OK; + return CRYPT_SUCCESS; } /*============================================================================*/ int32_t SM9_SignCtx(const SM9_Ctx *ctx, const uint8_t *msg, uint32_t mlen, uint8_t *rand, uint8_t *sign) { - static uint8_t default_rand[32]; + uint8_t randBuf[32]; if (!ctx || !msg || !sign) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } if (!ctx->has_sig_usr) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } if (!rand) { - int32_t ret = sm9_rand(default_rand, sizeof(default_rand)); + int32_t ret = sm9_rand(randBuf, sizeof(randBuf)); if (ret != CRYPT_SUCCESS) { - return SM9_ERR_RND_UNUSEABLE; + return CRYPT_SM9_ERR_SIGN_FAILED; } - rand = default_rand; + rand = randBuf; } const uint8_t *g_ptr = ctx->has_sig_g ? ctx->sig_g : NULL; @@ -135,11 +135,11 @@ int32_t SM9_VerifyCtx(const SM9_Ctx *ctx, const uint8_t *user_id, uint32_t id_le const uint8_t *msg, uint32_t mlen, const uint8_t *sign) { if (!ctx || !user_id || !msg || !sign) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } if (!ctx->has_sig_sys) { - return SM9_ERR_BAD_INPUT; + return CRYPT_SM9_ERR_BAD_INPUT; } const uint8_t *g_ptr = ctx->has_sig_g ? ctx->sig_g : NULL; diff --git a/include/bsl/bsl_params.h b/include/bsl/bsl_params.h index 6952cd6a..75f75c8e 100644 --- a/include/bsl/bsl_params.h +++ b/include/bsl/bsl_params.h @@ -52,8 +52,8 @@ typedef struct BslParam { int32_t key; uint32_t valueType; void *value; - uint32_t valueLen; - uint32_t useLen; + uint32_t valueLen; // Length of the para value + uint32_t useLen; // Allow users to write back the length used. } BSL_Param; typedef struct BslParamMaker BSL_ParamMaker; diff --git a/include/crypto/crypt_eal_pkey.h b/include/crypto/crypt_eal_pkey.h index 26c413b9..6bf87957 100644 --- a/include/crypto/crypt_eal_pkey.h +++ b/include/crypto/crypt_eal_pkey.h @@ -598,7 +598,7 @@ int32_t CRYPT_EAL_PkeyBlind(CRYPT_EAL_PkeyCtx *pkey, CRYPT_MD_AlgId id, const ui /** * @ingroup crypt_eal_pkey - * @brief Perform unblind operation on blinded data. + * @brief Perform unblind operation on blinded data. A ctx holds only one blinding factor. * * @param pkey [IN] Key session * @param input [IN] Blinded data to be unblinded diff --git a/include/crypto/crypt_errno.h b/include/crypto/crypt_errno.h index ae1f7d97..ab924530 100644 --- a/include/crypto/crypt_errno.h +++ b/include/crypto/crypt_errno.h @@ -409,7 +409,7 @@ enum CRYPT_ERROR { CRYPT_SM4_ERR_KEY_LEN, /**< Wrong key length is set. */ CRYPT_SM4_UNSAFE_KEY, /**< DataKey is the same as tweakKey. */ - CRYPT_SM9_BUFF_LEN_NOT_ENOUGH = 0x01210000, /**< SM9 buffer length not enough. */ + CRYPT_SM9_BUFF_LEN_NOT_ENOUGH = 0x011C0001, /**< SM9 buffer length not enough. */ CRYPT_SM9_ERR_KEY_ERR, /**< SM9 key error. */ CRYPT_SM9_ERR_NOT_SUPPORT, /**< SM9 operation not supported. */ CRYPT_SM9_ERR_SIGN_FAILED, /**< SM9 signature failed. */ @@ -422,7 +422,6 @@ enum CRYPT_ERROR { CRYPT_SM9_ERR_BAD_INPUT, /**< SM9 bad input parameter. */ CRYPT_SM9_ERR_NO_USER_KEY, /**< SM9 user key not set. */ CRYPT_SM9_ERR_NO_MASTER_KEY, /**< SM9 master key not set. */ - CRYPT_SM9_ERR_KEY_EXCHANGE_FAILED, /**< SM9 key exchange failed. */ CRYPT_SM9_PAIRWISE_CHECK_FAIL, /**< The public and private keys are inconsistent. */ CRYPT_SM9_INVALID_PRVKEY, /**< Invalid private key. */ diff --git a/include/crypto/crypt_types.h b/include/crypto/crypt_types.h index 33302081..996c25be 100644 --- a/include/crypto/crypt_types.h +++ b/include/crypto/crypt_types.h @@ -726,6 +726,9 @@ typedef enum { // xmss CRYPT_CTRL_GET_XMSS_XDR_ALG_TYPE = 800, /**< Get the XMSS xdr algId. */ CRYPT_CTRL_SET_XMSS_XDR_ALG_TYPE = 801, /**< Set the XMSS xdr algId. */ + + // sm9 + CRYPT_CTRL_SET_SM9_USER_ID = 900, /**< SM9 set the user ID. */ } CRYPT_PkeyCtrl; diff --git a/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.c b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.c index 9e454b90..3e563e7f 100644 --- a/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.c +++ b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.c @@ -995,3 +995,62 @@ EXIT: TestRandDeInit(); } /* END_CASE */ + +/** + * @test SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001 + * @title ECC_PointMul and ECC_PointMulAdd with k=0 should not crash. + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001(int paraId) +{ + if (IsCurveDisabled(paraId) && paraId != CRYPT_ECC_SM2) { + SKIP_TEST(); + } + TestMemInit(); + ASSERT_EQ(TestRandInit(), CRYPT_SUCCESS); + ECC_Para *para = ECC_NewPara(paraId); + ASSERT_TRUE(para != NULL); + + BN_BigNum *zero = BN_Create(0); + ASSERT_TRUE(zero != NULL); + BN_BigNum *one = BN_Create(0); + ASSERT_TRUE(one != NULL); + ASSERT_EQ(BN_SetLimb(one, 1), CRYPT_SUCCESS); + + ECC_Point *r = ECC_NewPoint(para); + ASSERT_TRUE(r != NULL); + ECC_Point *G = ECC_NewPoint(para); + ASSERT_TRUE(G != NULL); + + // Get generator point: 1*G + ASSERT_EQ(ECC_PointMul(para, G, one, NULL), CRYPT_SUCCESS); + + // ECC_PointMul with k=0 should return infinity + ASSERT_EQ(ECC_PointMul(para, r, zero, NULL), CRYPT_SUCCESS); + + // ECC_PointMul with k=0 and explicit point should return infinity + ASSERT_EQ(ECC_PointMul(para, r, zero, G), CRYPT_SUCCESS); + + // ECC_PointMulAdd: k1=0, k2=0 should return infinity + ASSERT_EQ(ECC_PointMulAdd(para, r, zero, zero, G), CRYPT_SUCCESS); + ASSERT_TRUE(BN_IsZero(&r->z)); + + // ECC_PointMulAdd: k1=0, k2!=0 should return k2*pt + ASSERT_EQ(ECC_PointMulAdd(para, r, zero, one, G), CRYPT_SUCCESS); + // Verify result equals G (since 0*G + 1*G = G) + ASSERT_EQ(ECC_PointCmp(para, r, G), CRYPT_SUCCESS); + + // ECC_PointMulAdd: k1!=0, k2=0 should return k1*G + ASSERT_EQ(ECC_PointMulAdd(para, r, one, zero, G), CRYPT_SUCCESS); + // Verify result equals G (since 1*G + 0*G = G) + ASSERT_EQ(ECC_PointCmp(para, r, G), CRYPT_SUCCESS); + +EXIT: + ECC_FreePara(para); + ECC_FreePoint(r); + ECC_FreePoint(G); + BN_Destroy(zero); + BN_Destroy(one); + TestRandDeInit(); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.data b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.data index 3052bd04..57ea8648 100644 --- a/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.data +++ b/testcode/sdv/testcase/crypto/ecc/test_suite_sdv_eal_ecdh.data @@ -615,3 +615,30 @@ SDV_CRYPTO_ECC_ADD_CAL_TEST_FUNC_TC001:CRYPT_ECC_BRAINPOOLP512R1:"fffffffe338637 SDV_CRYPTO_ECC_ADD_CAL_TEST_FUNC_TC001 SDV_CRYPTO_ECC_ADD_CAL_TEST_FUNC_TC001:CRYPT_ECC_SM2:"fffffffe338637100030353629323dbe":"79983a6b221fab08796ad40f712de3b6":"02" + +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001 +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001:CRYPT_ECC_NISTP192 + +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001 +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001:CRYPT_ECC_NISTP224 + +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001 +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001:CRYPT_ECC_NISTP256 + +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001 +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001:CRYPT_ECC_NISTP384 + +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001 +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001:CRYPT_ECC_NISTP521 + +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001 +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001:CRYPT_ECC_BRAINPOOLP256R1 + +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001 +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001:CRYPT_ECC_BRAINPOOLP384R1 + +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001 +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001:CRYPT_ECC_BRAINPOOLP512R1 + +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001 +SDV_CRYPTO_ECC_POINTMUL_ZERO_K_TC001:CRYPT_ECC_SM2 diff --git a/testcode/sdv/testcase/crypto/encode/test_suite_sdv_encode.data b/testcode/sdv/testcase/crypto/encode/test_suite_sdv_encode.data index bd47fcee..c061a8a8 100644 --- a/testcode/sdv/testcase/crypto/encode/test_suite_sdv_encode.data +++ b/testcode/sdv/testcase/crypto/encode/test_suite_sdv_encode.data @@ -33,7 +33,7 @@ SDV_DECODE_SIGN_BN_FUNC_TC001:Test abnormal decode - content length of sequence SDV_DECODE_SIGN_BN_FUNC_TC001:"3008020100020200f1":"":"":BSL_ASN1_ERR_DECODE_LEN SDV_DECODE_SIGN_BN_FUNC_TC001:Test abnormal decode - Exceed the length of sequence -SDV_DECODE_SIGN_BN_FUNC_TC001:"300602010002010001":"00":"00":CRYPT_SUCCESS +SDV_DECODE_SIGN_BN_FUNC_TC001:"300602010002010001":"00":"00":CRYPT_DECODE_ASN1_BUFF_FAILED SDV_DECODE_SIGN_BN_FUNC_TC001:Test abnormal decode - missing required field SDV_DECODE_SIGN_BN_FUNC_TC001:"3003020101":"":"":BSL_ASN1_ERR_DECODE_LEN @@ -68,8 +68,8 @@ SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:"307C022004EBFC718E8D1798620432268E77FEB6 SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:Test abnormal decode - null input SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:"":"":"":"":"":CRYPT_NULL_INPUT -SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:Test abnormal decode - incomplete data structure -SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:"303502100123456789ABCDEF0123456789ABCDEF021100FEDCBA9876543210FEDCBA9876543210040800112233445566770404AABBCCDDEE":"0123456789ABCDEF0123456789ABCDEF":"00FEDCBA9876543210FEDCBA9876543210":"0011223344556677":"AABBCCDD":CRYPT_SUCCESS +SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:Test abnormal decode - trailing data after sequence +SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:"303502100123456789ABCDEF0123456789ABCDEF021100FEDCBA9876543210FEDCBA9876543210040800112233445566770404AABBCCDDEE":"0123456789ABCDEF0123456789ABCDEF":"00FEDCBA9876543210FEDCBA9876543210":"0011223344556677":"AABBCCDD":CRYPT_DECODE_ASN1_BUFF_FAILED SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:Test abnormal decode - invalid integer SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:"3081880220002ed1067746155de13c45d767d1221f631d997d8238ccc0eb015f013888137f022079c665009c337f2aa548a134b96ae65ea254e4ae1714be07b68a425127b10f8404205ea82a72c0ce48f7d05aa6946cce9a7910e38ff2da80b3d242cb57eb295412b304209d64e6729e7d5e83919577db14c0cfee5cadd2c7dd11f49b88edca4b44373b36":"":"":"":"":BSL_ASN1_ERR_DECODE_INT @@ -89,6 +89,9 @@ SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:"302D02100123456789ABCDEF0123456789ABCDEF SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:Test abnormal decode - cipher.len is zero SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:"303102100123456789ABCDEF0123456789ABCDEF021100FEDCBA9876543210FEDCBA9876543210040800112233445566770400":"":"":"":"":CRYPT_DECODE_ASN1_BUFF_LEN_ZERO +SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:Test abnormal decode - valid ciphertext with trailing byte +SDV_DECODE_SM2_ENCRYPT_DATA_FUNC_TC001:"303502100123456789ABCDEF0123456789ABCDEF021100FEDCBA9876543210FEDCBA9876543210040800112233445566770404AABBCCDDFF":"":"":"":"":CRYPT_DECODE_ASN1_BUFF_FAILED + SDV_DECODE_SM2_ENCRYPT_DATA_API_TC001:Test abnormal input parameter SDV_DECODE_SM2_ENCRYPT_DATA_API_TC001:"303502100123456789ABCDEF0123456789ABCDEF021100FEDCBA9876543210FEDCBA9876543210040800112233445566770404AABBCCDD" diff --git a/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_sign_verify.c b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_sign_verify.c index 2337a040..f8808e2b 100644 --- a/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_sign_verify.c +++ b/testcode/sdv/testcase/crypto/rsa/test_suite_sdv_eal_rsa_sign_verify.c @@ -1729,6 +1729,8 @@ void SDV_CRYPTO_RSA_SIGN_VERIFY_ISO9796_2_DETER_TC001(int isProvider, int bits, ASSERT_EQ(signLen1, signLen2); ASSERT_EQ(memcmp(sign1, sign2, signLen1), 0); + mdId = CRYPT_MD_SHAKE128; + ASSERT_EQ(CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_SET_RSA_EMSA_ISO9796_2, isoParam, 0), CRYPT_EAL_ERR_ALGID); EXIT: #ifdef HITLS_CRYPTO_DRBG TestRandDeInit(); diff --git a/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_sign.c b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_sign.c index a26ee916..6ccebea5 100644 --- a/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_sign.c +++ b/testcode/sdv/testcase/crypto/sm2/test_suite_sdv_eal_sm2_sign.c @@ -529,32 +529,11 @@ EXIT: /** * @test SDV_CRYPTO_SM2_VERIFY_API_TC001 - * @title SM2: CRYPT_EAL_PkeyVerify test. + * @title SM2 verify: parameter validation and basic verify flow * @precon Vectors: public key, userId, msg, signature. * @brief - * 1. Create the context of the SM2 algorithm, expected result 1. - * 2. Call the CRYPT_EAL_PkeyCtrl method to set userId, expected result 2. - * 3. Call the CRYPT_EAL_PkeyVerify method, where all parameters are valid, expected result 3. - * 4. Free the context and create a new context of the SM2 algorithm, expected result 4. - * 5. Set public key, expected result 5. - * 6. Set userId, expected result 6. - * 7. Call the CRYPT_EAL_PkeyVerify method: - * (1) signLen is invalid: sign->len - 1 or sign->len + 1, expected result 7 - * (3) msg = NULL, msgLen != 0, expected result 8 - * (2) sign = NULL, signLen != 0, expected result 9 - * (4) all parameters are valid, expected result 10 - * (5) mdId != CRYPT_MD_SM3, expected result 11 - * @expect - * 1. Success, and context is not NULL. - * 2. CRYPT_SUCCESS - * 3. CRYPT_SM2_NO_PUBKEY - * 4. Success, and context is not NULL. - * 5. CRYPT_SUCCESS - * 6. CRYPT_SUCCESS - * 7. CRYPT_DSA_DECODE_FAIL - * 8-9. CRYPT_NULL_INPUT - * 10. CRYPT_SUCCESS - * 11. CRYPT_EAL_ERR_ALGID + * Test CRYPT_EAL_PkeyVerify with various invalid and valid parameter combinations, + * including missing public key, invalid sign length, NULL pointers, and wrong mdId. */ /* BEGIN_CASE */ void SDV_CRYPTO_SM2_VERIFY_API_TC001(Hex *pubKey, Hex *userId, Hex *msg, Hex *sign, int isProvider) @@ -583,7 +562,7 @@ void SDV_CRYPTO_SM2_VERIFY_API_TC001(Hex *pubKey, Hex *userId, Hex *msg, Hex *si ASSERT_EQ(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, sign->x, sign->len - 1), BSL_ASN1_ERR_DECODE_LEN); ASSERT_EQ(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, bigSign, SM2_SIGN_MAX_LEN + 1), - CRYPT_SUCCESS); + CRYPT_DECODE_ASN1_BUFF_FAILED); ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, NULL, msg->len, sign->x, sign->len) == CRYPT_NULL_INPUT); ASSERT_TRUE(CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg->x, msg->len, NULL, sign->len) == CRYPT_NULL_INPUT); diff --git a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9.base.c b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9.base.c index db49cbf4..3c907c12 100644 --- a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9.base.c +++ b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9.base.c @@ -19,6 +19,22 @@ #include "securec.h" #include "crypt_sm9.h" #include "crypt_util_rand.h" +#include "stub_utils.h" + +STUB_DEFINE_RET3(int32_t, CRYPT_RandEx, void *, uint8_t *, uint32_t); + +static uint8_t *g_sm9StubRand = NULL; +static uint32_t g_sm9StubRandLen = 0; + +int32_t STUB_CRYPT_RandEx(void *libCtx, uint8_t *rand, uint32_t randLen) +{ + (void)libCtx; + if (g_sm9StubRand == NULL || randLen > g_sm9StubRandLen) { + return -1; + } + memcpy(rand, g_sm9StubRand, randLen); + return 0; +} #define RAND_BUF_LEN 2048 #define UINT8_MAX_NUM 255 diff --git a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_crypt.c b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_crypt.c index e4748fa5..b8ff79fa 100644 --- a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_crypt.c +++ b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_crypt.c @@ -73,9 +73,9 @@ void SDV_CRYPTO_SM9_CRYPT_API_TC001(Hex *masterKey, Hex *userId, Hex *plaintext) nativeCtx = SM9_NewCtx(); ASSERT_TRUE(nativeCtx != NULL); ret = SM9_SetEncMasterKey(nativeCtx, masterKey->x); - ASSERT_EQ(ret, SM9_OK); + ASSERT_EQ(ret, CRYPT_SUCCESS); ret = SM9_GenEncUserKey(nativeCtx, userId->x, userId->len); - ASSERT_EQ(ret, SM9_OK); + ASSERT_EQ(ret, CRYPT_SUCCESS); memcpy_s(userKey, sizeof(userKey), nativeCtx->enc_dek, SM9_ENC_USR_PRIKEY_BYTES); memcpy_s(masterPubKey, sizeof(masterPubKey), nativeCtx->enc_mpk, SM9_ENC_SYS_PUBKEY_BYTES); @@ -143,6 +143,62 @@ EXIT: } /* END_CASE */ +/** + * @test SDV_CRYPTO_SM9_CRYPT_K1_ZERO_TC001 + * @title SM9 Encrypt: Verify K1 all-zero check at algorithm layer. + * @precon Prepare valid master key and user ID. + * @brief + * 1. Set up encryption master key and generate user key + * 2. Call SM9_Alg_Enc with a known-good random, expected result 2 + * 3. Decrypt the ciphertext, expected result 3 + * 4. Verify decrypted plaintext matches original, expected result 4 + * @expect + * 2. CRYPT_SUCCESS (K1 is not all zeros with valid random) + * 3. CRYPT_SUCCESS + * 4. Match + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM9_CRYPT_K1_ZERO_TC001(Hex *masterKey, Hex *userId, Hex *plaintext, Hex *randHex) +{ + SM9_Ctx *ctx = NULL; + uint8_t ciphertext[SM9_CIPHERTEXT_MAX_LEN] = {0}; + uint32_t cipherLen = sizeof(ciphertext); + uint8_t decrypted[SM9_PLAINTEXT_MAX_LEN] = {0}; + uint32_t decryptLen = sizeof(decrypted); + int ret; + + ctx = SM9_NewCtx(); + ASSERT_TRUE(ctx != NULL); + ret = SM9_SetEncMasterKey(ctx, masterKey->x); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ret = SM9_GenEncUserKey(ctx, userId->x, userId->len); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + // Encrypt with specified random - should succeed (K1 won't be all zeros) + ret = SM9_Alg_Enc(plaintext->x, plaintext->len, userId->x, userId->len, + randHex->x, ctx->enc_g, ctx->enc_mpk, ciphertext, &cipherLen); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + // Decrypt and verify + ret = SM9_Alg_Dec(ciphertext, cipherLen, ctx->enc_dek, userId->x, userId->len, + decrypted, &decryptLen); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ASSERT_EQ(decryptLen, plaintext->len); + ASSERT_EQ(memcmp(decrypted, plaintext->x, plaintext->len), 0); + // Tamper with C2 (located after C1 + C3) + uint32_t c2Offset = 2 * 32 + 32; // SM9_C1_ByteLen + SM9_C3_ByteLen + ciphertext[c2Offset] ^= 0xFF; + + // Decrypt should fail (MAC mismatch or K1 zero check) + ret = SM9_Alg_Dec(ciphertext, cipherLen, ctx->enc_dek, userId->x, userId->len, + decrypted, &decryptLen); + ASSERT_EQ(ret, CRYPT_SM9_ERR_DECRYPT_FAILED); + +EXIT: + SM9_FreeCtx(ctx); +} +/* END_CASE */ + /** * @test SDV_CRYPTO_SM9_CRYPT_API_TC002 * @title SM9 EAL Encrypt: Test with NULL parameters using EAL interfaces. @@ -190,9 +246,9 @@ void SDV_CRYPTO_SM9_CRYPT_API_TC002(Hex *masterKey, Hex *userId, Hex *plaintext) nativeCtx = SM9_NewCtx(); ASSERT_TRUE(nativeCtx != NULL); ret = SM9_SetEncMasterKey(nativeCtx, masterKey->x); - ASSERT_EQ(ret, SM9_OK); + ASSERT_EQ(ret, CRYPT_SUCCESS); ret = SM9_GenEncUserKey(nativeCtx, userId->x, userId->len); - ASSERT_EQ(ret, SM9_OK); + ASSERT_EQ(ret, CRYPT_SUCCESS); memcpy_s(userKey, sizeof(userKey), nativeCtx->enc_dek, SM9_ENC_USR_PRIKEY_BYTES); memcpy_s(masterPubKey, sizeof(masterPubKey), nativeCtx->enc_mpk, SM9_ENC_SYS_PUBKEY_BYTES); @@ -270,16 +326,16 @@ void SDV_CRYPTO_SM9_CRYPT_API_TC003(Hex *masterKey, Hex *userIdA, Hex *userIdB, nativeCtx = SM9_NewCtx(); ASSERT_TRUE(nativeCtx != NULL); ret = SM9_SetEncMasterKey(nativeCtx, masterKey->x); - ASSERT_EQ(ret, SM9_OK); + ASSERT_EQ(ret, CRYPT_SUCCESS); // Generate User A's key ret = SM9_GenEncUserKey(nativeCtx, userIdA->x, userIdA->len); - ASSERT_EQ(ret, SM9_OK); + ASSERT_EQ(ret, CRYPT_SUCCESS); memcpy_s(userKeyA, sizeof(userKeyA), nativeCtx->enc_dek, SM9_ENC_USR_PRIKEY_BYTES); // Generate User B's key ret = SM9_GenEncUserKey(nativeCtx, userIdB->x, userIdB->len); - ASSERT_EQ(ret, SM9_OK); + ASSERT_EQ(ret, CRYPT_SUCCESS); memcpy_s(userKeyB, sizeof(userKeyB), nativeCtx->enc_dek, SM9_ENC_USR_PRIKEY_BYTES); // Save master public key @@ -403,3 +459,114 @@ EXIT: SM9_FreeCtx(nativeCtx); } /* END_CASE */ + +/** + * @test SDV_CRYPTO_SM9_CRYPT_VECTOR_TC001 + * @title SM9 Encrypt/Decrypt: Verify decryption of known ciphertext from standard vector. + * @precon Prepare master key, user ID, message, fixed random, and expected ciphertext. + * @brief + * Source: GB/T 38635.2-2020 Appendix B (SM9 public key encryption algorithm example) + * 1. Generate user decryption key using native KGC API + * 2. Create EAL context and set public/private keys + * 3. Encrypt message via EAL and verify round-trip decryption + * 4. Decrypt the standard expected ciphertext via EAL and verify plaintext matches + * @expect + * 1-2. Setup succeeds + * 3. Round-trip encrypt/decrypt produces original message + * 4. Decryption of standard ciphertext produces expected plaintext + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM9_CRYPT_VECTOR_TC001(Hex *masterKey, Hex *userId, Hex *message, + Hex *randHex, Hex *expectedCipher) +{ + CRYPT_EAL_PkeyCtx *encCtx = NULL; + CRYPT_EAL_PkeyCtx *decCtx = NULL; + SM9_Ctx *nativeCtx = NULL; + uint8_t ciphertext[SM9_CIPHERTEXT_MAX_LEN] = {0}; + uint32_t cipherLen = sizeof(ciphertext); + uint8_t decrypted[SM9_PLAINTEXT_MAX_LEN] = {0}; + uint32_t decryptLen = sizeof(decrypted); + uint8_t userKey[SM9_ENC_USR_PRIKEY_BYTES] = {0}; + int ret; + BSL_Param params[4]; + int32_t keyType = SM9_KEY_TYPE_ENC; + + // Step 1: Generate user key using native KGC API + nativeCtx = SM9_NewCtx(); + ASSERT_TRUE(nativeCtx != NULL); + ret = SM9_SetEncMasterKey(nativeCtx, masterKey->x); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ret = SM9_GenEncUserKey(nativeCtx, userId->x, userId->len); + ASSERT_EQ(ret, CRYPT_SUCCESS); + memcpy(userKey, nativeCtx->enc_dek, SM9_ENC_USR_PRIKEY_BYTES); + + // Step 2: Create EAL encrypt context + encCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9); + ASSERT_TRUE(encCtx != NULL); + + BSL_PARAM_InitValue(¶ms[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS, + masterKey->x, masterKey->len); + BSL_PARAM_InitValue(¶ms[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS, + userId->x, userId->len); + BSL_PARAM_InitValue(¶ms[2], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, + &keyType, sizeof(int32_t)); + params[3] = (BSL_Param)BSL_PARAM_END; + + ret = CRYPT_EAL_PkeySetPubEx(encCtx, params); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + // Step 3: Encrypt with stubbed random and verify ciphertext matches standard vector + g_sm9StubRand = randHex->x; + g_sm9StubRandLen = randHex->len; + STUB_REPLACE(CRYPT_RandEx, STUB_CRYPT_RandEx); + + ret = CRYPT_EAL_PkeyEncrypt(encCtx, message->x, message->len, + ciphertext, &cipherLen); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ASSERT_EQ(cipherLen, expectedCipher->len); + ASSERT_EQ(memcmp(ciphertext, expectedCipher->x, cipherLen), 0); + + STUB_RESTORE(CRYPT_RandEx); + g_sm9StubRand = NULL; + g_sm9StubRandLen = 0; + + // Step 4: Create EAL decrypt context and verify decryption + decCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9); + ASSERT_TRUE(decCtx != NULL); + + BSL_PARAM_InitValue(¶ms[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS, + masterKey->x, masterKey->len); + BSL_PARAM_InitValue(¶ms[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, + &keyType, sizeof(int32_t)); + params[2] = (BSL_Param)BSL_PARAM_END; + + ret = CRYPT_EAL_PkeySetPubEx(decCtx, params); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + BSL_Param decParams[4]; + BSL_PARAM_InitValue(&decParams[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS, + userKey, SM9_ENC_USR_PRIKEY_BYTES); + BSL_PARAM_InitValue(&decParams[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS, + userId->x, userId->len); + BSL_PARAM_InitValue(&decParams[2], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, + &keyType, sizeof(int32_t)); + decParams[3] = (BSL_Param)BSL_PARAM_END; + + ret = CRYPT_EAL_PkeySetPrvEx(decCtx, decParams); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + ret = CRYPT_EAL_PkeyDecrypt(decCtx, expectedCipher->x, expectedCipher->len, + decrypted, &decryptLen); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ASSERT_EQ(decryptLen, message->len); + ASSERT_EQ(memcmp(decrypted, message->x, message->len), 0); + +EXIT: + STUB_RESTORE(CRYPT_RandEx); + g_sm9StubRand = NULL; + g_sm9StubRandLen = 0; + CRYPT_EAL_PkeyFreeCtx(encCtx); + CRYPT_EAL_PkeyFreeCtx(decCtx); + SM9_FreeCtx(nativeCtx); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_crypt.data b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_crypt.data index c2bf7425..29b77835 100644 --- a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_crypt.data +++ b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_crypt.data @@ -8,3 +8,11 @@ SDV_CRYPTO_SM9_CRYPT_API_TC002:"FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210 SDV_CRYPTO_SM9_CRYPT_API_TC003:masterKey:userIdA:userIdB:plaintext SDV_CRYPTO_SM9_CRYPT_API_TC003:"FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210":"416C696365":"426F62":"436F6E666964656E7469616C2044617461" + +# Source: GB/T 38635.2-2020 Appendix B (SM9 public key encryption algorithm example) +SDV_CRYPTO_SM9_CRYPT_VECTOR_TC001:masterKey:userId:message:randHex:expectedCipher +SDV_CRYPTO_SM9_CRYPT_VECTOR_TC001:"0001EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22":"426F62":"4368696E65736520494245207374616E64617264":"0000AAC0541779C8FC45E3E2CB25C12B5D2576B2129AE8BB5EE2CBE5EC9E785B":"2445471164490618E1EE20528FF1D545B0F14C8BCAA44544F03DAB5DAC07D8FF42FFCA97D57CDDC05EA405F2E586FEB3A6930715532B8000759F13059ED59AC0BA672387BCD6DE5016A158A52BB2E7FC429197BCAB70B25AFEE37A2B9DB9F3671B5F5B0E951489682F3E64E1378CDD5DA9513B1C" + +# K1 all-zero check tests +SDV_CRYPTO_SM9_CRYPT_K1_ZERO_TC001:masterKey:userId:plaintext:randHex +SDV_CRYPTO_SM9_CRYPT_K1_ZERO_TC001:"0001EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22":"426F62":"4368696E65736520494245207374616E64617264":"00AAC0541779C8FC45E3E2CB25C12B5D2576B2129AE200292B63AEF94BE05BAA" diff --git a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_exchange.c b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_exchange.c deleted file mode 100644 index 2601942c..00000000 --- a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_exchange.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * This file is part of the openHiTLS project. - * - * openHiTLS is licensed under the Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * - * http://license.coscl.org.cn/MulanPSL2 - * - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ -/* INCLUDE_BASE test_suite_sdv_eal_sm9 */ - -/* BEGIN_HEADER */ - -#include "crypt_sm9.h" -#include "crypt_params_key.h" -#include "bsl_params.h" -#include "securec.h" - -#define SM9_KEYEX_RA_LEN 64 -#define SM9_KEYEX_RB_LEN 64 -#define SM9_SHARED_KEY_LEN 32 -#define SM9_CONFIRM_LEN 32 -#define SM9_KEY_TYPE_SIGN 1 -#define SM9_KEY_TYPE_ENC 2 - -/* END_HEADER */ - -/** - * @test SDV_CRYPTO_SM9_KEYEX_API_TC001 - * @title SM9 Key Exchange: Test via EAL ComputeShareKey interface. - * @precon Prepare valid master key and user IDs. - * @brief - * 1. Create EAL contexts for Alice and Bob, expected result 1 - * 2. Set encrypt master keys via EAL, expected result 2 - * 3. Set user keys for Alice and Bob via EAL, expected result 3 - * 4. Compute shared key via EAL interface, expected result 4 - * 5. Compare shared keys, expected result 5 - * 6. Test ComputeShareKey with longer shareLen, expected result 6 - * 6. Test ComputeShareKey with shorter shareLen, expected result 7 - * @expect - * 1. Success, contexts are not NULL - * 2. CRYPT_SUCCESS - * 3. CRYPT_SUCCESS - * 4. CRYPT_SUCCESS - * 5. Shared keys match - * 6. CRYPT_SUCCESS - * 7. CRYPT_SUCCESS - */ -/* BEGIN_CASE */ -void SDV_CRYPTO_SM9_KEYEX_API_TC001(Hex *masterKey, Hex *userIdA, Hex *userIdB) -{ - CRYPT_EAL_PkeyCtx *ctx_a = NULL; - CRYPT_EAL_PkeyCtx *ctx_b = NULL; - uint8_t SK_A[SM9_SHARED_KEY_LEN] = {0}; - uint8_t SK_B[SM9_SHARED_KEY_LEN] = {0}; - uint32_t keyLen_A = SM9_SHARED_KEY_LEN; - uint32_t keyLen_B = SM9_SHARED_KEY_LEN; - uint8_t SK_Long[2 * SM9_SHARED_KEY_LEN - 1] = {0}; - uint8_t SK_Short[SM9_SHARED_KEY_LEN - 1] = {0}; - uint32_t longKeyLen = sizeof(SK_Long); - uint32_t shortKeyLen = sizeof(SK_Short); - int ret; - int32_t keyType = SM9_KEY_TYPE_ENC; - - // Generate master keys first (use native API for KGC operations) - SM9_Ctx *tmpCtx_a = SM9_NewCtx(); - SM9_Ctx *tmpCtx_b = SM9_NewCtx(); - ASSERT_TRUE(tmpCtx_a != NULL && tmpCtx_b != NULL); - - ret = SM9_SetEncMasterKey(tmpCtx_a, masterKey->x); - ASSERT_EQ(ret, SM9_OK); - ret = SM9_SetEncMasterKey(tmpCtx_b, masterKey->x); - ASSERT_EQ(ret, SM9_OK); - - ret = SM9_GenEncUserKey(tmpCtx_a, userIdA->x, userIdA->len); - ASSERT_EQ(ret, SM9_OK); - ret = SM9_GenEncUserKey(tmpCtx_b, userIdB->x, userIdB->len); - ASSERT_EQ(ret, SM9_OK); - - // Create EAL contexts - ctx_a = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9); - ctx_b = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9); - ASSERT_TRUE(ctx_a != NULL && ctx_b != NULL); - - // Set master private key via EAL for both contexts - BSL_Param params_master[3]; - BSL_PARAM_InitValue(¶ms_master[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS, - masterKey->x, masterKey->len); - BSL_PARAM_InitValue(¶ms_master[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, - &keyType, sizeof(int32_t)); - params_master[2] = (BSL_Param)BSL_PARAM_END; - - ret = CRYPT_EAL_PkeySetPubEx(ctx_a, params_master); - ASSERT_EQ(ret, CRYPT_SUCCESS); - ret = CRYPT_EAL_PkeySetPubEx(ctx_b, params_master); - ASSERT_EQ(ret, CRYPT_SUCCESS); - - // Set user keys via EAL - BSL_Param params_a[4]; - BSL_PARAM_InitValue(¶ms_a[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS, - tmpCtx_a->enc_dek, SM9_ENC_USR_PRIKEY_BYTES); - BSL_PARAM_InitValue(¶ms_a[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS, - userIdA->x, userIdA->len); - BSL_PARAM_InitValue(¶ms_a[2], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, - &keyType, sizeof(int32_t)); - params_a[3] = (BSL_Param)BSL_PARAM_END; - - ret = CRYPT_EAL_PkeySetPrvEx(ctx_a, params_a); - ASSERT_EQ(ret, CRYPT_SUCCESS); - - BSL_Param params_b[4]; - BSL_PARAM_InitValue(¶ms_b[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS, - tmpCtx_b->enc_dek, SM9_ENC_USR_PRIKEY_BYTES); - BSL_PARAM_InitValue(¶ms_b[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS, - userIdB->x, userIdB->len); - BSL_PARAM_InitValue(¶ms_b[2], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, - &keyType, sizeof(int32_t)); - params_b[3] = (BSL_Param)BSL_PARAM_END; - - ret = CRYPT_EAL_PkeySetPrvEx(ctx_b, params_b); - ASSERT_EQ(ret, CRYPT_SUCCESS); - - // Compute shared key via EAL interface - ret = CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK_A, &keyLen_A); - ASSERT_EQ(ret, CRYPT_SUCCESS); - - ret = CRYPT_EAL_PkeyComputeShareKey(ctx_b, ctx_a, SK_B, &keyLen_B); - ASSERT_EQ(ret, CRYPT_SUCCESS); - - // Verify shared keys match - ASSERT_EQ(keyLen_A, keyLen_B); - ASSERT_TRUE(memcmp(SK_A, SK_B, keyLen_A) == 0); - ASSERT_TRUE(TestIsErrStackEmpty()); - - ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK_Long, &longKeyLen), CRYPT_SUCCESS); - ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK_Short, &shortKeyLen), CRYPT_SUCCESS); - -EXIT: - SM9_FreeCtx(tmpCtx_a); - SM9_FreeCtx(tmpCtx_b); - CRYPT_EAL_PkeyFreeCtx(ctx_a); - CRYPT_EAL_PkeyFreeCtx(ctx_b); -} -/* END_CASE */ - -/** - * @test SDV_CRYPTO_SM9_KEYEX_API_TC002 - * @title SM9 Key Exchange: Test with NULL parameters via EAL. - * @precon Prepare valid contexts. - * @brief - * 1. Create and setup a valid context, expected result 1 - * 2. Test ComputeShareKey with NULL selfCtx, expected result 2 - * 3. Test ComputeShareKey with NULL peerCtx, expected result 3 - * 4. Test ComputeShareKey with NULL output buffer, expected result 4 - * 5. Test ComputeShareKey with NULL outLen, expected result 5 - * 6. Test ComputeShareKey, expected result 6 - * @expect - * 1. CRYPT_SUCCESS - * 2. CRYPT_NULL_INPUT - * 3. CRYPT_NULL_INPUT - * 4. CRYPT_NULL_INPUT - * 5. CRYPT_NULL_INPUT - * 6. CRYPT_SM9_ERR_NO_MASTER_KEY - */ -/* BEGIN_CASE */ -void SDV_CRYPTO_SM9_KEYEX_API_TC002(Hex *masterKey, Hex *userIdA, Hex *userIdB) -{ - CRYPT_EAL_PkeyCtx *ctx_a = NULL; - CRYPT_EAL_PkeyCtx *ctx_b = NULL; - uint8_t SK[SM9_SHARED_KEY_LEN] = {0}; - uint32_t keyLen = SM9_SHARED_KEY_LEN; - int ret; - int32_t keyType = SM9_KEY_TYPE_ENC; - - (void)userIdB; // Unused in this test - - // Create and setup valid contexts - ctx_a = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9); - ctx_b = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9); - ASSERT_TRUE(ctx_a != NULL && ctx_b != NULL); - - // Use native API for key generation - SM9_Ctx *tmpCtx_a = SM9_NewCtx(); - ASSERT_TRUE(tmpCtx_a != NULL); - ret = SM9_SetEncMasterKey(tmpCtx_a, masterKey->x); - ASSERT_EQ(ret, SM9_OK); - ret = SM9_GenEncUserKey(tmpCtx_a, userIdA->x, userIdA->len); - ASSERT_EQ(ret, SM9_OK); - - // Set master private key via EAL - BSL_Param params_master[3]; - BSL_PARAM_InitValue(¶ms_master[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS, - masterKey->x, masterKey->len); - BSL_PARAM_InitValue(¶ms_master[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, - &keyType, sizeof(int32_t)); - params_master[2] = (BSL_Param)BSL_PARAM_END; - ret = CRYPT_EAL_PkeySetPubEx(ctx_a, params_master); - ASSERT_EQ(ret, CRYPT_SUCCESS); - - BSL_Param params_a[4]; - BSL_PARAM_InitValue(¶ms_a[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS, - tmpCtx_a->enc_dek, SM9_ENC_USR_PRIKEY_BYTES); - BSL_PARAM_InitValue(¶ms_a[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS, - userIdA->x, userIdA->len); - BSL_PARAM_InitValue(¶ms_a[2], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, - &keyType, sizeof(int32_t)); - params_a[3] = (BSL_Param)BSL_PARAM_END; - ret = CRYPT_EAL_PkeySetPrvEx(ctx_a, params_a); - ASSERT_EQ(ret, CRYPT_SUCCESS); - - // Test NULL selfCtx - ret = CRYPT_EAL_PkeyComputeShareKey(NULL, ctx_b, SK, &keyLen); - ASSERT_EQ(ret, CRYPT_NULL_INPUT); - - // Test NULL peerCtx - ret = CRYPT_EAL_PkeyComputeShareKey(ctx_a, NULL, SK, &keyLen); - ASSERT_EQ(ret, CRYPT_NULL_INPUT); - - // Test NULL output buffer - ret = CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, NULL, &keyLen); - ASSERT_EQ(ret, CRYPT_NULL_INPUT); - - // Test NULL outLen - ret = CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK, NULL); - ASSERT_EQ(ret, CRYPT_NULL_INPUT); - - ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK, &keyLen), CRYPT_SM9_ERR_NO_MASTER_KEY); - -EXIT: - SM9_FreeCtx(tmpCtx_a); - CRYPT_EAL_PkeyFreeCtx(ctx_a); - CRYPT_EAL_PkeyFreeCtx(ctx_b); -} -/* END_CASE */ - -/** - * @test SDV_CRYPTO_SM9_KEYEX_USERID_OVERFLOW_TC001 - * @title SM9 Key Exchange: Test user ID length overflow check. - * @precon Prepare valid master key. - * @brief - * 1. Create contexts with very long user IDs, expected result 1 - * 2. Set master keys and user keys, expected result 2 - * 3. Test ComputeShareKey with combined user ID length > 512, expected result 3 - * @expect - * 1. Success, contexts are not NULL - * 2. CRYPT_SUCCESS - * 3. CRYPT_SM9_ERR_BAD_INPUT (user ID overflow) - */ -/* BEGIN_CASE */ -void SDV_CRYPTO_SM9_KEYEX_USERID_OVERFLOW_TC001(Hex *masterKey) -{ - CRYPT_EAL_PkeyCtx *ctx_a = NULL; - CRYPT_EAL_PkeyCtx *ctx_b = NULL; - uint8_t SK[SM9_SHARED_KEY_LEN] = {0}; - uint32_t keyLen = SM9_SHARED_KEY_LEN; - int ret; - int32_t keyType = SM9_KEY_TYPE_ENC; - - // Create very long user IDs that when combined exceed 512 bytes - uint8_t longUserIdA[256]; // Max allowed user ID length - uint8_t longUserIdB[256]; // Max allowed user ID length - memset(longUserIdA, 'A', sizeof(longUserIdA)); - memset(longUserIdB, 'B', sizeof(longUserIdB)); - - // Create EAL contexts - ctx_a = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9); - ctx_b = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9); - ASSERT_TRUE(ctx_a != NULL && ctx_b != NULL); - - // Set master private key via EAL - BSL_Param params_master[3]; - BSL_PARAM_InitValue(¶ms_master[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS, - masterKey->x, masterKey->len); - BSL_PARAM_InitValue(¶ms_master[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, - &keyType, sizeof(int32_t)); - params_master[2] = (BSL_Param)BSL_PARAM_END; - - ret = CRYPT_EAL_PkeySetPubEx(ctx_a, params_master); - ASSERT_EQ(ret, CRYPT_SUCCESS); - ret = CRYPT_EAL_PkeySetPubEx(ctx_b, params_master); - ASSERT_EQ(ret, CRYPT_SUCCESS); - - // Set user keys via EAL - BSL_Param params_a[4]; - BSL_PARAM_InitValue(¶ms_a[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS, - longUserIdA, sizeof(longUserIdA)); - BSL_PARAM_InitValue(¶ms_a[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, - &keyType, sizeof(int32_t)); - params_a[2] = (BSL_Param)BSL_PARAM_END; - - ret = CRYPT_EAL_PkeySetPrvEx(ctx_a, params_a); - ASSERT_EQ(ret, CRYPT_SUCCESS); - - BSL_Param params_b[4]; - BSL_PARAM_InitValue(¶ms_b[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS, - longUserIdB, sizeof(longUserIdB)); - BSL_PARAM_InitValue(¶ms_b[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, - &keyType, sizeof(int32_t)); - params_b[2] = (BSL_Param)BSL_PARAM_END; - - ret = CRYPT_EAL_PkeySetPrvEx(ctx_b, params_b); - ASSERT_EQ(ret, CRYPT_SUCCESS); - - // Test ComputeShareKey - should fail due to user ID length overflow - // 256 + 256 + 1 = 513 > 512 - ret = CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK, &keyLen); - ASSERT_EQ(ret, CRYPT_SUCCESS); - -EXIT: - CRYPT_EAL_PkeyFreeCtx(ctx_a); - CRYPT_EAL_PkeyFreeCtx(ctx_b); -} -/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_exchange.data b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_exchange.data deleted file mode 100644 index e7e39726..00000000 --- a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_exchange.data +++ /dev/null @@ -1,10 +0,0 @@ -# SM9 Key Exchange Test Data - -SDV_CRYPTO_SM9_KEYEX_API_TC001:masterKey:userIdA:userIdB -SDV_CRYPTO_SM9_KEYEX_API_TC001:"FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210":"416C696365":"426F62" - -SDV_CRYPTO_SM9_KEYEX_API_TC002:masterKey:userIdA:userIdB -SDV_CRYPTO_SM9_KEYEX_API_TC002:"FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210":"416C696365":"426F62" - -SDV_CRYPTO_SM9_KEYEX_USERID_OVERFLOW_TC001:masterKey -SDV_CRYPTO_SM9_KEYEX_USERID_OVERFLOW_TC001:"FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210" diff --git a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_sign.c b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_sign.c index a9b68c39..e33a9dc6 100644 --- a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_sign.c +++ b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_sign.c @@ -216,9 +216,9 @@ void SDV_CRYPTO_SM9_GET_PRV_API_TC001(Hex *masterKey, Hex *userId) nativeCtx = SM9_NewCtx(); ASSERT_TRUE(nativeCtx != NULL); ret = SM9_SetSignMasterKey(nativeCtx, masterKey->x); - ASSERT_EQ(ret, SM9_OK); + ASSERT_EQ(ret, CRYPT_SUCCESS); ret = SM9_GenSignUserKey(nativeCtx, userId->x, userId->len); - ASSERT_EQ(ret, SM9_OK); + ASSERT_EQ(ret, CRYPT_SUCCESS); memcpy_s(expectedUserKey, sizeof(expectedUserKey), nativeCtx->sig_dsk, SM9_SIG_USR_PRIKEY_BYTES); // Step 1: Create EAL context @@ -795,7 +795,7 @@ void SDV_CRYPTO_SM9_CHECK_KEYPAIR_FUNC_TC001(Hex *masterKey, Hex *userId1, Hex * BSL_PARAM_InitValue(¶ms[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS, userId1->x, userId1->len); params[1] = (BSL_Param)BSL_PARAM_END; - ret = CRYPT_EAL_PkeyCtrl(masterCtx, CRYPT_CTRL_SET_SM2_USER_ID, params[0].value, params[0].valueLen); + ret = CRYPT_EAL_PkeyCtrl(masterCtx, CRYPT_CTRL_SET_SM9_USER_ID, params[0].value, params[0].valueLen); ASSERT_EQ(ret, CRYPT_SUCCESS); // Check key pair - should succeed (same user ID) @@ -803,7 +803,7 @@ void SDV_CRYPTO_SM9_CHECK_KEYPAIR_FUNC_TC001(Hex *masterKey, Hex *userId1, Hex * ASSERT_EQ(ret, CRYPT_SUCCESS); // Step 6: Change user ID in master context to userId2 - ret = CRYPT_EAL_PkeyCtrl(masterCtx, CRYPT_CTRL_SET_SM2_USER_ID, userId2->x, userId2->len); + ret = CRYPT_EAL_PkeyCtrl(masterCtx, CRYPT_CTRL_SET_SM9_USER_ID, userId2->x, userId2->len); ASSERT_EQ(ret, CRYPT_SUCCESS); ASSERT_TRUE(TestIsErrStackEmpty()); @@ -941,3 +941,81 @@ EXIT: CRYPT_EAL_PkeyFreeCtx(ctx2); } /* END_CASE */ + +/** + * @test SDV_CRYPTO_SM9_SIGN_VECTOR_TC001 + * @title SM9 Sign/Verify: Verify signature from standard vector via EAL interface. + * @precon Prepare master key, user ID, message, fixed random, and expected signature. + * @brief + * Source: GB/T 38635.2-2020 Appendix A (SM9 digital signature algorithm example) + * 1. Create EAL context and set sign master key + * 2. Generate user signing key via EAL SetPrvEx + * 3. Verify the expected signature from standard via EAL PkeyVerify + * 4. Sign message via EAL PkeySign and verify the new signature + * @expect + * 1-2. Setup succeeds + * 3. Verification of standard signature succeeds + * 4. Round-trip sign/verify succeeds + */ +/* BEGIN_CASE */ +void SDV_CRYPTO_SM9_SIGN_VECTOR_TC001(Hex *masterKey, Hex *userId, Hex *message, + Hex *randHex, Hex *expectedSig) +{ + CRYPT_EAL_PkeyCtx *ctx = NULL; + uint8_t signature[SM9_SIGNATURE_LEN] = {0}; + uint32_t signLen = SM9_SIGNATURE_LEN; + BSL_Param params[4]; + int32_t keyType = SM9_KEY_TYPE_SIGN; + int ret; + + // Step 1: Create EAL context and set master key + ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9); + ASSERT_TRUE(ctx != NULL); + + BSL_PARAM_InitValue(¶ms[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS, + masterKey->x, masterKey->len); + BSL_PARAM_InitValue(¶ms[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, + &keyType, sizeof(int32_t)); + params[2] = (BSL_Param)BSL_PARAM_END; + + ret = CRYPT_EAL_PkeySetPubEx(ctx, params); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + // Step 2: Generate user signing key via EAL + BSL_PARAM_InitValue(¶ms[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS, + userId->x, userId->len); + BSL_PARAM_InitValue(¶ms[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32, + &keyType, sizeof(int32_t)); + params[2] = (BSL_Param)BSL_PARAM_END; + + ret = CRYPT_EAL_PkeySetPrvEx(ctx, params); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + // Step 3: Verify the expected signature from standard + ret = CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, message->x, message->len, + expectedSig->x, expectedSig->len); + ASSERT_EQ(ret, CRYPT_SUCCESS); + + // Step 4: Sign with stubbed random and verify signature matches standard vector + g_sm9StubRand = randHex->x; + g_sm9StubRandLen = randHex->len; + STUB_REPLACE(CRYPT_RandEx, STUB_CRYPT_RandEx); + + ret = CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, message->x, message->len, + signature, &signLen); + ASSERT_EQ(ret, CRYPT_SUCCESS); + ASSERT_EQ(signLen, expectedSig->len); + ASSERT_EQ(memcmp(signature, expectedSig->x, signLen), 0); + + // Step 5: Verify the generated signature + ret = CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, message->x, message->len, + signature, signLen); + ASSERT_EQ(ret, CRYPT_SUCCESS); + +EXIT: + STUB_RESTORE(CRYPT_RandEx); + g_sm9StubRand = NULL; + g_sm9StubRandLen = 0; + CRYPT_EAL_PkeyFreeCtx(ctx); +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_sign.data b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_sign.data index a59c90f8..5b7a980a 100644 --- a/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_sign.data +++ b/testcode/sdv/testcase/crypto/sm9/test_suite_sdv_eal_sm9_sign.data @@ -38,3 +38,7 @@ SDV_CRYPTO_SM9_CHECK_PRVKEY_FUNC_TC001:"0123456789ABCDEF0123456789ABCDEF01234567 SDV_CRYPTO_SM9_PUBKEY_SET_TEST_TC001: SDV_CRYPTO_SM9_PUBKEY_SET_TEST_TC001: + +# Source: GB/T 38635.2-2020 Appendix A (SM9 digital signature algorithm example) +SDV_CRYPTO_SM9_SIGN_VECTOR_TC001:masterKey:userId:message:randHex:expectedSig +SDV_CRYPTO_SM9_SIGN_VECTOR_TC001:"000130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4":"416C696365":"4368696E65736520494253207374616E64617264":"00033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBD":"823C4B21E4BD2DFE1ED92C606653E996668563152FC33F55D7BFBB9BD9705ADB73BF96923CE58B6AD0E13E9643A406D8EB98417C50EF1B29CEF9ADB48B6D598C856712F1C2E0968AB7769F42A99586AED139D5B8B3E15891827CC2ACED9BAA05"