From cdb875257a08bc3ae632b78c050293276aefe905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Mon, 24 Mar 2025 23:31:45 +0100 Subject: [PATCH] mbedTLS: Update to version 2.28.10 --- thirdparty/README.md | 2 +- thirdparty/mbedtls/include/mbedtls/config.h | 78 +++++- thirdparty/mbedtls/include/mbedtls/debug.h | 6 +- thirdparty/mbedtls/include/mbedtls/error.h | 2 +- thirdparty/mbedtls/include/mbedtls/gcm.h | 23 +- .../mbedtls/include/mbedtls/net_sockets.h | 2 +- thirdparty/mbedtls/include/mbedtls/ssl.h | 102 +++++++- .../mbedtls/include/mbedtls/ssl_internal.h | 13 +- thirdparty/mbedtls/include/mbedtls/version.h | 8 +- thirdparty/mbedtls/library/aesni.c | 8 +- thirdparty/mbedtls/library/ecp.c | 2 +- thirdparty/mbedtls/library/error.c | 2 + thirdparty/mbedtls/library/net_sockets.c | 12 +- thirdparty/mbedtls/library/ssl_cli.c | 9 +- thirdparty/mbedtls/library/ssl_tls.c | 242 ++++++++++++------ thirdparty/mbedtls/library/version_features.c | 3 + 16 files changed, 390 insertions(+), 124 deletions(-) diff --git a/thirdparty/README.md b/thirdparty/README.md index 575c32eaf7e..b904013a0ae 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -485,7 +485,7 @@ in the MSVC debugger. ## mbedtls - Upstream: https://github.com/Mbed-TLS/mbedtls -- Version: 2.28.9 (5e146adef63b326b04282252639bebc2730939c6, 2024) +- Version: 2.28.10 (2fc8413bfcb51354c8e679141b17b3f1a5942561, 2025) - License: Apache 2.0 File extracted from upstream release tarball: diff --git a/thirdparty/mbedtls/include/mbedtls/config.h b/thirdparty/mbedtls/include/mbedtls/config.h index 84af7f767e8..a67eb6017ee 100644 --- a/thirdparty/mbedtls/include/mbedtls/config.h +++ b/thirdparty/mbedtls/include/mbedtls/config.h @@ -1713,6 +1713,46 @@ */ //#define MBEDTLS_SSL_ASYNC_PRIVATE +/** \def MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + * + * In TLS clients, when a client authenticates a server through its + * certificate, the client normally checks three things: + * - the certificate chain must be valid; + * - the chain must start from a trusted CA; + * - the certificate must cover the server name that is expected by the client. + * + * Omitting any of these checks is generally insecure, and can allow a + * malicious server to impersonate a legitimate server. + * + * The third check may be safely skipped in some unusual scenarios, + * such as networks where eavesdropping is a risk but not active attacks, + * or a private PKI where the client equally trusts all servers that are + * accredited by the root CA. + * + * You should call mbedtls_ssl_set_hostname() with the expected server name + * before starting a TLS handshake on a client (unless the client is + * set up to only use PSK-based authentication, which does not rely on the + * host name). This configuration option controls what happens if a TLS client + * is configured with the authentication mode #MBEDTLS_SSL_VERIFY_REQUIRED + * (default), certificate authentication is enabled and the client does not + * call mbedtls_ssl_set_hostname(): + * + * - If this option is unset (default), the connection attempt is aborted + * with the error #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME. + * - If this option is set, the TLS library does not check the server name + * that the certificate is valid for. This is the historical behavior + * of Mbed TLS, but may be insecure as explained above. + * + * Enable this option for strict backward compatibility if you have + * determined that it is secure in the scenario where you are using + * Mbed TLS. + * + * \deprecated This option exists only for backward compatibility and will + * be removed in the next major version of Mbed TLS. + * + */ +//#define MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + /** * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION * @@ -2290,6 +2330,10 @@ * That is, the APIs enabled by this option are not covered by the usual * promises of API stability. * + * \warning In multithreaded applications, you must also enable + * #MBEDTLS_THREADING_C, unless only one thread ever calls PSA functions + * (`psa_xxx()`), including indirect calls through SSL/TLS, X.509 or PK. + * * Requires: MBEDTLS_PSA_CRYPTO_C. * * Uncomment this to enable internal use of PSA Crypto and new associated APIs. @@ -3389,6 +3433,14 @@ * * Enable the Platform Security Architecture cryptography API. * + * \note In multithreaded applications, you must enable #MBEDTLS_THREADING_C, + * unless only one thread ever calls `psa_xxx()` functions. + * That includes indirect calls, such as: + * - indirect calls from PK, X.509 or SSL functions when + * #MBEDTLS_USE_PSA_CRYPTO is enabled; + * - any other call to a function that requires calling psa_crypto_init() + * beforehand. + * * Module: library/psa_crypto.c * * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C, @@ -3605,11 +3657,29 @@ /** * \def MBEDTLS_THREADING_C * - * Enable the threading abstraction layer. - * By default Mbed TLS assumes it is used in a non-threaded environment or that - * contexts are not shared between threads. If you do intend to use contexts + * Traditionally, Mbed TLS assumes it is used in a non-threaded environment or + * that contexts are not shared between threads. If you do intend to use contexts * between threads, you will need to enable this layer to prevent race - * conditions. See also our Knowledge Base article about threading: + * conditions. + * + * The PSA subsystem has an implicit shared context. Therefore, you must + * enable this option if more than one thread may use any part of + * Mbed TLS that is implemented on top of the PSA subsystem. + * + * You must enable this option in multithreaded applications where more than + * one thread performs any of the following operations: + * + * - Any call to a PSA function (`psa_xxx()`). + * - Any call to a TLS, X.509 or PK function (`mbedtls_ssl_xxx()`, + * `mbedtls_x509_xxx()`, `mbedtls_pkcs7_xxx()`, `mbedtls_pk_xxx()`) + * if `MBEDTLS_USE_PSA_CRYPTO` is enabled (regardless of whether individual + * TLS, X.509 or PK contexts are shared between threads). + * - Any use of a cryptographic context if the same context is used in + * multiple threads. + * - Any call to a function where the documentation specifies that + * psa_crypto_init() must be called prior to that function. + * + * See also our Knowledge Base article about threading: * https://mbed-tls.readthedocs.io/en/latest/kb/development/thread-safety-and-multi-threading * * Module: library/threading.c diff --git a/thirdparty/mbedtls/include/mbedtls/debug.h b/thirdparty/mbedtls/include/mbedtls/debug.h index c29c40eee7a..1da0726ff30 100644 --- a/thirdparty/mbedtls/include/mbedtls/debug.h +++ b/thirdparty/mbedtls/include/mbedtls/debug.h @@ -108,16 +108,16 @@ * * This module provides debugging functions. */ -#if (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) +#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) #include #define MBEDTLS_PRINTF_SIZET PRIuPTR #define MBEDTLS_PRINTF_LONGLONG "I64d" #else \ - /* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */ + /* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) */ #define MBEDTLS_PRINTF_SIZET "zu" #define MBEDTLS_PRINTF_LONGLONG "lld" #endif \ - /* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */ + /* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) */ #ifdef __cplusplus extern "C" { diff --git a/thirdparty/mbedtls/include/mbedtls/error.h b/thirdparty/mbedtls/include/mbedtls/error.h index 7a183733eeb..fd0ac763212 100644 --- a/thirdparty/mbedtls/include/mbedtls/error.h +++ b/thirdparty/mbedtls/include/mbedtls/error.h @@ -92,7 +92,7 @@ * ECP 4 10 (Started from top) * MD 5 5 * HKDF 5 1 (Started from top) - * SSL 5 2 (Started from 0x5F00) + * SSL 5 3 (Started from 0x5F00) * CIPHER 6 8 (Started from 0x6080) * SSL 6 24 (Started from top, plus 0x6000) * SSL 7 32 diff --git a/thirdparty/mbedtls/include/mbedtls/gcm.h b/thirdparty/mbedtls/include/mbedtls/gcm.h index 1ad0e9e96f4..166ae1cad03 100644 --- a/thirdparty/mbedtls/include/mbedtls/gcm.h +++ b/thirdparty/mbedtls/include/mbedtls/gcm.h @@ -107,10 +107,9 @@ int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx, /** * \brief This function performs GCM encryption or decryption of a buffer. * - * \note For encryption, the output buffer can be the same as the - * input buffer. For decryption, the output buffer cannot be - * the same as input buffer. If the buffers overlap, the output - * buffer must trail at least 8 Bytes behind the input buffer. + * \note The output buffer \p output can be the same as the input + * buffer \p input. If \p output is greater than \p input, they + * cannot overlap. * * \warning When this function performs a decryption, it outputs the * authentication tag and does not verify that the data is @@ -171,9 +170,11 @@ int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, * \brief This function performs a GCM authenticated decryption of a * buffer. * - * \note For decryption, the output buffer cannot be the same as - * input buffer. If the buffers overlap, the output buffer - * must trail at least 8 Bytes behind the input buffer. + * \note The output buffer \p output can be the same as the input + * buffer \p input. If \p output is greater than \p input, they + * cannot overlap. Implementations which require + * MBEDTLS_GCM_ALT to be enabled may not provide support for + * overlapping buffers. * * \param ctx The GCM context. This must be initialized. * \param length The length of the ciphertext to decrypt, which is also @@ -243,9 +244,11 @@ int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, * Bytes. Only the last call before calling * mbedtls_gcm_finish() can be less than 16 Bytes. * - * \note For decryption, the output buffer cannot be the same as - * input buffer. If the buffers overlap, the output buffer - * must trail at least 8 Bytes behind the input buffer. + * \note The output buffer \p output can be the same as the input + * buffer \p input. If \p output is greater than \p input, they + * cannot overlap. Implementations which require + * MBEDTLS_GCM_ALT to be enabled may not provide support for + * overlapping buffers. * * \param ctx The GCM context. This must be initialized. * \param length The length of the input data. This must be a multiple of diff --git a/thirdparty/mbedtls/include/mbedtls/net_sockets.h b/thirdparty/mbedtls/include/mbedtls/net_sockets.h index 1a12c9c8034..5f5202fc26b 100644 --- a/thirdparty/mbedtls/include/mbedtls/net_sockets.h +++ b/thirdparty/mbedtls/include/mbedtls/net_sockets.h @@ -226,7 +226,7 @@ int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len); /** * \brief Write at most 'len' characters. If no error occurs, - * the actual amount read is returned. + * the actual amount written is returned. * * \param ctx Socket * \param buf The buffer to read from diff --git a/thirdparty/mbedtls/include/mbedtls/ssl.h b/thirdparty/mbedtls/include/mbedtls/ssl.h index 9cdf3a3ebba..8f9d38efe7f 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl.h @@ -183,6 +183,41 @@ #define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80 /** Cache entry not found */ #define MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND -0x5E00 +/** Attempt to verify a certificate without an expected hostname. + * This is usually insecure. + * + * In TLS clients, when a client authenticates a server through its + * certificate, the client normally checks three things: + * - the certificate chain must be valid; + * - the chain must start from a trusted CA; + * - the certificate must cover the server name that is expected by the client. + * + * Omitting any of these checks is generally insecure, and can allow a + * malicious server to impersonate a legitimate server. + * + * The third check may be safely skipped in some unusual scenarios, + * such as networks where eavesdropping is a risk but not active attacks, + * or a private PKI where the client equally trusts all servers that are + * accredited by the root CA. + * + * You should call mbedtls_ssl_set_hostname() with the expected server name + * before starting a TLS handshake on a client (unless the client is + * set up to only use PSK-based authentication, which does not rely on the + * host name). If you have determined that server name verification is not + * required for security in your scenario, call mbedtls_ssl_set_hostname() + * with \p NULL as the server name. + * + * This error is raised if all of the following conditions are met: + * + * - A TLS client is configured with the authentication mode + * #MBEDTLS_SSL_VERIFY_REQUIRED (default). + * - Certificate authentication is enabled. + * - The client does not call mbedtls_ssl_set_hostname(). + * - The configuration option + * #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + * is not enabled. + */ +#define MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME -0x5D80 /* * Various constants @@ -1403,8 +1438,36 @@ struct mbedtls_ssl_context { * User settings */ #if defined(MBEDTLS_X509_CRT_PARSE_C) - char *hostname; /*!< expected peer CN for verification - (and SNI if available) */ + /** Expected peer CN for verification. + * + * Also used on clients for SNI. + * + * The value of this field can be: + * - \p NULL in a newly initialized or reset context. + * - A heap-allocated copy of the last value passed to + * mbedtls_ssl_set_hostname(), if the last call had a non-null + * \p hostname argument. + * - A special value to indicate that mbedtls_ssl_set_hostname() + * was called with \p NULL (as opposed to never having been called). + * + * If you need to obtain the value passed to + * mbedtls_ssl_set_hostname() even if it may have been called with + * \p NULL, call mbedtls_ssl_get_hostname_pointer(). + * + * If this field contains the value \p NULL and the configuration option + * #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + * is unset, on a TLS client, attempting to verify a server certificate + * results in the error + * #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME. + * + * If this field contains the special value described above, or if + * the value is \p NULL and the configuration option + * #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + * is set, then the peer name verification is skipped, which may be + * insecure, especially on a client. Furthermore, on a client, the + * server_name extension is not sent. + */ + char *hostname; #endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_SSL_ALPN) @@ -1535,6 +1598,14 @@ void mbedtls_ssl_init(mbedtls_ssl_context *ssl); * Calling mbedtls_ssl_setup again is not supported, even * if no session is active. * + * \warning After setting up a client context, if certificate-based + * authentication is enabled, you should call + * mbedtls_ssl_set_hostname() to specifiy the expected + * name of the server. Without this, in most scenarios, + * the TLS connection is insecure. See + * #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + * for more information. + * * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto * subsystem must have been initialized by calling * psa_crypto_init() before calling this function. @@ -3107,16 +3178,29 @@ void mbedtls_ssl_conf_sig_hashes(mbedtls_ssl_config *conf, #if defined(MBEDTLS_X509_CRT_PARSE_C) /** * \brief Set or reset the hostname to check against the received - * server certificate. It sets the ServerName TLS extension, - * too, if that extension is enabled. (client-side only) + * peer certificate. On a client, this also sets the + * ServerName TLS extension, if that extension is enabled. + * On a TLS 1.3 client, this also sets the server name in + * the session resumption ticket, if that feature is enabled. * * \param ssl SSL context - * \param hostname the server hostname, may be NULL to clear hostname - - * \note Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN. + * \param hostname The server hostname. This may be \c NULL to clear + * the hostname. * - * \return 0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on - * allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on + * \note Maximum hostname length #MBEDTLS_SSL_MAX_HOST_NAME_LEN. + * + * \note If the hostname is \c NULL on a client, then the server + * is not authenticated: it only needs to have a valid + * certificate, not a certificate matching its name. + * Therefore you should always call this function on a client, + * unless the connection is set up to only allow + * pre-shared keys, or in scenarios where server + * impersonation is not a concern. See the documentation of + * #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + * for more details. + * + * \return 0 if successful, #MBEDTLS_ERR_SSL_ALLOC_FAILED on + * allocation failure, #MBEDTLS_ERR_SSL_BAD_INPUT_DATA on * too long input hostname. * * Hostname set to the one provided on success (cleared diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h index 3a40b4ba2fa..17bb631b59b 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h @@ -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) @@ -1214,6 +1215,16 @@ static inline size_t mbedtls_ssl_hs_hdr_len(const mbedtls_ssl_context *ssl) return 4; } +/** Get the host name from the SSL context. + * + * \param[in] ssl SSL context + * + * \return The \p hostname pointer from the SSL context. + * \c NULL if mbedtls_ssl_set_hostname() has never been called on + * \p ssl or if it was last called with \p NULL. + */ +const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl); + #if defined(MBEDTLS_SSL_PROTO_DTLS) void mbedtls_ssl_send_flight_completed(mbedtls_ssl_context *ssl); void mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context *ssl); diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h index 66998bf560f..4d30fcfb543 100644 --- a/thirdparty/mbedtls/include/mbedtls/version.h +++ b/thirdparty/mbedtls/include/mbedtls/version.h @@ -26,16 +26,16 @@ */ #define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MINOR 28 -#define MBEDTLS_VERSION_PATCH 9 +#define MBEDTLS_VERSION_PATCH 10 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x021C0900 -#define MBEDTLS_VERSION_STRING "2.28.9" -#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 2.28.9" +#define MBEDTLS_VERSION_NUMBER 0x021C0A00 +#define MBEDTLS_VERSION_STRING "2.28.10" +#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 2.28.10" #if defined(MBEDTLS_VERSION_C) diff --git a/thirdparty/mbedtls/library/aesni.c b/thirdparty/mbedtls/library/aesni.c index 74bae91f5e3..7491f8d980b 100644 --- a/thirdparty/mbedtls/library/aesni.c +++ b/thirdparty/mbedtls/library/aesni.c @@ -460,7 +460,7 @@ int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx, "movdqu %%xmm0, (%4) \n\t" // export output : : "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output) - : "memory", "cc", "xmm0", "xmm1"); + : "memory", "cc", "xmm0", "xmm1", "0", "1"); return 0; @@ -648,7 +648,7 @@ static void aesni_setkey_enc_128(unsigned char *rk, AESKEYGENA(xmm0_xmm1, "0x36") "call 1b \n\t" : : "r" (rk), "r" (key) - : "memory", "cc", "0"); + : "memory", "cc", "xmm0", "xmm1", "0"); } /* @@ -705,7 +705,7 @@ static void aesni_setkey_enc_192(unsigned char *rk, : : "r" (rk), "r" (key) - : "memory", "cc", "0"); + : "memory", "cc", "xmm0", "xmm1", "xmm2", "0"); } /* @@ -771,7 +771,7 @@ static void aesni_setkey_enc_256(unsigned char *rk, AESKEYGENA(xmm1_xmm2, "0x40") "call 1b \n\t" : : "r" (rk), "r" (key) - : "memory", "cc", "0"); + : "memory", "cc", "xmm0", "xmm1", "xmm2", "0"); } #endif /* MBEDTLS_AESNI_HAVE_CODE */ diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c index cfe02b0d2c2..2ed735d754e 100644 --- a/thirdparty/mbedtls/library/ecp.c +++ b/thirdparty/mbedtls/library/ecp.c @@ -3125,7 +3125,7 @@ int mbedtls_ecp_check_privkey(const mbedtls_ecp_group *grp, /* see RFC 7748 sec. 5 para. 5 */ if (mbedtls_mpi_get_bit(d, 0) != 0 || mbedtls_mpi_get_bit(d, 1) != 0 || - mbedtls_mpi_bitlen(d) - 1 != grp->nbits) { /* mbedtls_mpi_bitlen is one-based! */ + mbedtls_mpi_bitlen(d) != grp->nbits + 1) { /* mbedtls_mpi_bitlen is one-based! */ return MBEDTLS_ERR_ECP_INVALID_KEY; } diff --git a/thirdparty/mbedtls/library/error.c b/thirdparty/mbedtls/library/error.c index cb7ad57e450..a0667e177d6 100644 --- a/thirdparty/mbedtls/library/error.c +++ b/thirdparty/mbedtls/library/error.c @@ -508,6 +508,8 @@ const char *mbedtls_high_level_strerr(int error_code) return( "SSL - Invalid value in SSL config" ); case -(MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND): return( "SSL - Cache entry not found" ); + case -(MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME): + return( "SSL - Attempt to verify a certificate without an expected hostname. This is usually insecure. In TLS clients, when a client authenticates a server through its certificate, the client normally checks three things: - the certificate chain must be valid; - the chain must start from a trusted CA; - the certificate must cover the server name that is expected by the client. Omitting any of these checks is generally insecure, and can allow a malicious server to impersonate a legitimate server. The third check may be safely skipped in some unusual scenarios, such as networks where eavesdropping is a risk but not active attacks, or a private PKI where the client equally trusts all servers that are accredited by the root CA. You should call mbedtls_ssl_set_hostname() with the expected server name before starting a TLS handshake on a client (unless the client is set up to only use PSK-based authentication, which does not rely on the host name). If you have determined that server name verification is not required for security in your scenario, call mbedtls_ssl_set_hostname() with \\p NULL as the server name. This error is raised if all of the following conditions are met: - A TLS client is configured with the authentication mode #MBEDTLS_SSL_VERIFY_REQUIRED (default). - Certificate authentication is enabled. - The client does not call mbedtls_ssl_set_hostname(). - The configuration option #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME is not enabled" ); #endif /* MBEDTLS_SSL_TLS_C */ #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) diff --git a/thirdparty/mbedtls/library/net_sockets.c b/thirdparty/mbedtls/library/net_sockets.c index 5d985ef0011..730d13b1a64 100644 --- a/thirdparty/mbedtls/library/net_sockets.c +++ b/thirdparty/mbedtls/library/net_sockets.c @@ -195,7 +195,7 @@ int mbedtls_net_connect(mbedtls_net_context *ctx, const char *host, break; } - close(ctx->fd); + mbedtls_net_close(ctx); ret = MBEDTLS_ERR_NET_CONNECT_FAILED; } @@ -242,13 +242,13 @@ int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char * n = 1; if (setsockopt(ctx->fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(n)) != 0) { - close(ctx->fd); + mbedtls_net_close(ctx); ret = MBEDTLS_ERR_NET_SOCKET_FAILED; continue; } if (bind(ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen) != 0) { - close(ctx->fd); + mbedtls_net_close(ctx); ret = MBEDTLS_ERR_NET_BIND_FAILED; continue; } @@ -256,7 +256,7 @@ int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char * /* Listen only makes sense for TCP */ if (proto == MBEDTLS_NET_PROTO_TCP) { if (listen(ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG) != 0) { - close(ctx->fd); + mbedtls_net_close(ctx); ret = MBEDTLS_ERR_NET_LISTEN_FAILED; continue; } @@ -529,8 +529,8 @@ void mbedtls_net_usleep(unsigned long usec) #else struct timeval tv; tv.tv_sec = usec / 1000000; -#if defined(__unix__) || defined(__unix) || \ - (defined(__APPLE__) && defined(__MACH__)) +#if (defined(__unix__) || defined(__unix) || \ + (defined(__APPLE__) && defined(__MACH__))) && !defined(__DJGPP__) tv.tv_usec = (suseconds_t) usec % 1000000; #else tv.tv_usec = usec % 1000000; diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c index 4fde783d3e7..2854e00fcb1 100644 --- a/thirdparty/mbedtls/library/ssl_cli.c +++ b/thirdparty/mbedtls/library/ssl_cli.c @@ -83,19 +83,20 @@ static int ssl_write_hostname_ext(mbedtls_ssl_context *ssl, size_t *olen) { unsigned char *p = buf; + const char *hostname = mbedtls_ssl_get_hostname_pointer(ssl); size_t hostname_len; *olen = 0; - if (ssl->hostname == NULL) { + if (hostname == NULL) { return 0; } MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding server name extension: %s", - ssl->hostname)); + hostname)); - hostname_len = strlen(ssl->hostname); + hostname_len = strlen(hostname); MBEDTLS_SSL_CHK_BUF_PTR(p, end, hostname_len + 9); @@ -139,7 +140,7 @@ static int ssl_write_hostname_ext(mbedtls_ssl_context *ssl, MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0); p += 2; - memcpy(p, ssl->hostname, hostname_len); + memcpy(p, hostname, hostname_len); *olen = hostname_len + 9; diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c index 61494341040..73f9c7f4710 100644 --- a/thirdparty/mbedtls/library/ssl_tls.c +++ b/thirdparty/mbedtls/library/ssl_tls.c @@ -38,6 +38,92 @@ #include "mbedtls/oid.h" #endif +#if defined(MBEDTLS_X509_CRT_PARSE_C) + +/* A magic value for `ssl->hostname` indicating that + * mbedtls_ssl_set_hostname() has been called with `NULL`. + * If mbedtls_ssl_set_hostname() has never been called on `ssl`, then + * `ssl->hostname == NULL`. */ +static const char *const ssl_hostname_skip_cn_verification = ""; + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) +/** Whether mbedtls_ssl_set_hostname() has been called. + * + * \param[in] ssl SSL context + * + * \return \c 1 if mbedtls_ssl_set_hostname() has been called on \p ssl + * (including `mbedtls_ssl_set_hostname(ssl, NULL)`), + * otherwise \c 0. + */ +static int mbedtls_ssl_has_set_hostname_been_called( + const mbedtls_ssl_context *ssl) +{ + return ssl->hostname != NULL; +} +#endif + +const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl) +{ + if (ssl->hostname == ssl_hostname_skip_cn_verification) { + return NULL; + } + return ssl->hostname; +} + +static void mbedtls_ssl_free_hostname(mbedtls_ssl_context *ssl) +{ + if (ssl->hostname != NULL && + ssl->hostname != ssl_hostname_skip_cn_verification) { + mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname)); + mbedtls_free(ssl->hostname); + } + ssl->hostname = NULL; +} + +int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname) +{ + /* Initialize to suppress unnecessary compiler warning */ + size_t hostname_len = 0; + + /* Check if new hostname is valid before + * making any change to current one */ + if (hostname != NULL) { + hostname_len = strlen(hostname); + + if (hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + } + + /* Now it's clear that we will overwrite the old hostname, + * so we can free it safely */ + mbedtls_ssl_free_hostname(ssl); + + if (hostname == NULL) { + /* Passing NULL as hostname clears the old one, but leaves a + * special marker to indicate that mbedtls_ssl_set_hostname() + * has been called. */ + /* ssl->hostname should be const, but isn't. We won't actually + * write to the buffer, so it's ok to cast away the const. */ + ssl->hostname = (char *) ssl_hostname_skip_cn_verification; + } else { + ssl->hostname = mbedtls_calloc(1, hostname_len + 1); + if (ssl->hostname == NULL) { + /* mbedtls_ssl_set_hostname() has been called, but unsuccessfully. + * Leave ssl->hostname in the same state as if the function had + * not been called, i.e. a null pointer. */ + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + + memcpy(ssl->hostname, hostname, hostname_len); + + ssl->hostname[hostname_len] = '\0'; + } + + return 0; +} +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + #if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) @@ -538,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) @@ -806,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 */ @@ -2521,13 +2624,33 @@ static int ssl_parse_certificate_coordinate(mbedtls_ssl_context *ssl, return SSL_CERTIFICATE_EXPECTED; } +static int get_hostname_for_verification(mbedtls_ssl_context *ssl, + const char **hostname) +{ + if (!mbedtls_ssl_has_set_hostname_been_called(ssl)) { + MBEDTLS_SSL_DEBUG_MSG(1, ("Certificate verification without having set hostname")); +#if !defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME) + if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && + ssl->conf->authmode == MBEDTLS_SSL_VERIFY_REQUIRED) { + return MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME; + } +#endif + } + + *hostname = mbedtls_ssl_get_hostname_pointer(ssl); + if (*hostname == NULL) { + MBEDTLS_SSL_DEBUG_MSG(2, ("Certificate verification without CN verification")); + } + + return 0; +} + MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl, int authmode, mbedtls_x509_crt *chain, void *rs_ctx) { - int ret = 0; const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->handshake->ciphersuite_info; int have_ca_chain = 0; @@ -2549,6 +2672,13 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl, p_vrfy = ssl->conf->p_vrfy; } + const char *hostname = ""; + int ret = get_hostname_for_verification(ssl, &hostname); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "get_hostname_for_verification", ret); + return ret; + } + /* * Main check: verify certificate */ @@ -2563,7 +2693,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl, ssl->conf->f_ca_cb, ssl->conf->p_ca_cb, ssl->conf->cert_profile, - ssl->hostname, + hostname, &ssl->session_negotiate->verify_result, f_vrfy, p_vrfy); } else @@ -2591,7 +2721,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl, chain, ca_chain, ca_crl, ssl->conf->cert_profile, - ssl->hostname, + hostname, &ssl->session_negotiate->verify_result, f_vrfy, p_vrfy, rs_ctx); } @@ -3023,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; @@ -3105,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; @@ -3165,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; @@ -3201,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 @@ -3241,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; @@ -3277,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 @@ -3328,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 */ @@ -3422,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 @@ -3551,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); @@ -4617,49 +4764,6 @@ void mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf, } #endif /* MBEDTLS_ECP_C */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname) -{ - /* Initialize to suppress unnecessary compiler warning */ - size_t hostname_len = 0; - - /* Check if new hostname is valid before - * making any change to current one */ - if (hostname != NULL) { - hostname_len = strlen(hostname); - - if (hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - } - - /* Now it's clear that we will overwrite the old hostname, - * so we can free it safely */ - - if (ssl->hostname != NULL) { - mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname)); - mbedtls_free(ssl->hostname); - } - - /* Passing NULL as hostname shall clear the old one */ - - if (hostname == NULL) { - ssl->hostname = NULL; - } else { - ssl->hostname = mbedtls_calloc(1, hostname_len + 1); - if (ssl->hostname == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(ssl->hostname, hostname, hostname_len); - - ssl->hostname[hostname_len] = '\0'; - } - - return 0; -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) void mbedtls_ssl_conf_sni(mbedtls_ssl_config *conf, int (*f_sni)(void *, mbedtls_ssl_context *, @@ -6816,10 +6920,7 @@ void mbedtls_ssl_free(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_X509_CRT_PARSE_C) - if (ssl->hostname != NULL) { - mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname)); - mbedtls_free(ssl->hostname); - } + mbedtls_ssl_free_hostname(ssl); #endif #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) @@ -7559,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; } diff --git a/thirdparty/mbedtls/library/version_features.c b/thirdparty/mbedtls/library/version_features.c index 6f663b12a73..f5734c45774 100644 --- a/thirdparty/mbedtls/library/version_features.c +++ b/thirdparty/mbedtls/library/version_features.c @@ -486,6 +486,9 @@ static const char * const features[] = { #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) "MBEDTLS_SSL_ASYNC_PRIVATE", #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ +#if defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME) + "MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME", +#endif /* MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME */ #if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) "MBEDTLS_SSL_CONTEXT_SERIALIZATION", #endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */