mirror of
https://github.com/openharmony/third_party_openhitls.git
synced 2026-07-01 10:05:26 -04:00
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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -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(¶ms[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
|
||||
masterKey->x, masterKey->len);
|
||||
BSL_PARAM_InitValue(¶ms[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
|
||||
userId->x, userId->len);
|
||||
BSL_PARAM_InitValue(¶ms[2], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params[3] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPubEx(encCtx, params);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Step 3: Encrypt with stubbed random and verify ciphertext matches standard vector
|
||||
g_sm9StubRand = randHex->x;
|
||||
g_sm9StubRandLen = randHex->len;
|
||||
STUB_REPLACE(CRYPT_RandEx, STUB_CRYPT_RandEx);
|
||||
|
||||
ret = CRYPT_EAL_PkeyEncrypt(encCtx, message->x, message->len,
|
||||
ciphertext, &cipherLen);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
ASSERT_EQ(cipherLen, expectedCipher->len);
|
||||
ASSERT_EQ(memcmp(ciphertext, expectedCipher->x, cipherLen), 0);
|
||||
|
||||
STUB_RESTORE(CRYPT_RandEx);
|
||||
g_sm9StubRand = NULL;
|
||||
g_sm9StubRandLen = 0;
|
||||
|
||||
// Step 4: Create EAL decrypt context and verify decryption
|
||||
decCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9);
|
||||
ASSERT_TRUE(decCtx != NULL);
|
||||
|
||||
BSL_PARAM_InitValue(¶ms[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
|
||||
masterKey->x, masterKey->len);
|
||||
BSL_PARAM_InitValue(¶ms[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params[2] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPubEx(decCtx, params);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
BSL_Param decParams[4];
|
||||
BSL_PARAM_InitValue(&decParams[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS,
|
||||
userKey, SM9_ENC_USR_PRIKEY_BYTES);
|
||||
BSL_PARAM_InitValue(&decParams[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
|
||||
userId->x, userId->len);
|
||||
BSL_PARAM_InitValue(&decParams[2], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
decParams[3] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPrvEx(decCtx, decParams);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
ret = CRYPT_EAL_PkeyDecrypt(decCtx, expectedCipher->x, expectedCipher->len,
|
||||
decrypted, &decryptLen);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
ASSERT_EQ(decryptLen, message->len);
|
||||
ASSERT_EQ(memcmp(decrypted, message->x, message->len), 0);
|
||||
|
||||
EXIT:
|
||||
STUB_RESTORE(CRYPT_RandEx);
|
||||
g_sm9StubRand = NULL;
|
||||
g_sm9StubRandLen = 0;
|
||||
CRYPT_EAL_PkeyFreeCtx(encCtx);
|
||||
CRYPT_EAL_PkeyFreeCtx(decCtx);
|
||||
SM9_FreeCtx(nativeCtx);
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
@@ -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(¶ms_master[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
|
||||
masterKey->x, masterKey->len);
|
||||
BSL_PARAM_InitValue(¶ms_master[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params_master[2] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPubEx(ctx_a, params_master);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
ret = CRYPT_EAL_PkeySetPubEx(ctx_b, params_master);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Set user keys via EAL
|
||||
BSL_Param params_a[4];
|
||||
BSL_PARAM_InitValue(¶ms_a[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS,
|
||||
tmpCtx_a->enc_dek, SM9_ENC_USR_PRIKEY_BYTES);
|
||||
BSL_PARAM_InitValue(¶ms_a[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
|
||||
userIdA->x, userIdA->len);
|
||||
BSL_PARAM_InitValue(¶ms_a[2], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params_a[3] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPrvEx(ctx_a, params_a);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
BSL_Param params_b[4];
|
||||
BSL_PARAM_InitValue(¶ms_b[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS,
|
||||
tmpCtx_b->enc_dek, SM9_ENC_USR_PRIKEY_BYTES);
|
||||
BSL_PARAM_InitValue(¶ms_b[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
|
||||
userIdB->x, userIdB->len);
|
||||
BSL_PARAM_InitValue(¶ms_b[2], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params_b[3] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPrvEx(ctx_b, params_b);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Compute shared key via EAL interface
|
||||
ret = CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK_A, &keyLen_A);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
ret = CRYPT_EAL_PkeyComputeShareKey(ctx_b, ctx_a, SK_B, &keyLen_B);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Verify shared keys match
|
||||
ASSERT_EQ(keyLen_A, keyLen_B);
|
||||
ASSERT_TRUE(memcmp(SK_A, SK_B, keyLen_A) == 0);
|
||||
ASSERT_TRUE(TestIsErrStackEmpty());
|
||||
|
||||
ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK_Long, &longKeyLen), CRYPT_SUCCESS);
|
||||
ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK_Short, &shortKeyLen), CRYPT_SUCCESS);
|
||||
|
||||
EXIT:
|
||||
SM9_FreeCtx(tmpCtx_a);
|
||||
SM9_FreeCtx(tmpCtx_b);
|
||||
CRYPT_EAL_PkeyFreeCtx(ctx_a);
|
||||
CRYPT_EAL_PkeyFreeCtx(ctx_b);
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPTO_SM9_KEYEX_API_TC002
|
||||
* @title SM9 Key Exchange: Test with NULL parameters via EAL.
|
||||
* @precon Prepare valid contexts.
|
||||
* @brief
|
||||
* 1. Create and setup a valid context, expected result 1
|
||||
* 2. Test ComputeShareKey with NULL selfCtx, expected result 2
|
||||
* 3. Test ComputeShareKey with NULL peerCtx, expected result 3
|
||||
* 4. Test ComputeShareKey with NULL output buffer, expected result 4
|
||||
* 5. Test ComputeShareKey with NULL outLen, expected result 5
|
||||
* 6. Test ComputeShareKey, expected result 6
|
||||
* @expect
|
||||
* 1. CRYPT_SUCCESS
|
||||
* 2. CRYPT_NULL_INPUT
|
||||
* 3. CRYPT_NULL_INPUT
|
||||
* 4. CRYPT_NULL_INPUT
|
||||
* 5. CRYPT_NULL_INPUT
|
||||
* 6. CRYPT_SM9_ERR_NO_MASTER_KEY
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPTO_SM9_KEYEX_API_TC002(Hex *masterKey, Hex *userIdA, Hex *userIdB)
|
||||
{
|
||||
CRYPT_EAL_PkeyCtx *ctx_a = NULL;
|
||||
CRYPT_EAL_PkeyCtx *ctx_b = NULL;
|
||||
uint8_t SK[SM9_SHARED_KEY_LEN] = {0};
|
||||
uint32_t keyLen = SM9_SHARED_KEY_LEN;
|
||||
int ret;
|
||||
int32_t keyType = SM9_KEY_TYPE_ENC;
|
||||
|
||||
(void)userIdB; // Unused in this test
|
||||
|
||||
// Create and setup valid contexts
|
||||
ctx_a = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9);
|
||||
ctx_b = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9);
|
||||
ASSERT_TRUE(ctx_a != NULL && ctx_b != NULL);
|
||||
|
||||
// Use native API for key generation
|
||||
SM9_Ctx *tmpCtx_a = SM9_NewCtx();
|
||||
ASSERT_TRUE(tmpCtx_a != NULL);
|
||||
ret = SM9_SetEncMasterKey(tmpCtx_a, masterKey->x);
|
||||
ASSERT_EQ(ret, SM9_OK);
|
||||
ret = SM9_GenEncUserKey(tmpCtx_a, userIdA->x, userIdA->len);
|
||||
ASSERT_EQ(ret, SM9_OK);
|
||||
|
||||
// Set master private key via EAL
|
||||
BSL_Param params_master[3];
|
||||
BSL_PARAM_InitValue(¶ms_master[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
|
||||
masterKey->x, masterKey->len);
|
||||
BSL_PARAM_InitValue(¶ms_master[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params_master[2] = (BSL_Param)BSL_PARAM_END;
|
||||
ret = CRYPT_EAL_PkeySetPubEx(ctx_a, params_master);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
BSL_Param params_a[4];
|
||||
BSL_PARAM_InitValue(¶ms_a[0], CRYPT_PARAM_SM9_USER_KEY, BSL_PARAM_TYPE_OCTETS,
|
||||
tmpCtx_a->enc_dek, SM9_ENC_USR_PRIKEY_BYTES);
|
||||
BSL_PARAM_InitValue(¶ms_a[1], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
|
||||
userIdA->x, userIdA->len);
|
||||
BSL_PARAM_InitValue(¶ms_a[2], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params_a[3] = (BSL_Param)BSL_PARAM_END;
|
||||
ret = CRYPT_EAL_PkeySetPrvEx(ctx_a, params_a);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Test NULL selfCtx
|
||||
ret = CRYPT_EAL_PkeyComputeShareKey(NULL, ctx_b, SK, &keyLen);
|
||||
ASSERT_EQ(ret, CRYPT_NULL_INPUT);
|
||||
|
||||
// Test NULL peerCtx
|
||||
ret = CRYPT_EAL_PkeyComputeShareKey(ctx_a, NULL, SK, &keyLen);
|
||||
ASSERT_EQ(ret, CRYPT_NULL_INPUT);
|
||||
|
||||
// Test NULL output buffer
|
||||
ret = CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, NULL, &keyLen);
|
||||
ASSERT_EQ(ret, CRYPT_NULL_INPUT);
|
||||
|
||||
// Test NULL outLen
|
||||
ret = CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK, NULL);
|
||||
ASSERT_EQ(ret, CRYPT_NULL_INPUT);
|
||||
|
||||
ASSERT_EQ(CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK, &keyLen), CRYPT_SM9_ERR_NO_MASTER_KEY);
|
||||
|
||||
EXIT:
|
||||
SM9_FreeCtx(tmpCtx_a);
|
||||
CRYPT_EAL_PkeyFreeCtx(ctx_a);
|
||||
CRYPT_EAL_PkeyFreeCtx(ctx_b);
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPTO_SM9_KEYEX_USERID_OVERFLOW_TC001
|
||||
* @title SM9 Key Exchange: Test user ID length overflow check.
|
||||
* @precon Prepare valid master key.
|
||||
* @brief
|
||||
* 1. Create contexts with very long user IDs, expected result 1
|
||||
* 2. Set master keys and user keys, expected result 2
|
||||
* 3. Test ComputeShareKey with combined user ID length > 512, expected result 3
|
||||
* @expect
|
||||
* 1. Success, contexts are not NULL
|
||||
* 2. CRYPT_SUCCESS
|
||||
* 3. CRYPT_SM9_ERR_BAD_INPUT (user ID overflow)
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPTO_SM9_KEYEX_USERID_OVERFLOW_TC001(Hex *masterKey)
|
||||
{
|
||||
CRYPT_EAL_PkeyCtx *ctx_a = NULL;
|
||||
CRYPT_EAL_PkeyCtx *ctx_b = NULL;
|
||||
uint8_t SK[SM9_SHARED_KEY_LEN] = {0};
|
||||
uint32_t keyLen = SM9_SHARED_KEY_LEN;
|
||||
int ret;
|
||||
int32_t keyType = SM9_KEY_TYPE_ENC;
|
||||
|
||||
// Create very long user IDs that when combined exceed 512 bytes
|
||||
uint8_t longUserIdA[256]; // Max allowed user ID length
|
||||
uint8_t longUserIdB[256]; // Max allowed user ID length
|
||||
memset(longUserIdA, 'A', sizeof(longUserIdA));
|
||||
memset(longUserIdB, 'B', sizeof(longUserIdB));
|
||||
|
||||
// Create EAL contexts
|
||||
ctx_a = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9);
|
||||
ctx_b = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9);
|
||||
ASSERT_TRUE(ctx_a != NULL && ctx_b != NULL);
|
||||
|
||||
// Set master private key via EAL
|
||||
BSL_Param params_master[3];
|
||||
BSL_PARAM_InitValue(¶ms_master[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
|
||||
masterKey->x, masterKey->len);
|
||||
BSL_PARAM_InitValue(¶ms_master[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params_master[2] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPubEx(ctx_a, params_master);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
ret = CRYPT_EAL_PkeySetPubEx(ctx_b, params_master);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Set user keys via EAL
|
||||
BSL_Param params_a[4];
|
||||
BSL_PARAM_InitValue(¶ms_a[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
|
||||
longUserIdA, sizeof(longUserIdA));
|
||||
BSL_PARAM_InitValue(¶ms_a[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params_a[2] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPrvEx(ctx_a, params_a);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
BSL_Param params_b[4];
|
||||
BSL_PARAM_InitValue(¶ms_b[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
|
||||
longUserIdB, sizeof(longUserIdB));
|
||||
BSL_PARAM_InitValue(¶ms_b[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params_b[2] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPrvEx(ctx_b, params_b);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Test ComputeShareKey - should fail due to user ID length overflow
|
||||
// 256 + 256 + 1 = 513 > 512
|
||||
ret = CRYPT_EAL_PkeyComputeShareKey(ctx_a, ctx_b, SK, &keyLen);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
EXIT:
|
||||
CRYPT_EAL_PkeyFreeCtx(ctx_a);
|
||||
CRYPT_EAL_PkeyFreeCtx(ctx_b);
|
||||
}
|
||||
/* END_CASE */
|
||||
@@ -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(¶ms[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
|
||||
userId1->x, userId1->len);
|
||||
params[1] = (BSL_Param)BSL_PARAM_END;
|
||||
ret = CRYPT_EAL_PkeyCtrl(masterCtx, CRYPT_CTRL_SET_SM2_USER_ID, params[0].value, params[0].valueLen);
|
||||
ret = CRYPT_EAL_PkeyCtrl(masterCtx, CRYPT_CTRL_SET_SM9_USER_ID, params[0].value, params[0].valueLen);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Check key pair - should succeed (same user ID)
|
||||
@@ -803,7 +803,7 @@ void SDV_CRYPTO_SM9_CHECK_KEYPAIR_FUNC_TC001(Hex *masterKey, Hex *userId1, Hex *
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Step 6: Change user ID in master context to userId2
|
||||
ret = CRYPT_EAL_PkeyCtrl(masterCtx, CRYPT_CTRL_SET_SM2_USER_ID, userId2->x, userId2->len);
|
||||
ret = CRYPT_EAL_PkeyCtrl(masterCtx, CRYPT_CTRL_SET_SM9_USER_ID, userId2->x, userId2->len);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
ASSERT_TRUE(TestIsErrStackEmpty());
|
||||
|
||||
@@ -941,3 +941,81 @@ EXIT:
|
||||
CRYPT_EAL_PkeyFreeCtx(ctx2);
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/**
|
||||
* @test SDV_CRYPTO_SM9_SIGN_VECTOR_TC001
|
||||
* @title SM9 Sign/Verify: Verify signature from standard vector via EAL interface.
|
||||
* @precon Prepare master key, user ID, message, fixed random, and expected signature.
|
||||
* @brief
|
||||
* Source: GB/T 38635.2-2020 Appendix A (SM9 digital signature algorithm example)
|
||||
* 1. Create EAL context and set sign master key
|
||||
* 2. Generate user signing key via EAL SetPrvEx
|
||||
* 3. Verify the expected signature from standard via EAL PkeyVerify
|
||||
* 4. Sign message via EAL PkeySign and verify the new signature
|
||||
* @expect
|
||||
* 1-2. Setup succeeds
|
||||
* 3. Verification of standard signature succeeds
|
||||
* 4. Round-trip sign/verify succeeds
|
||||
*/
|
||||
/* BEGIN_CASE */
|
||||
void SDV_CRYPTO_SM9_SIGN_VECTOR_TC001(Hex *masterKey, Hex *userId, Hex *message,
|
||||
Hex *randHex, Hex *expectedSig)
|
||||
{
|
||||
CRYPT_EAL_PkeyCtx *ctx = NULL;
|
||||
uint8_t signature[SM9_SIGNATURE_LEN] = {0};
|
||||
uint32_t signLen = SM9_SIGNATURE_LEN;
|
||||
BSL_Param params[4];
|
||||
int32_t keyType = SM9_KEY_TYPE_SIGN;
|
||||
int ret;
|
||||
|
||||
// Step 1: Create EAL context and set master key
|
||||
ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM9);
|
||||
ASSERT_TRUE(ctx != NULL);
|
||||
|
||||
BSL_PARAM_InitValue(¶ms[0], CRYPT_PARAM_SM9_MASTER_KEY, BSL_PARAM_TYPE_OCTETS,
|
||||
masterKey->x, masterKey->len);
|
||||
BSL_PARAM_InitValue(¶ms[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params[2] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPubEx(ctx, params);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Step 2: Generate user signing key via EAL
|
||||
BSL_PARAM_InitValue(¶ms[0], CRYPT_PARAM_SM9_USER_ID, BSL_PARAM_TYPE_OCTETS,
|
||||
userId->x, userId->len);
|
||||
BSL_PARAM_InitValue(¶ms[1], CRYPT_PARAM_SM9_KEY_TYPE, BSL_PARAM_TYPE_INT32,
|
||||
&keyType, sizeof(int32_t));
|
||||
params[2] = (BSL_Param)BSL_PARAM_END;
|
||||
|
||||
ret = CRYPT_EAL_PkeySetPrvEx(ctx, params);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Step 3: Verify the expected signature from standard
|
||||
ret = CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, message->x, message->len,
|
||||
expectedSig->x, expectedSig->len);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
// Step 4: Sign with stubbed random and verify signature matches standard vector
|
||||
g_sm9StubRand = randHex->x;
|
||||
g_sm9StubRandLen = randHex->len;
|
||||
STUB_REPLACE(CRYPT_RandEx, STUB_CRYPT_RandEx);
|
||||
|
||||
ret = CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, message->x, message->len,
|
||||
signature, &signLen);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
ASSERT_EQ(signLen, expectedSig->len);
|
||||
ASSERT_EQ(memcmp(signature, expectedSig->x, signLen), 0);
|
||||
|
||||
// Step 5: Verify the generated signature
|
||||
ret = CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, message->x, message->len,
|
||||
signature, signLen);
|
||||
ASSERT_EQ(ret, CRYPT_SUCCESS);
|
||||
|
||||
EXIT:
|
||||
STUB_RESTORE(CRYPT_RandEx);
|
||||
g_sm9StubRand = NULL;
|
||||
g_sm9StubRandLen = 0;
|
||||
CRYPT_EAL_PkeyFreeCtx(ctx);
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user