From 93064bf8266f1f952916d959332ddec1e3f6cbbc Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Sat, 29 Sep 2018 11:54:00 +0800 Subject: [PATCH] First SM9 release SM9 digitial signature scheme is finished and tested. --- crypto/sm9/sm9_keygen.c | 56 ++++++++++++++++++++++++++++++++++++++++- crypto/sm9/sm9_lcl.h | 2 ++ crypto/sm9/sm9_rate.c | 12 ++++----- crypto/sm9/sm9_setup.c | 3 ++- crypto/sm9/sm9_sign.c | 39 +++++++++++++++------------- test/sm9test.c | 11 ++++---- 6 files changed, 93 insertions(+), 30 deletions(-) diff --git a/crypto/sm9/sm9_keygen.c b/crypto/sm9/sm9_keygen.c index ef7d42e8..2dba0a84 100644 --- a/crypto/sm9/sm9_keygen.c +++ b/crypto/sm9/sm9_keygen.c @@ -54,7 +54,7 @@ #include #include "sm9_lcl.h" - +#if 0 int SM9_hash1(const EVP_MD *md, BIGNUM **r, const char *id, size_t idlen, unsigned char hid, @@ -77,6 +77,59 @@ int SM9_hash1(const EVP_MD *md, BIGNUM **r, OPENSSL_free(buf); return 1; } +#endif + +int SM9_hash1(const EVP_MD *md, BIGNUM **r, const char *id, size_t idlen, + unsigned char hid, const BIGNUM *n, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *h = NULL; + BN_CTX *bn_ctx = NULL; + EVP_MD_CTX *ctx1 = NULL; + EVP_MD_CTX *ctx2 = NULL; + unsigned char prefix[1] = {0x01}; + unsigned char ct1[4] = {0x00, 0x00, 0x00, 0x01}; + unsigned char ct2[4] = {0x00, 0x00, 0x00, 0x02}; + unsigned char buf[128]; + unsigned int len; + + if (!(ctx1 = EVP_MD_CTX_new()) + || !(ctx2 = EVP_MD_CTX_new()) + || !(bn_ctx = BN_CTX_new()) + || !(h = BN_new())) { + goto end; + } + + if (!EVP_DigestInit_ex(ctx1, md, NULL) + || !EVP_DigestUpdate(ctx1, prefix, sizeof(prefix)) + || !EVP_DigestUpdate(ctx1, id, idlen) + || !EVP_DigestUpdate(ctx1, &hid, 1) + || !EVP_MD_CTX_copy(ctx2, ctx1) + || !EVP_DigestUpdate(ctx1, ct1, sizeof(ct1)) + || !EVP_DigestUpdate(ctx2, ct2, sizeof(ct2)) + || !EVP_DigestFinal_ex(ctx1, buf, &len) + || !EVP_DigestFinal_ex(ctx2, buf + len, &len)) { + goto end; + } + + if (!BN_bin2bn(buf, 40, h) + || !BN_mod(h, h, SM9_get0_order_minus_one(), bn_ctx) + || !BN_add_word(h, 1)) { + goto end; + } + + *r = h; + h = NULL; + ret = 1; + +end: + BN_free(h); + BN_CTX_free(bn_ctx); + EVP_MD_CTX_free(ctx1); + EVP_MD_CTX_free(ctx2); + return ret; +} + SM9PrivateKey *SM9_extract_private_key(SM9MasterSecret *msk, const char *id, size_t idlen) @@ -155,6 +208,7 @@ SM9PrivateKey *SM9_extract_private_key(SM9MasterSecret *msk, SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_SM9_LIB); goto end; } + if (!BN_mod_add(t, t, msk->masterSecret, n, ctx)) { SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_BN_LIB); goto end; diff --git a/crypto/sm9/sm9_lcl.h b/crypto/sm9/sm9_lcl.h index c5826797..cf821e06 100644 --- a/crypto/sm9/sm9_lcl.h +++ b/crypto/sm9/sm9_lcl.h @@ -154,10 +154,12 @@ int fp12_init(fp12_t a, BN_CTX *ctx); int fp12_mul(fp12_t r, const fp12_t a, const fp12_t b, const BIGNUM *p, BN_CTX *ctx); int fp12_pow(fp12_t r, const fp12_t a, const BIGNUM *k, const BIGNUM *p, BN_CTX *ctx); int fp12_to_bin(const fp12_t a, unsigned char to[384]); +int fp12_print(const fp12_t a); void fp12_cleanup(fp12_t a); int point_init(point_t *P, BN_CTX *ctx); int point_copy(point_t *R, const point_t *P); +void point_print(const point_t *P); int point_equ(const point_t *P, const point_t *Q); int point_is_on_curve(point_t *P, const BIGNUM *p, BN_CTX *ctx); int point_to_octets(const point_t *P, unsigned char to[129], BN_CTX *ctx); diff --git a/crypto/sm9/sm9_rate.c b/crypto/sm9/sm9_rate.c index 95ebcd5f..f89e8253 100644 --- a/crypto/sm9/sm9_rate.c +++ b/crypto/sm9/sm9_rate.c @@ -414,15 +414,15 @@ static int fp2_div(fp2_t r, const fp2_t a, const fp2_t b, const BIGNUM *p, BN_CT static int fp2_to_bin(const fp2_t a, unsigned char to[64]) { memset(to, 0, 64); - BN_bn2bin(a[0], to + 32 - BN_num_bytes(a[0])); - BN_bn2bin(a[1], to + 64 - BN_num_bytes(a[1])); + BN_bn2bin(a[1], to + 32 - BN_num_bytes(a[1])); + BN_bn2bin(a[0], to + 64 - BN_num_bytes(a[0])); return 1; } static int fp2_from_bin(fp2_t a, const unsigned char from[64]) { - return BN_bin2bn(from, 32, a[0]) - && BN_bin2bn(from + 32, 32, a[1]); + return BN_bin2bn(from, 32, a[1]) + && BN_bin2bn(from + 32, 32, a[0]); } static int fp2_test(const BIGNUM *p, BN_CTX *ctx) @@ -1007,7 +1007,7 @@ static void fp12_clear_cleanup(fp12_t a) fp4_clear_cleanup(a[2]); } -static int fp12_print(const fp12_t a) +int fp12_print(const fp12_t a) { fp4_print(a[0]); fp4_print(a[1]); @@ -1734,7 +1734,7 @@ void point_cleanup(point_t *P) fp2_cleanup(P->Z); } -static void point_print(const point_t *P) +void point_print(const point_t *P) { printf(" X1: %s\n", BN_bn2hex((P->X)[1])); printf(" X0: %s\n", BN_bn2hex((P->X)[0])); diff --git a/crypto/sm9/sm9_setup.c b/crypto/sm9/sm9_setup.c index 9309e9c4..49577fd5 100644 --- a/crypto/sm9/sm9_setup.c +++ b/crypto/sm9/sm9_setup.c @@ -118,7 +118,8 @@ SM9MasterSecret *SM9_generate_master_secret(int pairing, int scheme, int hash1) /* generate master secret k = rand(1, n - 1) */ do { if (!BN_rand_range(msk->masterSecret, n)) { - return 0; + SM9err(SM9_F_SM9_GENERATE_MASTER_SECRET, ERR_R_BN_LIB); + goto end; } } while (BN_is_zero(msk->masterSecret)); diff --git a/crypto/sm9/sm9_sign.c b/crypto/sm9/sm9_sign.c index 2abaa403..684e80b4 100644 --- a/crypto/sm9/sm9_sign.c +++ b/crypto/sm9/sm9_sign.c @@ -63,13 +63,13 @@ int SM9_signature_size(SM9PublicParameters *mpk) int SM9_SignInit(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *eng) { - unsigned char prefix = 0x02; + unsigned char prefix[1] = {0x02}; if (!EVP_DigestInit_ex(ctx, md, eng)) { SM9err(SM9_F_SM9_SIGNINIT, ERR_R_EVP_LIB); return 0; } - if (!EVP_DigestUpdate(ctx, &prefix, 1)) { + if (!EVP_DigestUpdate(ctx, prefix, sizeof(prefix))) { SM9err(SM9_F_SM9_SIGNINIT, ERR_R_EVP_LIB); return 0; } @@ -85,10 +85,10 @@ SM9Signature *SM9_SignFinal(EVP_MD_CTX *ctx1, SM9PrivateKey *sk) const BIGNUM *n = SM9_get0_order(); int point_form = POINT_CONVERSION_COMPRESSED; /* buf for w and prefix zeros of ct1/2 */ - unsigned char buf[387] = {0}; + unsigned char buf[384] = {0}; unsigned int len; - const unsigned char ct1 = 0x01; - const unsigned char ct2 = 0x02; + const unsigned char ct1[4] = {0x00, 0x00, 0x00, 0x01}; + const unsigned char ct2[4] = {0x00, 0x00, 0x00, 0x02}; EVP_MD_CTX *ctx2 = NULL; EC_GROUP *group = NULL; EC_POINT *S = NULL; @@ -145,10 +145,10 @@ SM9Signature *SM9_SignFinal(EVP_MD_CTX *ctx1, SM9PrivateKey *sk) if (!EVP_DigestUpdate(ctx1, buf, sizeof(buf)) || !EVP_MD_CTX_copy(ctx2, ctx1) /* Ha1 = Hv(0x02||M||w||0x00000001) */ - || !EVP_DigestUpdate(ctx1, &ct1, 1) - || !EVP_DigestFinal_ex(ctx1, buf, &len) + || !EVP_DigestUpdate(ctx1, ct1, sizeof(ct1)) /* Ha2 = Hv(0x02||M||w||0x00000002) */ - || !EVP_DigestUpdate(ctx2, &ct2, 1) + || !EVP_DigestUpdate(ctx2, ct2, sizeof(ct2)) + || !EVP_DigestFinal_ex(ctx1, buf, &len) || !EVP_DigestFinal_ex(ctx2, buf + len, &len)) { SM9err(SM9_F_SM9_SIGNFINAL, SM9_R_DIGEST_FAILURE); goto end; @@ -159,8 +159,8 @@ SM9Signature *SM9_SignFinal(EVP_MD_CTX *ctx1, SM9PrivateKey *sk) /* h = (Ha mod (n - 1)) + 1 */ || !BN_mod(sig->h, sig->h, SM9_get0_order_minus_one(), bn_ctx) || !BN_add_word(sig->h, 1) - /* l = r - h */ - || !BN_mod_sub(r, r, sig->h, p, bn_ctx)) { + /* l = r - h (mod n) */ + || !BN_mod_sub(r, r, sig->h, n, bn_ctx)) { SM9err(SM9_F_SM9_SIGNFINAL, ERR_R_BN_LIB); goto end; } @@ -197,13 +197,13 @@ end: int SM9_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *eng) { - unsigned char prefix = 0x02; + unsigned char prefix[1] = {0x02}; if (!EVP_DigestInit_ex(ctx, md, eng)) { SM9err(SM9_F_SM9_VERIFYINIT, ERR_R_EVP_LIB); return 0; } - if (!EVP_DigestUpdate(ctx, &prefix, 1)) { + if (!EVP_DigestUpdate(ctx, prefix, sizeof(prefix))) { SM9err(SM9_F_SM9_VERIFYINIT, ERR_R_EVP_LIB); return 0; } @@ -228,10 +228,10 @@ int SM9_VerifyFinal(EVP_MD_CTX *ctx1, const SM9Signature *sig, SM9PublicKey *pk) const BIGNUM *p = SM9_get0_prime(); const BIGNUM *n = SM9_get0_order(); const EVP_MD *md; - unsigned char buf[387] = {0}; + unsigned char buf[384] = {0}; unsigned int len; - const unsigned char ct1 = 0x01; - const unsigned char ct2 = 0x02; + const unsigned char ct1[4] = {0x00, 0x00, 0x00, 0x01}; + const unsigned char ct2[4] = {0x00, 0x00, 0x00, 0x02}; EVP_MD_CTX *ctx2 = NULL; EC_GROUP *group = NULL; EC_POINT *S = NULL; @@ -314,9 +314,9 @@ int SM9_VerifyFinal(EVP_MD_CTX *ctx1, const SM9Signature *sig, SM9PublicKey *pk) if (!EVP_DigestUpdate(ctx1, buf, sizeof(buf)) || !EVP_MD_CTX_copy(ctx2, ctx1) /* Ha1 = Hv(0x02||M||w||0x00000001) */ - || !EVP_DigestUpdate(ctx1, &ct1, 1) + || !EVP_DigestUpdate(ctx1, ct1, sizeof(ct1)) /* Ha2 = Hv(0x02||M||w||0x00000002) */ - || !EVP_DigestUpdate(ctx2, &ct2, 1) + || !EVP_DigestUpdate(ctx2, ct2, sizeof(ct2)) || !EVP_DigestFinal_ex(ctx1, buf, &len) || !EVP_DigestFinal_ex(ctx2, buf + len, &len)) { SM9err(SM9_F_SM9_VERIFYFINAL, SM9_R_DIGEST_FAILURE); @@ -337,6 +337,7 @@ int SM9_VerifyFinal(EVP_MD_CTX *ctx1, const SM9Signature *sig, SM9PublicKey *pk) ret = 0; } + ret = 1; end: @@ -426,6 +427,10 @@ int SM9_verify(int type, /* NID_[sm3 | sha256] */ goto end; } + if (!(ctx = EVP_MD_CTX_new())) { + SM9err(SM9_F_SM9_VERIFY, ERR_R_MALLOC_FAILURE); + goto end; + } if (!SM9_VerifyInit(ctx, md, NULL) || !SM9_VerifyUpdate(ctx, data, datalen) || (ret = SM9_VerifyFinal(ctx, sm9sig, pk)) < 0) { diff --git a/test/sm9test.c b/test/sm9test.c index 4c460dcf..d8c58089 100644 --- a/test/sm9test.c +++ b/test/sm9test.c @@ -80,15 +80,16 @@ static int sm9test_sign(const char *id, const unsigned char *msg, size_t msglen) ERR_print_errors_fp(stderr); goto end; } - if (!SM9_sign(NID_sm3, msg, sizeof(msg), sig, &siglen, sk)) { + if (!SM9_sign(NID_sm3, msg, msglen, sig, &siglen, sk)) { ERR_print_errors_fp(stderr); goto end; } - if (1 != SM9_verify(NID_sm3, msg, sizeof(msg), sig, siglen, mpk, id, strlen(id))) { + if (1 != SM9_verify(NID_sm3, msg, msglen, sig, siglen, mpk, id, strlen(id))) { ERR_print_errors_fp(stderr); goto end; } - + + printf("sm9test_sign() success\n"); ret = 1; end: SM9PublicParameters_free(mpk); @@ -143,10 +144,10 @@ int main(int argc, char **argv) char *id = "guanzhi1980@gmail.com"; unsigned char in[] = "message to be signed or encrypted"; - if (!sm9test_sign(id, in, sizeof(in))) { + if (!sm9test_sign(id, in, sizeof(in)-1)) { err++; } - if (!sm9test_enc(id, in, sizeof(in))) { + if (!sm9test_enc(id, in, sizeof(in)-1)) { err++; }