From: slontis Date: Wed, 4 Feb 2026 22:35:43 +0000 (+1100) Subject: AES-WRAP fixes. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ca8a2bd6186f5478d0b8e03af90d6d1f6cd87161;p=thirdparty%2Fopenssl.git AES-WRAP fixes. 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 Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/29940) --- diff --git a/providers/implementations/ciphers/cipher_aes_wrp.c b/providers/implementations/ciphers/cipher_aes_wrp.c index 10284d2d2fb..c947f5f6946 100644 --- a/providers/implementations/ciphers/cipher_aes_wrp.c +++ b/providers/implementations/ciphers/cipher_aes_wrp.c @@ -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; }