]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
fix sm2 encryption implementation bug.
authorLiu-Ermeng <liuermeng2@huawei.com>
Mon, 8 Jan 2024 04:01:29 +0000 (20:01 -0800)
committerTomas Mraz <tomas@openssl.org>
Wed, 15 May 2024 09:20:26 +0000 (11:20 +0200)
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 <liuermeng2@huawei.com>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23210)

(cherry picked from commit 170620675dfd74f34bdcf8aba71dffeb07f3d533)

crypto/sm2/sm2_crypt.c

index 5318c6199f68018f64772356e19ff9d29d107252..0e3f2d975d757196caf03486fb8f5c1ed08d7de1 100644 (file)
@@ -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];