mirror of
https://github.com/openssl/openssl.git
synced 2025-03-31 20:10:45 +08:00
Make SM2 ID stick to specification
Reviewed-by: Tim Hudson <tjh@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/7113)
This commit is contained in:
parent
0a8fdef752
commit
00433bad41
@ -20,18 +20,28 @@
|
||||
/* The default user id as specified in GM/T 0009-2012 */
|
||||
# define SM2_DEFAULT_USERID "1234567812345678"
|
||||
|
||||
int sm2_compute_userid_digest(uint8_t *out,
|
||||
const EVP_MD *digest,
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const EC_KEY *key);
|
||||
|
||||
/*
|
||||
* SM2 signature operation. Computes ZA (user id digest) and then signs
|
||||
* H(ZA || msg) using SM2
|
||||
*/
|
||||
ECDSA_SIG *sm2_do_sign(const EC_KEY *key,
|
||||
const EVP_MD *digest,
|
||||
const char *user_id, const uint8_t *msg, size_t msg_len);
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const uint8_t *msg, size_t msg_len);
|
||||
|
||||
int sm2_do_verify(const EC_KEY *key,
|
||||
const EVP_MD *digest,
|
||||
const ECDSA_SIG *signature,
|
||||
const char *user_id, const uint8_t *msg, size_t msg_len);
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const uint8_t *msg, size_t msg_len);
|
||||
|
||||
/*
|
||||
* SM2 signature generation.
|
||||
|
@ -22,6 +22,8 @@ typedef struct {
|
||||
EC_GROUP *gen_group;
|
||||
/* message digest */
|
||||
const EVP_MD *md;
|
||||
uint8_t *id;
|
||||
size_t id_len;
|
||||
} SM2_PKEY_CTX;
|
||||
|
||||
static int pkey_sm2_init(EVP_PKEY_CTX *ctx)
|
||||
@ -209,6 +211,29 @@ static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
return -2;
|
||||
}
|
||||
|
||||
static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
|
||||
{
|
||||
uint8_t z[EVP_MAX_MD_SIZE];
|
||||
SM2_PKEY_CTX *sctx = ctx->data;
|
||||
EC_KEY *ec = ctx->pkey->pkey.ec;
|
||||
const EVP_MD *md = EVP_MD_CTX_md(mctx);
|
||||
|
||||
if (sctx->id == NULL) {
|
||||
/* XXX:
|
||||
* currently we reject all null-ID for SM2, but this needs
|
||||
* more considerations and discussion since the specifications
|
||||
* on SM2 are not clear on null-ID
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get hashed prefix of tbs message */
|
||||
if (!sm2_compute_userid_digest(z, md, sctx->id, sctx->id_len, ec))
|
||||
return 0;
|
||||
|
||||
return EVP_DigestUpdate(mctx, z, EVP_MD_size(md));
|
||||
}
|
||||
|
||||
const EVP_PKEY_METHOD sm2_pkey_meth = {
|
||||
EVP_PKEY_SM2,
|
||||
0,
|
||||
@ -241,5 +266,11 @@ const EVP_PKEY_METHOD sm2_pkey_meth = {
|
||||
0,
|
||||
0,
|
||||
pkey_sm2_ctrl,
|
||||
pkey_sm2_ctrl_str
|
||||
pkey_sm2_ctrl_str,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0, 0,
|
||||
|
||||
pkey_sm2_digest_custom
|
||||
};
|
||||
|
@ -18,10 +18,11 @@
|
||||
#include <openssl/bn.h>
|
||||
#include <string.h>
|
||||
|
||||
static int sm2_compute_userid_digest(uint8_t *out,
|
||||
const EVP_MD *digest,
|
||||
const char *user_id,
|
||||
const EC_KEY *key)
|
||||
int sm2_compute_userid_digest(uint8_t *out,
|
||||
const EVP_MD *digest,
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const EC_KEY *key)
|
||||
{
|
||||
int rc = 0;
|
||||
const EC_GROUP *group = EC_KEY_get0_group(key);
|
||||
@ -36,7 +37,6 @@ static int sm2_compute_userid_digest(uint8_t *out,
|
||||
BIGNUM *yA = NULL;
|
||||
int p_bytes = 0;
|
||||
uint8_t *buf = NULL;
|
||||
size_t uid_len = 0;
|
||||
uint16_t entla = 0;
|
||||
uint8_t e_byte = 0;
|
||||
|
||||
@ -67,14 +67,13 @@ static int sm2_compute_userid_digest(uint8_t *out,
|
||||
|
||||
/* Z = SM3(ENTLA || IDA || a || b || xG || yG || xA || yA) */
|
||||
|
||||
uid_len = strlen(user_id);
|
||||
if (uid_len >= (UINT16_MAX / 8)) {
|
||||
if (id_len >= (UINT16_MAX / 8)) {
|
||||
/* too large */
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, SM2_R_USER_ID_TOO_LARGE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
entla = (uint16_t)(8 * uid_len);
|
||||
entla = (uint16_t)(8 * id_len);
|
||||
|
||||
e_byte = entla >> 8;
|
||||
if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
|
||||
@ -83,7 +82,7 @@ static int sm2_compute_userid_digest(uint8_t *out,
|
||||
}
|
||||
e_byte = entla & 0xFF;
|
||||
if (!EVP_DigestUpdate(hash, &e_byte, 1)
|
||||
|| !EVP_DigestUpdate(hash, user_id, uid_len)) {
|
||||
|| !EVP_DigestUpdate(hash, id, id_len)) {
|
||||
SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
|
||||
goto done;
|
||||
}
|
||||
@ -134,7 +133,8 @@ static int sm2_compute_userid_digest(uint8_t *out,
|
||||
|
||||
static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
|
||||
const EC_KEY *key,
|
||||
const char *user_id,
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const uint8_t *msg, size_t msg_len)
|
||||
{
|
||||
EVP_MD_CTX *hash = EVP_MD_CTX_new();
|
||||
@ -153,7 +153,7 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!sm2_compute_userid_digest(za, digest, user_id, key)) {
|
||||
if (!sm2_compute_userid_digest(za, digest, id, id_len, key)) {
|
||||
/* SM2err already called */
|
||||
goto done;
|
||||
}
|
||||
@ -358,12 +358,14 @@ static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig,
|
||||
|
||||
ECDSA_SIG *sm2_do_sign(const EC_KEY *key,
|
||||
const EVP_MD *digest,
|
||||
const char *user_id, const uint8_t *msg, size_t msg_len)
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const uint8_t *msg, size_t msg_len)
|
||||
{
|
||||
BIGNUM *e = NULL;
|
||||
ECDSA_SIG *sig = NULL;
|
||||
|
||||
e = sm2_compute_msg_hash(digest, key, user_id, msg, msg_len);
|
||||
e = sm2_compute_msg_hash(digest, key, id, id_len, msg, msg_len);
|
||||
if (e == NULL) {
|
||||
/* SM2err already called */
|
||||
goto done;
|
||||
@ -379,12 +381,14 @@ ECDSA_SIG *sm2_do_sign(const EC_KEY *key,
|
||||
int sm2_do_verify(const EC_KEY *key,
|
||||
const EVP_MD *digest,
|
||||
const ECDSA_SIG *sig,
|
||||
const char *user_id, const uint8_t *msg, size_t msg_len)
|
||||
const uint8_t *id,
|
||||
const size_t id_len,
|
||||
const uint8_t *msg, size_t msg_len)
|
||||
{
|
||||
BIGNUM *e = NULL;
|
||||
int ret = 0;
|
||||
|
||||
e = sm2_compute_msg_hash(digest, key, user_id, msg, msg_len);
|
||||
e = sm2_compute_msg_hash(digest, key, id, id_len, msg, msg_len);
|
||||
if (e == NULL) {
|
||||
/* SM2err already called */
|
||||
goto done;
|
||||
|
@ -294,7 +294,8 @@ static int test_sm2_sign(const EC_GROUP *group,
|
||||
goto done;
|
||||
|
||||
start_fake_rand(k_hex);
|
||||
sig = sm2_do_sign(key, EVP_sm3(), userid, (const uint8_t *)message, msg_len);
|
||||
sig = sm2_do_sign(key, EVP_sm3(), (const uint8_t *)userid, strlen(userid),
|
||||
(const uint8_t *)message, msg_len);
|
||||
if (!TEST_ptr(sig)
|
||||
|| !TEST_size_t_eq(fake_rand_bytes_offset, fake_rand_size)) {
|
||||
restore_rand();
|
||||
@ -310,8 +311,8 @@ static int test_sm2_sign(const EC_GROUP *group,
|
||||
|| !TEST_BN_eq(s, sig_s))
|
||||
goto done;
|
||||
|
||||
ok = sm2_do_verify(key, EVP_sm3(), sig, userid, (const uint8_t *)message,
|
||||
msg_len);
|
||||
ok = sm2_do_verify(key, EVP_sm3(), sig, (const uint8_t *)userid,
|
||||
strlen(userid), (const uint8_t *)message, msg_len);
|
||||
|
||||
/* We goto done whether this passes or fails */
|
||||
TEST_true(ok);
|
||||
|
Loading…
x
Reference in New Issue
Block a user