]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
poly1305: prevent crash on final without a key
author007bsd <22483432+007bsd@users.noreply.github.com>
Tue, 26 May 2026 18:11:27 +0000 (21:11 +0300)
committerNorbert Pocs <norbertp@openssl.org>
Mon, 1 Jun 2026 07:34:47 +0000 (09:34 +0200)
EVP_MAC_init with a NULL key followed by EVP_MAC_final on a
Poly1305 context crashed with a NULL function-pointer dispatch
because poly1305_init accepted the no-key case as success, and
poly1305_final had no guard before dispatching through the
uninitialised Poly1305 state.

Add a key_set field to struct poly1305_data_st (matching
OCB/CCM/GCM), set it in poly1305_setkey, and refuse init and
final if no key has been installed.

Added a regression test asserting EVP_MAC_init with a NULL key
returns 0.

##### Checklist
- [ ] documentation is added or updated
- [x] tests are added or updated

CLA: trivial

Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
MergeDate: Mon Jun  1 07:35:02 2026
(Merged from https://github.com/openssl/openssl/pull/31298)

providers/implementations/macs/poly1305_prov.c
test/evp_extra_test.c

index cfa59b2b492f51105dc7a54dc6021d6487337404..8d6f9c952e9d9d146637aa75b274d28b75060917 100644 (file)
@@ -42,6 +42,7 @@ static OSSL_FUNC_mac_final_fn poly1305_final;
 struct poly1305_data_st {
     void *provctx;
     int updated;
+    int key_set;
     POLY1305 poly1305; /* Poly1305 data */
 };
 
@@ -91,6 +92,7 @@ static int poly1305_setkey(struct poly1305_data_st *ctx,
     }
     Poly1305_Init(&ctx->poly1305, key);
     ctx->updated = 0;
+    ctx->key_set = 1;
     return 1;
 }
 
@@ -129,6 +131,10 @@ static int poly1305_final(void *vmacctx, unsigned char *out, size_t *outl,
 
     if (!ossl_prov_is_running())
         return 0;
+    if (!ctx->key_set) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
+        return 0;
+    }
     ctx->updated = 1;
     Poly1305_Final(&ctx->poly1305, out);
     *outl = poly1305_size();
index 7242166e767d8b2b65209d9f8dc59914f42b8f68..2ca066926577479bad21af29aeab051cd6e9abdc 100644 (file)
@@ -2322,6 +2322,29 @@ out:
     return ret;
 }
 
+#ifndef OPENSSL_NO_POLY1305
+/* Test that EVP_MAC_final fails for Poly1305 when no key was set */
+static int test_evp_mac_poly1305_no_key(void)
+{
+    int ret = 0;
+    EVP_MAC *mac = NULL;
+    EVP_MAC_CTX *ctx = NULL;
+    unsigned char out[16];
+    size_t outl = 0;
+
+    if (!TEST_ptr(mac = EVP_MAC_fetch(testctx, "Poly1305", testpropq))
+        || !TEST_ptr(ctx = EVP_MAC_CTX_new(mac))
+        || !TEST_int_eq(EVP_MAC_init(ctx, NULL, 0, NULL), 1)
+        || !TEST_int_eq(EVP_MAC_final(ctx, out, &outl, sizeof(out)), 0))
+        goto err;
+    ret = 1;
+err:
+    EVP_MAC_CTX_free(ctx);
+    EVP_MAC_free(mac);
+    return ret;
+}
+#endif
+
 static int test_d2i_AutoPrivateKey(int i)
 {
     int ret = 0;
@@ -7994,6 +8017,9 @@ int setup_tests(void)
 #endif
     ADD_TEST(test_EVP_Digest);
     ADD_TEST(test_EVP_md_null);
+#ifndef OPENSSL_NO_POLY1305
+    ADD_TEST(test_evp_mac_poly1305_no_key);
+#endif
     ADD_ALL_TESTS(test_EVP_PKEY_sign, 3);
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     ADD_ALL_TESTS(test_EVP_PKEY_sign_with_app_method, 2);