Merge pull request #1088 from gilles-peskine-arm/tls13_read_public_xxdhe_share-overflow
Fix buffer overflow in TLS 1.3 and USE_PSA_CRYPTO ClientHello ECDH/FFDH parsers
This commit is contained in:
commit
130938a804
4 changed files with 33 additions and 9 deletions
8
ChangeLog.d/xxx_psa_peerkey.txt
Normal file
8
ChangeLog.d/xxx_psa_peerkey.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
Security
|
||||
* Fix a remotely exploitable heap buffer overflow in TLS handshake parsing.
|
||||
In TLS 1.3, all configurations are affected except PSK-only ones, and
|
||||
both clients and servers are affected.
|
||||
In TLS 1.2, the affected configurations are those with
|
||||
MBEDTLS_USE_PSA_CRYPTO and ECDH enabled but DHM and RSA disabled,
|
||||
and only servers are affected, not clients.
|
||||
Credit to OSS-Fuzz.
|
|
@ -1727,7 +1727,7 @@ static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl,
|
|||
unsigned char *end)
|
||||
{
|
||||
uint16_t tls_id;
|
||||
uint8_t ecpoint_len;
|
||||
size_t ecpoint_len;
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
|
||||
size_t ec_bits = 0;
|
||||
|
@ -1779,7 +1779,7 @@ static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl,
|
|||
return MBEDTLS_ERR_SSL_DECODE_ERROR;
|
||||
}
|
||||
|
||||
if (ecpoint_len > PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)) {
|
||||
if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) {
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -2059,7 +2059,7 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
|
|||
ret = mbedtls_ecp_point_write_binary(&peer_key->grp, &peer_key->Q,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED, &olen,
|
||||
ssl->handshake->xxdh_psa_peerkey,
|
||||
MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH);
|
||||
sizeof(ssl->handshake->xxdh_psa_peerkey));
|
||||
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecp_point_write_binary"), ret);
|
||||
|
|
|
@ -3718,22 +3718,32 @@ static int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl)
|
|||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Read the peer's public key."));
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Read the peer's public key."));
|
||||
|
||||
/*
|
||||
* We must have at least two bytes (1 for length, at least 1 for data)
|
||||
*/
|
||||
if (buf_len < 2) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid buffer length"));
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid buffer length: %" MBEDTLS_PRINTF_SIZET,
|
||||
buf_len));
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
|
||||
if (data_len < 1 || data_len > buf_len) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid data length"));
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid data length: %" MBEDTLS_PRINTF_SIZET
|
||||
" > %" MBEDTLS_PRINTF_SIZET,
|
||||
data_len, buf_len));
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
|
||||
/* Store peer's ECDH public key. */
|
||||
if (data_len > sizeof(handshake->xxdh_psa_peerkey)) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %" MBEDTLS_PRINTF_SIZET
|
||||
" > %" MBEDTLS_PRINTF_SIZET,
|
||||
data_len,
|
||||
sizeof(handshake->xxdh_psa_peerkey)));
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
memcpy(handshake->xxdh_psa_peerkey, p, data_len);
|
||||
handshake->xxdh_psa_peerkey_len = data_len;
|
||||
|
||||
|
|
|
@ -1516,7 +1516,13 @@ int mbedtls_ssl_tls13_read_public_xxdhe_share(mbedtls_ssl_context *ssl,
|
|||
/* Check if key size is consistent with given buffer length. */
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, peerkey_len);
|
||||
|
||||
/* Store peer's ECDH public key. */
|
||||
/* Store peer's ECDH/FFDH public key. */
|
||||
if (peerkey_len > sizeof(handshake->xxdh_psa_peerkey)) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %u > %" MBEDTLS_PRINTF_SIZET,
|
||||
(unsigned) peerkey_len,
|
||||
sizeof(handshake->xxdh_psa_peerkey)));
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
memcpy(handshake->xxdh_psa_peerkey, p, peerkey_len);
|
||||
handshake->xxdh_psa_peerkey_len = peerkey_len;
|
||||
|
||||
|
|
Loading…
Reference in a new issue