Commit 07485b844a for openssl.org
commit 07485b844a0689354c2c17163604860a82d281bb
Author: 007bsd <22483432+007bsd@users.noreply.github.com>
Date: Tue May 26 21:11:27 2026 +0300
poly1305: prevent crash on final without a key
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)
diff --git a/providers/implementations/macs/poly1305_prov.c b/providers/implementations/macs/poly1305_prov.c
index cfa59b2b49..8d6f9c952e 100644
--- a/providers/implementations/macs/poly1305_prov.c
+++ b/providers/implementations/macs/poly1305_prov.c
@@ -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();
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 7242166e76..2ca0669265 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -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);