Skip to content

Commit f72711c

Browse files
committed
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
1 parent 22c2c18 commit f72711c

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

lib/libcrypto/evp/e_aes.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: e_aes.c,v 1.41 2020/04/30 18:43:11 tb Exp $ */
1+
/* $OpenBSD: e_aes.c,v 1.42 2020/06/05 18:44:42 tb Exp $ */
22
/* ====================================================================
33
* Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.
44
*
@@ -1636,9 +1636,35 @@ aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
16361636
return ret != 0 ? ret : -1;
16371637
}
16381638

1639+
static int
1640+
aes_wrap_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
1641+
{
1642+
EVP_AES_WRAP_CTX *wctx = c->cipher_data;
1643+
1644+
switch (type) {
1645+
case EVP_CTRL_COPY:
1646+
{
1647+
EVP_CIPHER_CTX *out = ptr;
1648+
EVP_AES_WRAP_CTX *wctx_out = out->cipher_data;
1649+
1650+
if (wctx->iv != NULL) {
1651+
if (c->iv != wctx->iv)
1652+
return 0;
1653+
1654+
wctx_out->iv = out->iv;
1655+
}
1656+
1657+
return 1;
1658+
}
1659+
}
1660+
1661+
return -1;
1662+
}
1663+
16391664
#define WRAP_FLAGS \
16401665
( EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER | \
1641-
EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1 )
1666+
EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1 | \
1667+
EVP_CIPH_CUSTOM_COPY )
16421668

16431669
static const EVP_CIPHER aes_128_wrap = {
16441670
.nid = NID_id_aes128_wrap,
@@ -1652,7 +1678,7 @@ static const EVP_CIPHER aes_128_wrap = {
16521678
.ctx_size = sizeof(EVP_AES_WRAP_CTX),
16531679
.set_asn1_parameters = NULL,
16541680
.get_asn1_parameters = NULL,
1655-
.ctrl = NULL,
1681+
.ctrl = aes_wrap_ctrl,
16561682
.app_data = NULL,
16571683
};
16581684

@@ -1674,7 +1700,7 @@ static const EVP_CIPHER aes_192_wrap = {
16741700
.ctx_size = sizeof(EVP_AES_WRAP_CTX),
16751701
.set_asn1_parameters = NULL,
16761702
.get_asn1_parameters = NULL,
1677-
.ctrl = NULL,
1703+
.ctrl = aes_wrap_ctrl,
16781704
.app_data = NULL,
16791705
};
16801706

@@ -1696,7 +1722,7 @@ static const EVP_CIPHER aes_256_wrap = {
16961722
.ctx_size = sizeof(EVP_AES_WRAP_CTX),
16971723
.set_asn1_parameters = NULL,
16981724
.get_asn1_parameters = NULL,
1699-
.ctrl = NULL,
1725+
.ctrl = aes_wrap_ctrl,
17001726
.app_data = NULL,
17011727
};
17021728

0 commit comments

Comments
 (0)