mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-05-05 17:37:58 +02:00
Merge pull request #1321 from davidhorstmann-arm/calc-finished-check-return-2.28
[Backport 2.28] TLS1.2: Check for failures in Finished calculation
This commit is contained in:
6
ChangeLog.d/tls12-check-finished-calc.txt
Normal file
6
ChangeLog.d/tls12-check-finished-calc.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Security
|
||||
* Fix a vulnerability in the TLS 1.2 handshake. If memory allocation failed
|
||||
or there was a cryptographic hardware failure when calculating the
|
||||
Finished message, it could be calculated incorrectly. This would break
|
||||
the security guarantees of the TLS handshake.
|
||||
CVE-2025-27810
|
||||
@@ -467,7 +467,8 @@ struct mbedtls_ssl_handshake_params {
|
||||
|
||||
void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
|
||||
void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *);
|
||||
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
|
||||
mbedtls_ssl_tls_prf_cb *tls_prf;
|
||||
|
||||
#if defined(MBEDTLS_DHM_C)
|
||||
|
||||
@@ -624,6 +624,23 @@ exit:
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
static int mbedtls_ssl_md_error_from_psa(psa_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
|
||||
case PSA_ERROR_BUFFER_TOO_SMALL:
|
||||
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
|
||||
case PSA_ERROR_INSUFFICIENT_MEMORY:
|
||||
return MBEDTLS_ERR_MD_ALLOC_FAILED;
|
||||
default:
|
||||
return MBEDTLS_ERR_MD_HW_ACCEL_FAILED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
|
||||
@@ -892,25 +909,25 @@ static void ssl_update_checksum_md5sha1(mbedtls_ssl_context *, const unsigned ch
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_SSL3)
|
||||
static void ssl_calc_verify_ssl(const mbedtls_ssl_context *, unsigned char *, size_t *);
|
||||
static void ssl_calc_finished_ssl(mbedtls_ssl_context *, unsigned char *, int);
|
||||
static int ssl_calc_finished_ssl(mbedtls_ssl_context *, unsigned char *, int);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
|
||||
static void ssl_calc_verify_tls(const mbedtls_ssl_context *, unsigned char *, size_t *);
|
||||
static void ssl_calc_finished_tls(mbedtls_ssl_context *, unsigned char *, int);
|
||||
static int ssl_calc_finished_tls(mbedtls_ssl_context *, unsigned char *, int);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
static void ssl_update_checksum_sha256(mbedtls_ssl_context *, const unsigned char *, size_t);
|
||||
static void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *, unsigned char *, size_t *);
|
||||
static void ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int);
|
||||
static int ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
|
||||
static void ssl_update_checksum_sha384(mbedtls_ssl_context *, const unsigned char *, size_t);
|
||||
static void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char *, size_t *);
|
||||
static void ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
|
||||
static int ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
|
||||
#endif
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
@@ -3136,7 +3153,7 @@ static void ssl_update_checksum_sha384(mbedtls_ssl_context *ssl,
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_SSL3)
|
||||
static void ssl_calc_finished_ssl(
|
||||
static int ssl_calc_finished_ssl(
|
||||
mbedtls_ssl_context *ssl, unsigned char *buf, int from)
|
||||
{
|
||||
const char *sender;
|
||||
@@ -3218,11 +3235,13 @@ static void ssl_calc_finished_ssl(
|
||||
mbedtls_platform_zeroize(sha1sum, sizeof(sha1sum));
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
|
||||
static void ssl_calc_finished_tls(
|
||||
static int ssl_calc_finished_tls(
|
||||
mbedtls_ssl_context *ssl, unsigned char *buf, int from)
|
||||
{
|
||||
int len = 12;
|
||||
@@ -3278,12 +3297,14 @@ static void ssl_calc_finished_tls(
|
||||
mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
static void ssl_calc_finished_tls_sha256(
|
||||
static int ssl_calc_finished_tls_sha256(
|
||||
mbedtls_ssl_context *ssl, unsigned char *buf, int from)
|
||||
{
|
||||
int len = 12;
|
||||
@@ -3314,13 +3335,13 @@ static void ssl_calc_finished_tls_sha256(
|
||||
status = psa_hash_clone(&ssl->handshake->fin_sha256_psa, &sha256_psa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
|
||||
return;
|
||||
return mbedtls_ssl_md_error_from_psa(status);
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&sha256_psa, padbuf, sizeof(padbuf), &hash_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
|
||||
return;
|
||||
return mbedtls_ssl_md_error_from_psa(status);
|
||||
}
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 32);
|
||||
#else
|
||||
@@ -3354,12 +3375,14 @@ static void ssl_calc_finished_tls_sha256(
|
||||
mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_SHA256_C */
|
||||
|
||||
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
|
||||
|
||||
static void ssl_calc_finished_tls_sha384(
|
||||
static int ssl_calc_finished_tls_sha384(
|
||||
mbedtls_ssl_context *ssl, unsigned char *buf, int from)
|
||||
{
|
||||
int len = 12;
|
||||
@@ -3390,13 +3413,13 @@ static void ssl_calc_finished_tls_sha384(
|
||||
status = psa_hash_clone(&ssl->handshake->fin_sha384_psa, &sha384_psa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
|
||||
return;
|
||||
return mbedtls_ssl_md_error_from_psa(status);
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&sha384_psa, padbuf, sizeof(padbuf), &hash_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
|
||||
return;
|
||||
return mbedtls_ssl_md_error_from_psa(status);
|
||||
}
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 48);
|
||||
#else
|
||||
@@ -3441,6 +3464,8 @@ static void ssl_calc_finished_tls_sha384(
|
||||
mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
@@ -3535,7 +3560,12 @@ int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl)
|
||||
|
||||
mbedtls_ssl_update_out_pointers(ssl, ssl->transform_negotiate);
|
||||
|
||||
ssl->handshake->calc_finished(ssl, ssl->out_msg + 4, ssl->conf->endpoint);
|
||||
ret = ssl->handshake->calc_finished(ssl, ssl->out_msg + 4,
|
||||
ssl->conf->endpoint);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
|
||||
@@ -3664,7 +3694,11 @@ int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl)
|
||||
#endif
|
||||
hash_len = 12;
|
||||
|
||||
ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1);
|
||||
ret = ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
|
||||
@@ -7626,17 +7660,8 @@ exit:
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
||||
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
|
||||
switch (status) {
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
|
||||
case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
|
||||
case PSA_ERROR_BUFFER_TOO_SMALL:
|
||||
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
|
||||
case PSA_ERROR_INSUFFICIENT_MEMORY:
|
||||
return MBEDTLS_ERR_MD_ALLOC_FAILED;
|
||||
default:
|
||||
return MBEDTLS_ERR_MD_HW_ACCEL_FAILED;
|
||||
}
|
||||
|
||||
return mbedtls_ssl_md_error_from_psa(status);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user