diff options
author | 2020-06-05 18:44:42 +0000 | |
---|---|---|
committer | 2020-06-05 18:44:42 +0000 | |
commit | f72711c6fb8692f12b01b3a3b7f54687729f6f9b (patch) | |
tree | ddf1d46c6b69cc56df29a18cb80494652a3c23ac /lib | |
parent | Use IANA allocated GOST ClientCertificateTypes. (diff) | |
download | wireguard-openbsd-f72711c6fb8692f12b01b3a3b7f54687729f6f9b.tar.xz wireguard-openbsd-f72711c6fb8692f12b01b3a3b7f54687729f6f9b.zip |
Add a custom copy handler for AES key wrap
This is necessary because ctx->cipher_data is an EVP_AES_WRAP_CTX
containing a pointer to ctx->iv. EVP_CIPHER_CTX_copy() uses memcpy
to copy cipher_data to the target struct. The result is that the
copy contains a pointer to the wrong struct, which then leads to a
use-after-free. The custom copy handler fixes things up to avoid
that.
Issue reported by Guido Vranken
ok beck inoguchi jsing
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libcrypto/evp/e_aes.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/lib/libcrypto/evp/e_aes.c b/lib/libcrypto/evp/e_aes.c index 80eba802445..05ed0029500 100644 --- a/lib/libcrypto/evp/e_aes.c +++ b/lib/libcrypto/evp/e_aes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: e_aes.c,v 1.41 2020/04/30 18:43:11 tb Exp $ */ +/* $OpenBSD: e_aes.c,v 1.42 2020/06/05 18:44:42 tb Exp $ */ /* ==================================================================== * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. * @@ -1636,9 +1636,35 @@ aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return ret != 0 ? ret : -1; } +static int +aes_wrap_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_WRAP_CTX *wctx = c->cipher_data; + + switch (type) { + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_WRAP_CTX *wctx_out = out->cipher_data; + + if (wctx->iv != NULL) { + if (c->iv != wctx->iv) + return 0; + + wctx_out->iv = out->iv; + } + + return 1; + } + } + + return -1; +} + #define WRAP_FLAGS \ ( EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER | \ - EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1 ) + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1 | \ + EVP_CIPH_CUSTOM_COPY ) static const EVP_CIPHER aes_128_wrap = { .nid = NID_id_aes128_wrap, @@ -1652,7 +1678,7 @@ static const EVP_CIPHER aes_128_wrap = { .ctx_size = sizeof(EVP_AES_WRAP_CTX), .set_asn1_parameters = NULL, .get_asn1_parameters = NULL, - .ctrl = NULL, + .ctrl = aes_wrap_ctrl, .app_data = NULL, }; @@ -1674,7 +1700,7 @@ static const EVP_CIPHER aes_192_wrap = { .ctx_size = sizeof(EVP_AES_WRAP_CTX), .set_asn1_parameters = NULL, .get_asn1_parameters = NULL, - .ctrl = NULL, + .ctrl = aes_wrap_ctrl, .app_data = NULL, }; @@ -1696,7 +1722,7 @@ static const EVP_CIPHER aes_256_wrap = { .ctx_size = sizeof(EVP_AES_WRAP_CTX), .set_asn1_parameters = NULL, .get_asn1_parameters = NULL, - .ctrl = NULL, + .ctrl = aes_wrap_ctrl, .app_data = NULL, }; |