From: Liu-Ermeng Date: Mon, 8 Jan 2024 04:01:29 +0000 (-0800) Subject: fix sm2 encryption implementation bug. X-Git-Tag: openssl-3.1.6~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fa03085f26f4c08164f1eea21d0cdc1beb89b38c;p=thirdparty%2Fopenssl.git fix sm2 encryption implementation bug. According to the "GB/T 32918.4-2016" section 6.1 encryption, step A5: If result of the "KDF" is all zeros, we should go back to the begin(step A1). section 7.1 decryption, step B4: If result of the "KDF" is all zeros, we should raise error and exit. Signed-off-by: Liu-Ermeng Reviewed-by: Neil Horman Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/23210) (cherry picked from commit 170620675dfd74f34bdcf8aba71dffeb07f3d533) --- diff --git a/crypto/sm2/sm2_crypt.c b/crypto/sm2/sm2_crypt.c index 5318c6199f6..0e3f2d975d7 100644 --- a/crypto/sm2/sm2_crypt.c +++ b/crypto/sm2/sm2_crypt.c @@ -67,6 +67,18 @@ static size_t ec_field_size(const EC_GROUP *group) return field_size; } +static int is_all_zeros(const unsigned char *msg, size_t msglen) +{ + unsigned char re = 0; + size_t i; + + for (i = 0; i < msglen; i++) { + re |= msg[i]; + } + + return re == 0 ? 1 : 0; +} + int ossl_sm2_plaintext_size(const unsigned char *ct, size_t ct_size, size_t *pt_size) { @@ -179,6 +191,13 @@ int ossl_sm2_encrypt(const EC_KEY *key, memset(ciphertext_buf, 0, *ciphertext_len); + msg_mask = OPENSSL_zalloc(msg_len); + if (msg_mask == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + goto done; + } + +again: if (!BN_priv_rand_range_ex(k, order, 0, ctx)) { ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; @@ -198,12 +217,6 @@ int ossl_sm2_encrypt(const EC_KEY *key, goto done; } - msg_mask = OPENSSL_zalloc(msg_len); - if (msg_mask == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); - goto done; - } - /* X9.63 with no salt happens to match the KDF used in SM2 */ if (!ossl_ecdh_kdf_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, digest, libctx, propq)) { @@ -211,6 +224,11 @@ int ossl_sm2_encrypt(const EC_KEY *key, goto done; } + if (is_all_zeros(msg_mask, msg_len)) { + memset(x2y2, 0, 2 * field_size); + goto again; + } + for (i = 0; i != msg_len; ++i) msg_mask[i] ^= msg[i]; @@ -364,6 +382,11 @@ int ossl_sm2_decrypt(const EC_KEY *key, goto done; } + if (is_all_zeros(msg_mask, msg_len)) { + ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_ENCODING); + goto done; + } + for (i = 0; i != msg_len; ++i) ptext_buf[i] = C2[i] ^ msg_mask[i];