Commit 71996a34db for openssl.org

commit 71996a34db7f02e747ee83e24a5f83c03ff4f5b0
Author: Billy Brumley <bbb@iki.fi>
Date:   Tue Oct 6 02:41:53 2026 -0400

    Reject encryption and decryption on unkeyed AEAD contexts

    ChaCha20-Poly1305 and AES-GCM-SIV completed operations on a context that
    had never been given a key, producing ciphertext and a tag under the
    all-zero key with no error. This fix makes the rejection behavior
    consistent across all AEADs.

    Assisted-by: Claude:claude-fable-5-1
    Reviewed-by: Richard Levitte <levitte@openssl.foundation>
    Reviewed-by: Andrew Dinh <andrewd@openssl.org>
    Reviewed-by: Neil Horman <nhorman@openssl.org>
    Merge-date: Sun Nov  8 21:43:11 2026
    Merged-from: https://github.com/openssl/openssl/pull/33116

diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv.c b/providers/implementations/ciphers/cipher_aes_gcm_siv.c
index 560dd239bd..84c722b63d 100644
--- a/providers/implementations/ciphers/cipher_aes_gcm_siv.c
+++ b/providers/implementations/ciphers/cipher_aes_gcm_siv.c
@@ -125,7 +125,8 @@ static int ossl_aes_gcm_siv_init(void *vctx, const unsigned char *key, size_t ke
         memcpy(ctx->nonce, iv, sizeof(ctx->nonce));
     }

-    if (!ctx->hw->initkey(ctx))
+    /* only initialize state if we have a key */
+    if ((key != NULL || ctx->ecb_ctx != NULL) && ctx->hw->initkey(ctx) == 0)
         return 0;

     return ossl_aes_gcm_siv_set_ctx_params(ctx, params);
diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c
index d38c508bb9..05106679b8 100644
--- a/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c
+++ b/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c
@@ -284,6 +284,11 @@ static int aes_gcm_siv_cipher(void *vctx, unsigned char *out,
 {
     PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx;

+    if (ctx->ecb_ctx == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
+        return 0;
+    }
+
     /* EncryptFinal or DecryptFinal */
     if (in == NULL)
         return aes_gcm_siv_finish(ctx);
diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.c b/providers/implementations/ciphers/cipher_chacha20_poly1305.c
index d813cf28da..af8743cc39 100644
--- a/providers/implementations/ciphers/cipher_chacha20_poly1305.c
+++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.c
@@ -291,6 +291,11 @@ static int chacha20_poly1305_cipher(void *vctx, unsigned char *out,
     if (!ossl_prov_is_running())
         return 0;

+    if (!ctx->key_set) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
+        return 0;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return 0;
@@ -337,6 +342,11 @@ static int chacha20_poly1305_final(void *vctx, unsigned char *out, size_t *outl,
     if (!ossl_prov_is_running())
         return 0;

+    if (!ctx->base.key_set) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
+        return 0;
+    }
+
     /* The tag must be set before actually decrypting data */
     if (!ctx->base.enc && ctx->tag_len == 0) {
         ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_SET);