From d6a8adeccdb8188517c5a84d35b79ef826176472 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 18 Mar 2024 14:59:32 -0400 Subject: [PATCH] Add check for public key presence on sm2 signing SM2 requires that the public EC_POINT be present in a key when signing. If its not there we crash on a NULL pointer. Add a check to ensure that its present, and raise an error if its not Reviewed-by: Paul Yang Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/23887) --- crypto/sm2/sm2_sign.c | 9 ++++++++- test/sm2_internal_test.c | 39 +++++++++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/crypto/sm2/sm2_sign.c b/crypto/sm2/sm2_sign.c index 1b3ca94d6e..1ffbb171fa 100644 --- a/crypto/sm2/sm2_sign.c +++ b/crypto/sm2/sm2_sign.c @@ -28,6 +28,7 @@ int ossl_sm2_compute_z_digest(uint8_t *out, { int rc = 0; const EC_GROUP *group = EC_KEY_get0_group(key); + const EC_POINT *pubkey = EC_KEY_get0_public_key(key); BN_CTX *ctx = NULL; EVP_MD_CTX *hash = NULL; BIGNUM *p = NULL; @@ -42,6 +43,12 @@ int ossl_sm2_compute_z_digest(uint8_t *out, uint16_t entl = 0; uint8_t e_byte = 0; + /* SM2 Signatures require a public key, check for it */ + if (pubkey == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_PASSED_NULL_PARAMETER); + goto done; + } + hash = EVP_MD_CTX_new(); if (hash == NULL) { ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); @@ -119,7 +126,7 @@ int ossl_sm2_compute_z_digest(uint8_t *out, || BN_bn2binpad(yG, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || !EC_POINT_get_affine_coordinates(group, - EC_KEY_get0_public_key(key), + pubkey, xA, yA, ctx) || BN_bn2binpad(xA, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) diff --git a/test/sm2_internal_test.c b/test/sm2_internal_test.c index 2d91827749..69665e7c1b 100644 --- a/test/sm2_internal_test.c +++ b/test/sm2_internal_test.c @@ -305,7 +305,8 @@ static int test_sm2_sign(const EC_GROUP *group, const char *message, const char *k_hex, const char *r_hex, - const char *s_hex) + const char *s_hex, + int omit_pubkey) { const size_t msg_len = strlen(message); int ok = 0; @@ -327,11 +328,13 @@ static int test_sm2_sign(const EC_GROUP *group, || !TEST_true(EC_KEY_set_private_key(key, priv))) goto done; - pt = EC_POINT_new(group); - if (!TEST_ptr(pt) - || !TEST_true(EC_POINT_mul(group, pt, priv, NULL, NULL, NULL)) - || !TEST_true(EC_KEY_set_public_key(key, pt))) - goto done; + if (omit_pubkey == 0) { + pt = EC_POINT_new(group); + if (!TEST_ptr(pt) + || !TEST_true(EC_POINT_mul(group, pt, priv, NULL, NULL, NULL)) + || !TEST_true(EC_KEY_set_public_key(key, pt))) + goto done; + } start_fake_rand(k_hex); sig = ossl_sm2_do_sign(key, EVP_sm3(), (const uint8_t *)userid, @@ -393,7 +396,7 @@ static int sm2_sig_test(void) "006CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F" "007c47811054c6f99613a578eb8453706ccb96384fe7df5c171671e760bfa8be3a", "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1", - "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7"))) + "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7", 0))) goto done; /* From Annex A in both GM/T0003.5-2012 and GB/T 32918.5-2016.*/ @@ -424,7 +427,27 @@ static int sm2_sig_test(void) /* signature R, 0x20 bytes */ "F5A03B0648D2C4630EEAC513E1BB81A15944DA3827D5B74143AC7EACEEE720B3", /* signature S, 0x20 bytes */ - "B1B6AA29DF212FD8763182BC0D421CA1BB9038FD1F7F42D4840B69C485BBC1AA"))) + "B1B6AA29DF212FD8763182BC0D421CA1BB9038FD1F7F42D4840B69C485BBC1AA", 0))) + goto done; + + + /* Make sure we fail if we omit the public portion of the key */ + if (!TEST_false(test_sm2_sign( + gm_group, + /* the default ID specified in GM/T 0009-2012 (Sec. 10).*/ + SM2_DEFAULT_USERID, + /* privkey */ + "3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8", + /* plaintext message */ + "message digest", + /* ephemeral nonce k */ + "59276E27D506861A16680F3AD9C02DCCEF3CC1FA3CDBE4CE6D54B80DEAC1BC21", + /* expected signature, the field values are from GM/T 0003.5-2012, + Annex A. */ + /* signature R, 0x20 bytes */ + "F5A03B0648D2C4630EEAC513E1BB81A15944DA3827D5B74143AC7EACEEE720B3", + /* signature S, 0x20 bytes */ + "B1B6AA29DF212FD8763182BC0D421CA1BB9038FD1F7F42D4840B69C485BBC1AA", 1))) goto done; testresult = 1;