feat(sm9): remove key exchange capability

Remove all SM9 key exchange functionality including algorithm
  implementation, EAL layer, CTRL commands, test cases, and cmake options.
  Sign and encrypt operations remain fully functional.

Cherry-picked from: https://gitcode.com/openHiTLS/openhitls/merge_requests/1412

Signed-off-by: Dongjianwei001 <dongjianwei1@huawei.com>
This commit is contained in:
jchx
2026-05-13 11:29:04 +00:00
committed by Dongjianwei001
parent 6cca63e935
commit ee9c094ad4
33 changed files with 581 additions and 1421 deletions
+1 -2
View File
@@ -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"
],
@@ -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
+4 -1
View File
@@ -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;
}
-4
View File
@@ -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
+2 -2
View File
@@ -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
+5
View File
@@ -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;
}
+3 -8
View File
@@ -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) {
+4 -1
View File
@@ -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),
+5 -5
View File
@@ -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.
+2 -13
View File
@@ -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
-12
View File
@@ -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
+9 -92
View File
@@ -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
+73 -574
View File
@@ -24,7 +24,7 @@
#include "crypt_util_rand.h"
#include "crypt_errno.h"
#include <string.h>
#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 */
+23 -25
View File
@@ -19,6 +19,7 @@
#include "crypt_sm9.h"
#include "crypt_errno.h"
#include "sm9.h"
#include "bsl_sal.h"
#include <string.h>
/*============================================================================*/
@@ -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);
+42 -163
View File
@@ -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;
}
-125
View File
@@ -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 <string.h>
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
+18 -18
View File
@@ -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;
+2 -2
View File
@@ -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;
+1 -1
View File
@@ -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
+1 -2
View File
@@ -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. */
+3
View File
@@ -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;
@@ -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 */
@@ -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
@@ -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"
@@ -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();
@@ -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);
@@ -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
@@ -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(&params[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
masterKey->x, masterKey->len);
BSL_PARAM_InitValue(&params[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
userId->x, userId->len);
BSL_PARAM_InitValue(&params[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(&params[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
masterKey->x, masterKey->len);
BSL_PARAM_InitValue(&params[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 */
@@ -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"
@@ -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(&params_master[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
masterKey->x, masterKey->len);
BSL_PARAM_InitValue(&params_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(&params_a[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS,
tmpCtx_a->enc_dek, SM9_ENC_USR_PRIKEY_BYTES);
BSL_PARAM_InitValue(&params_a[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
userIdA->x, userIdA->len);
BSL_PARAM_InitValue(&params_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(&params_b[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS,
tmpCtx_b->enc_dek, SM9_ENC_USR_PRIKEY_BYTES);
BSL_PARAM_InitValue(&params_b[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
userIdB->x, userIdB->len);
BSL_PARAM_InitValue(&params_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(&params_master[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
masterKey->x, masterKey->len);
BSL_PARAM_InitValue(&params_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(&params_a[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS,
tmpCtx_a->enc_dek, SM9_ENC_USR_PRIKEY_BYTES);
BSL_PARAM_InitValue(&params_a[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
userIdA->x, userIdA->len);
BSL_PARAM_InitValue(&params_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(&params_master[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
masterKey->x, masterKey->len);
BSL_PARAM_InitValue(&params_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(&params_a[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
longUserIdA, sizeof(longUserIdA));
BSL_PARAM_InitValue(&params_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(&params_b[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
longUserIdB, sizeof(longUserIdB));
BSL_PARAM_InitValue(&params_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 */
@@ -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"
@@ -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(&params[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(&params[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
masterKey->x, masterKey->len);
BSL_PARAM_InitValue(&params[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(&params[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
userId->x, userId->len);
BSL_PARAM_InitValue(&params[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 */
@@ -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"