]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
evp-cmac: do not seg-fault when getting mac-size before init
authorJames Muir <james@openssl.org>
Wed, 29 Nov 2023 03:43:52 +0000 (22:43 -0500)
committerTomas Mraz <tomas@openssl.org>
Fri, 1 Dec 2023 10:54:51 +0000 (11:54 +0100)
Add null check to cmac_size().  This avoids a seg-fault encountered
with cmac when EVP_MAC_CTX_get_mac_size() is called before init.

Extend mac testing in evp_test.c to check that the sizes returned by
EVP_MAC_CTX_get_mac_size() before and after init make sense (this also
ensures that we no longer seg-fault).

Fixes #22842

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22858)

providers/implementations/macs/cmac_prov.c
test/evp_test.c

index 1b3893598d888b9b128ba750a80ea45361fc5c45..fa0b576b97123d0579e83eb131f474c31b7c6750 100644 (file)
@@ -101,8 +101,12 @@ static void *cmac_dup(void *vsrc)
 static size_t cmac_size(void *vmacctx)
 {
     struct cmac_data_st *macctx = vmacctx;
+    const EVP_CIPHER_CTX *cipherctx = CMAC_CTX_get0_cipher_ctx(macctx->ctx);
 
-    return EVP_CIPHER_CTX_get_block_size(CMAC_CTX_get0_cipher_ctx(macctx->ctx));
+    if (EVP_CIPHER_CTX_get0_cipher(cipherctx) == NULL)
+        return 0;
+
+    return EVP_CIPHER_CTX_get_block_size(cipherctx);
 }
 
 static int cmac_setkey(struct cmac_data_st *macctx,
index d74da09616c502702512111e9649564326f0285f..cef7b1b9e83bcf7dc7082314528d7a94012609b7 100644 (file)
@@ -1514,6 +1514,7 @@ static int mac_test_run_mac(EVP_TEST *t)
     EVP_MAC_CTX *ctx = NULL;
     unsigned char *got = NULL;
     size_t got_len = 0, size = 0;
+    size_t size_before_init, size_after_init, size_val = 0;
     int i, block_size = -1, output_size = -1;
     OSSL_PARAM params[21], sizes[3], *psizes = sizes;
     size_t params_n = 0;
@@ -1610,6 +1611,9 @@ static int mac_test_run_mac(EVP_TEST *t)
         }
         params_n++;
 
+        if (strcmp(tmpkey, "size") == 0)
+            size_val = (size_t)strtoul(tmpval, NULL, 0);
+
         OPENSSL_free(tmpkey);
     }
     params[params_n] = OSSL_PARAM_construct_end();
@@ -1618,11 +1622,28 @@ static int mac_test_run_mac(EVP_TEST *t)
         t->err = "MAC_CREATE_ERROR";
         goto err;
     }
-
+    size_before_init = EVP_MAC_CTX_get_mac_size(ctx);
     if (!EVP_MAC_init(ctx, expected->key, expected->key_len, params)) {
         t->err = "MAC_INIT_ERROR";
         goto err;
     }
+    size_after_init = EVP_MAC_CTX_get_mac_size(ctx);
+    if (!TEST_false(size_before_init == 0 && size_after_init == 0)) {
+        t->err = "MAC SIZE not set";
+        goto err;
+    }
+    if (size_before_init != 0) {
+        /* mac-size not modified by init params */
+        if (size_val == 0 && !TEST_size_t_eq(size_before_init, size_after_init)) {
+            t->err = "MAC SIZE check failed";
+            goto err;
+        }
+        /* mac-size modified by init params */
+        if (size_val != 0 && !TEST_size_t_eq(size_val, size_after_init)) {
+            t->err = "MAC SIZE check failed";
+            goto err;
+        }
+    }
     if (expected->output_size >= 0)
         *psizes++ = OSSL_PARAM_construct_int(OSSL_MAC_PARAM_SIZE,
                                              &output_size);