|
|
@@ -0,0 +1,62 @@
|
|
|
+From: Felix Fietkau <[email protected]>
|
|
|
+Date: Mon, 1 Dec 2025 16:22:17 +0000
|
|
|
+Subject: [PATCH] providers/implementations/ciphers: fix AES-GCM-SIV and
|
|
|
+ AES-SIV with zero-length messages
|
|
|
+
|
|
|
+When ossl_aes_gcm_siv_cipher() or siv_cipher() is called with in=NULL
|
|
|
+for zero-length input, the hw->cipher function interprets this as a
|
|
|
+finalization request and calls the finish function instead of
|
|
|
+encrypt/decrypt. This causes the authentication tag to never be computed
|
|
|
+for zero-length messages, resulting in decryption verification failures.
|
|
|
+
|
|
|
+Fix this by substituting a static empty byte address when in is NULL,
|
|
|
+ensuring hw->cipher always receives a non-NULL pointer from Update calls
|
|
|
+and correctly routes to the encrypt/decrypt path.
|
|
|
+
|
|
|
+For AES-GCM-SIV, this is a different fix than upstream commit
|
|
|
+f1a4f0368b73 ("make aes-gcm-siv work with zero-length messages") which
|
|
|
+removed early-return and length checks that don't exist in 3.5.x.
|
|
|
+
|
|
|
+Signed-off-by: Felix Fietkau <[email protected]>
|
|
|
+
|
|
|
+---
|
|
|
+--- a/providers/implementations/ciphers/cipher_aes_gcm_siv.c
|
|
|
++++ b/providers/implementations/ciphers/cipher_aes_gcm_siv.c
|
|
|
+@@ -140,6 +140,7 @@ static int ossl_aes_gcm_siv_cipher(void
|
|
|
+ {
|
|
|
+ PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx;
|
|
|
+ int error = 0;
|
|
|
++ static const unsigned char empty;
|
|
|
+
|
|
|
+ if (!ossl_prov_is_running())
|
|
|
+ return 0;
|
|
|
+@@ -149,6 +150,9 @@ static int ossl_aes_gcm_siv_cipher(void
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
++ if (in == NULL)
|
|
|
++ in = ∅
|
|
|
++
|
|
|
+ error |= !ctx->hw->cipher(ctx, out, in, inl);
|
|
|
+
|
|
|
+ if (outl != NULL && !error)
|
|
|
+--- a/providers/implementations/ciphers/cipher_aes_siv.c
|
|
|
++++ b/providers/implementations/ciphers/cipher_aes_siv.c
|
|
|
+@@ -114,6 +114,7 @@ static int siv_cipher(void *vctx, unsign
|
|
|
+ size_t outsize, const unsigned char *in, size_t inl)
|
|
|
+ {
|
|
|
+ PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
|
|
|
++ static const unsigned char empty;
|
|
|
+
|
|
|
+ if (!ossl_prov_is_running())
|
|
|
+ return 0;
|
|
|
+@@ -123,6 +124,9 @@ static int siv_cipher(void *vctx, unsign
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
++ if (in == NULL)
|
|
|
++ in = ∅
|
|
|
++
|
|
|
+ if (ctx->hw->cipher(ctx, out, in, inl) <= 0)
|
|
|
+ return 0;
|
|
|
+
|