]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
AES-WRAP fixes.
authorslontis <shane.lontis@oracle.com>
Wed, 4 Feb 2026 22:35:43 +0000 (09:35 +1100)
committerPauli <paul.dale@oracle.com>
Fri, 6 Feb 2026 07:42:03 +0000 (18:42 +1100)
Partially fixes issue in Discussion 22861

AES-WRAP pad is documented as only working for non streaming cases.
It did not however enforce this, so a user could potentially
wrap something incorrectly without an error and then not be able to
unwrap it without an error. The code now checks that update is only
called once.

An internal function returned an int which could be negative for bad
input values, and the return value was assigned to a size_t which
ignored the error condition.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/29940)

providers/implementations/ciphers/cipher_aes_wrp.c

index 10284d2d2fb580e1fbae4e608f7687d5a9ba3abf..c947f5f694668dfcf0f71c474065d7909ece9061 100644 (file)
@@ -44,6 +44,7 @@ typedef struct prov_aes_wrap_ctx_st {
         AES_KEY ks;
     } ks;
     aeswrap_fn wrapfn;
+    int updated;
 
 } PROV_AES_WRAP_CTX;
 
@@ -107,6 +108,7 @@ static int aes_wrap_init(void *vctx, const unsigned char *key,
     if (!ossl_prov_is_running())
         return 0;
 
+    wctx->updated = 0;
     ctx->enc = enc;
     if (ctx->pad)
         wctx->wrapfn = enc ? CRYPTO_128_wrap_pad : CRYPTO_128_unwrap_pad;
@@ -209,6 +211,16 @@ static int aes_wrap_cipher_internal(void *vctx, unsigned char *out,
         }
     }
 
+    /*
+     * Multiple calls to update are not allowed, since the algorithm
+     * relies on all fields being present.
+     */
+    if (wctx->updated) {
+        ERR_raise(ERR_LIB_PROV, EVP_R_UPDATE_ERROR);
+        return -1;
+    }
+    wctx->updated = 1;
+
     rv = wctx->wrapfn(&wctx->ks.ks, ctx->iv_set ? ctx->iv : NULL, out, in,
         inlen, ctx->block);
     if (!rv) {
@@ -237,7 +249,7 @@ static int aes_wrap_cipher(void *vctx,
     const unsigned char *in, size_t inl)
 {
     PROV_AES_WRAP_CTX *ctx = (PROV_AES_WRAP_CTX *)vctx;
-    size_t len;
+    int len;
 
     if (!ossl_prov_is_running())
         return 0;
@@ -256,7 +268,7 @@ static int aes_wrap_cipher(void *vctx,
     if (len <= 0)
         return 0;
 
-    *outl = len;
+    *outl = (size_t)len;
     return 1;
 }