Validate the SM2 digest len before use
[openssl.git] / crypto / sm2 / sm2_pmeth.c
index aed7f33044575bbdca9444daae815c1f3723d4ec..d187699cc411705042b4ee1029050b7745438a16 100644 (file)
@@ -72,6 +72,7 @@ static int pkey_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
     if (sctx->id != NULL) {
         dctx->id = OPENSSL_malloc(sctx->id_len);
         if (dctx->id == NULL) {
+            SM2err(SM2_F_PKEY_SM2_COPY, ERR_R_MALLOC_FAILURE);
             pkey_sm2_cleanup(dst);
             return 0;
         }
@@ -163,6 +164,7 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
 {
     SM2_PKEY_CTX *smctx = ctx->data;
     EC_GROUP *group;
+    uint8_t *tmp_id;
 
     switch (type) {
     case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
@@ -192,14 +194,18 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
         return 1;
 
     case EVP_PKEY_CTRL_SET1_ID:
-        OPENSSL_free(smctx->id);
         if (p1 > 0) {
-            smctx->id = OPENSSL_malloc(p1);
-            if (smctx->id == NULL)
+            tmp_id = OPENSSL_malloc(p1);
+            if (tmp_id == NULL) {
+                SM2err(SM2_F_PKEY_SM2_CTRL, ERR_R_MALLOC_FAILURE);
                 return 0;
-            memcpy(smctx->id, p2, p1);
+            }
+            memcpy(tmp_id, p2, p1);
+            OPENSSL_free(smctx->id);
+            smctx->id = tmp_id;
         } else {
             /* set null-ID */
+            OPENSSL_free(smctx->id);
             smctx->id = NULL;
         }
         smctx->id_len = (size_t)p1;
@@ -253,6 +259,7 @@ static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
     SM2_PKEY_CTX *smctx = ctx->data;
     EC_KEY *ec = ctx->pkey->pkey.ec;
     const EVP_MD *md = EVP_MD_CTX_md(mctx);
+    int mdlen = EVP_MD_size(md);
 
     if (!smctx->id_set) {
         /*
@@ -260,6 +267,12 @@ static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
          * NULL is allowed. We only allow it if set explicitly for maximum
          * flexibility.
          */
+        SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_ID_NOT_SET);
+        return 0;
+    }
+
+    if (mdlen < 0) {
+        SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_INVALID_DIGEST);
         return 0;
     }
 
@@ -267,7 +280,7 @@ static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
     if (!sm2_compute_z_digest(z, md, smctx->id, smctx->id_len, ec))
         return 0;
 
-    return EVP_DigestUpdate(mctx, z, EVP_MD_size(md));
+    return EVP_DigestUpdate(mctx, z, (size_t)mdlen);
 }
 
 const EVP_PKEY_METHOD sm2_pkey_meth = {