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)
AES_KEY ks;
} ks;
aeswrap_fn wrapfn;
+ int updated;
} PROV_AES_WRAP_CTX;
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;
}
}
+ /*
+ * 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) {
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;
if (len <= 0)
return 0;
- *outl = len;
+ *outl = (size_t)len;
return 1;
}