diff --git a/DEPENDENCIES b/DEPENDENCIES index ef32744..56bebad 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -1,5 +1,5 @@ vendorpull https://github.com/sourcemeta/vendorpull 1dcbac42809cf87cb5b045106b863e17ad84ba02 -mbedtls https://github.com/Mbed-TLS/mbedtls v3.6.5 +mbedtls https://github.com/Mbed-TLS/mbedtls v3.6.6 zlib https://github.com/madler/zlib v1.3.2 curl https://github.com/curl/curl curl-8_19_0 nghttp2 https://github.com/nghttp2/nghttp2 v1.67.1 diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake index c08c699..166d88d 100644 --- a/cmake/FindMbedTLS.cmake +++ b/cmake/FindMbedTLS.cmake @@ -67,6 +67,7 @@ if(NOT MbedTLS_FOUND) "${MBEDTLS_DIR}/library/psa_crypto_hash.c" "${MBEDTLS_DIR}/library/psa_crypto_mac.c" "${MBEDTLS_DIR}/library/psa_crypto_pake.c" + "${MBEDTLS_DIR}/library/psa_crypto_random.c" "${MBEDTLS_DIR}/library/psa_crypto_rsa.c" "${MBEDTLS_DIR}/library/psa_crypto_se.c" "${MBEDTLS_DIR}/library/psa_crypto_slot_management.c" diff --git a/vendor/mbedtls/include/mbedtls/asn1write.h b/vendor/mbedtls/include/mbedtls/asn1write.h index 0c5a85a..9a1062a 100644 --- a/vendor/mbedtls/include/mbedtls/asn1write.h +++ b/vendor/mbedtls/include/mbedtls/asn1write.h @@ -381,10 +381,10 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(mbedtls_asn1_named_data * const unsigned char *val, size_t val_len); +#endif /* MBEDTLS_ASN1_WRITE_C */ + #ifdef __cplusplus } #endif -#endif /* MBEDTLS_ASN1_WRITE_C */ - #endif /* MBEDTLS_ASN1_WRITE_H */ diff --git a/vendor/mbedtls/include/mbedtls/build_info.h b/vendor/mbedtls/include/mbedtls/build_info.h index 3d867aa..b5e8066 100644 --- a/vendor/mbedtls/include/mbedtls/build_info.h +++ b/vendor/mbedtls/include/mbedtls/build_info.h @@ -26,16 +26,16 @@ */ #define MBEDTLS_VERSION_MAJOR 3 #define MBEDTLS_VERSION_MINOR 6 -#define MBEDTLS_VERSION_PATCH 5 +#define MBEDTLS_VERSION_PATCH 6 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x03060500 -#define MBEDTLS_VERSION_STRING "3.6.5" -#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.5" +#define MBEDTLS_VERSION_NUMBER 0x03060600 +#define MBEDTLS_VERSION_STRING "3.6.6" +#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.6" /* Macros for build-time platform detection */ diff --git a/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h b/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h index 331ac9b..db684ad 100644 --- a/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h +++ b/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h @@ -48,6 +48,49 @@ #endif #endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */ +/* The number of "true" entropy sources (excluding NV seed). + * This must be consistent with mbedtls_entropy_init() in entropy.c. + */ +/* Define auxiliary macros, because in standard C, defined(xxx) is only + * allowed directly on an #if or #elif line, not in recursive expansion. */ +#if defined(MBEDTLS_NO_PLATFORM_ENTROPY) +#define MBEDTLS_PLATFORM_ENTROPY_ENABLED 0 +#else +#define MBEDTLS_PLATFORM_ENTROPY_ENABLED 1 +#endif +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) +#define MBEDTLS_ENTROPY_HARDWARE_ALT_DEFINED 1 +#else +#define MBEDTLS_ENTROPY_HARDWARE_ALT_DEFINED 0 +#endif + +#define MBEDTLS_ENTROPY_TRUE_SOURCES ( \ + MBEDTLS_ENTROPY_HARDWARE_ALT_DEFINED + \ + MBEDTLS_PLATFORM_ENTROPY_ENABLED + \ + 0) + +/* Whether there is at least one entropy source for the entropy module. + * + * Note that when MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled, the entropy + * module is unused and the configuration will typically not include any + * entropy source, so this macro will typically remain undefined. + */ +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#define MBEDTLS_ENTROPY_HAVE_SOURCES (MBEDTLS_ENTROPY_TRUE_SOURCES + 1) +#elif MBEDTLS_ENTROPY_TRUE_SOURCES != 0 +#define MBEDTLS_ENTROPY_HAVE_SOURCES MBEDTLS_ENTROPY_TRUE_SOURCES +#else +#undef MBEDTLS_ENTROPY_HAVE_SOURCES +#endif + +/* Test function dependencies can only check with defined(), + * not other preprocessor expressions. */ +#if MBEDTLS_ENTROPY_TRUE_SOURCES > 0 +#define MBEDTLS_ENTROPY_HAVE_TRUE_SOURCES +#else +#undef MBEDTLS_ENTROPY_HAVE_TRUE_SOURCES +#endif + /* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT * is defined as well to include all PSA code. */ diff --git a/vendor/mbedtls/include/mbedtls/ctr_drbg.h b/vendor/mbedtls/include/mbedtls/ctr_drbg.h index 0b7cce1..c8d6483 100644 --- a/vendor/mbedtls/include/mbedtls/ctr_drbg.h +++ b/vendor/mbedtls/include/mbedtls/ctr_drbg.h @@ -186,8 +186,7 @@ typedef struct mbedtls_ctr_drbg_context { unsigned char MBEDTLS_PRIVATE(counter)[16]; /*!< The counter (V). */ int MBEDTLS_PRIVATE(reseed_counter); /*!< The reseed counter. * This is the number of requests that have - * been made since the last (re)seeding, - * minus one. + * been made since the last (re)seeding. * Before the initial seeding, this field * contains the amount of entropy in bytes * to use as a nonce for the initial seeding, diff --git a/vendor/mbedtls/include/mbedtls/debug.h b/vendor/mbedtls/include/mbedtls/debug.h index e6f5dad..45bf390 100644 --- a/vendor/mbedtls/include/mbedtls/debug.h +++ b/vendor/mbedtls/include/mbedtls/debug.h @@ -111,7 +111,7 @@ #if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) #include #define MBEDTLS_PRINTF_SIZET PRIuPTR - #define MBEDTLS_PRINTF_LONGLONG "I64d" + #define MBEDTLS_PRINTF_LONGLONG PRId64 #else \ /* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) */ #define MBEDTLS_PRINTF_SIZET "zu" diff --git a/vendor/mbedtls/include/mbedtls/ecdh.h b/vendor/mbedtls/include/mbedtls/ecdh.h index a919ad2..e81d5c3 100644 --- a/vendor/mbedtls/include/mbedtls/ecdh.h +++ b/vendor/mbedtls/include/mbedtls/ecdh.h @@ -6,7 +6,7 @@ * The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous * key agreement protocol allowing two parties to establish a shared * secret over an insecure channel. Each party must have an - * elliptic-curve public–private key pair. + * elliptic-curve public private key pair. * * For more information, see NIST SP 800-56A Rev. 2: Recommendation for * Pair-Wise Key Establishment Schemes Using Discrete Logarithm diff --git a/vendor/mbedtls/include/mbedtls/mbedtls_config.h b/vendor/mbedtls/include/mbedtls/mbedtls_config.h index 75eff2d..8fa445a 100644 --- a/vendor/mbedtls/include/mbedtls/mbedtls_config.h +++ b/vendor/mbedtls/include/mbedtls/mbedtls_config.h @@ -1204,6 +1204,20 @@ * This is useful if your platform does not support * standards like the /dev/urandom or Windows CryptoAPI. * + * If you enable this macro, you will probably need to enable + * #MBEDTLS_ENTROPY_HARDWARE_ALT and provide a function + * mbedtls_hardware_poll(). + * + * \note The default platform entropy function supports the following + * sources: + * - getrandom() on Linux (if syscall() is available at compile time); + * - getrandom() on FreeBSD and DragonFlyBSD (if available at compile + * time); + * - `sysctl(KERN_ARND)` on FreeBSD and NetBSD; + * - #MBEDTLS_PLATFORM_DEV_RANDOM on Unix-like platforms + * (unless one of the above is used); + * - BCryptGenRandom() on Windows. + * * Uncomment this macro to disable the built-in platform entropy functions. */ //#define MBEDTLS_NO_PLATFORM_ENTROPY @@ -4140,6 +4154,37 @@ //#define MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO int64_t //#define MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO int64_t /**< Default milliseconds time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled. It must be signed, and at least 64 bits. If it is changed from the default, MBEDTLS_PRINTF_MS_TIME must be updated to match.*/ //#define MBEDTLS_PRINTF_MS_TIME PRId64 /**< Default fmt for printf. That's avoid compiler warning if mbedtls_ms_time_t is redefined */ +/** \def MBEDTLS_PLATFORM_DEV_RANDOM + * + * Path to a special file that returns cryptographic-quality random bytes + * when read. This is used by the default platform entropy source on + * non-Windows platforms unless a dedicated system call is available + * (see #MBEDTLS_NO_PLATFORM_ENTROPY). + * + * The default value is `/dev/random`, which is suitable on most platforms + * other than Linux. On Linux, either `/dev/random` or `/dev/urandom` + * may be the right choice, depending on the circumstances: + * + * - If possible, the library will use the getrandom() system call, + * which is preferable, and #MBEDTLS_PLATFORM_DEV_RANDOM is not used. + * - If there is a dedicated hardware entropy source (e.g. RDRAND on x86 + * processors), then both `/dev/random` and `/dev/urandom` are fine. + * - `/dev/random` is always secure. However, with kernels older than 5.6, + * `/dev/random` often blocks unnecessarily if there is no dedicated + * hardware entropy source. + * - `/dev/urandom` never blocks. However, it may return predictable data + * if it is used early after the kernel boots, especially on embedded + * devices without an interactive user. + * + * Thus you should change the value to `/dev/urandom` if your application + * definitely won't be used on a device running Linux without a dedicated + * entropy source early during or after boot. + * + * This is the default value of ::mbedtls_platform_dev_random, which + * can be changed at run time. + */ +//#define MBEDTLS_PLATFORM_DEV_RANDOM "/dev/random" + /** \def MBEDTLS_CHECK_RETURN * * This macro is used at the beginning of the declaration of a function diff --git a/vendor/mbedtls/include/mbedtls/pk.h b/vendor/mbedtls/include/mbedtls/pk.h index 2b7f34b..68b0f4b 100644 --- a/vendor/mbedtls/include/mbedtls/pk.h +++ b/vendor/mbedtls/include/mbedtls/pk.h @@ -218,8 +218,11 @@ typedef struct mbedtls_pk_info_t mbedtls_pk_info_t; * \brief Public key container */ typedef struct mbedtls_pk_context { - const mbedtls_pk_info_t *MBEDTLS_PRIVATE(pk_info); /**< Public key information */ - void *MBEDTLS_PRIVATE(pk_ctx); /**< Underlying public key context */ + /** Method table */ + const mbedtls_pk_info_t *MBEDTLS_PRIVATE(pk_info); + /** Underlying type-specific key context */ + void *MBEDTLS_PRIVATE(pk_ctx); + /* The following field is used to store the ID of a private key in the * following cases: * - opaque key when MBEDTLS_USE_PSA_CRYPTO is defined @@ -838,7 +841,7 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, * length up to the hash length), depending on the padding mode * in the underlying RSA context. For a pk object constructed * by parsing, this is PKCS#1 v1.5 by default. Use - * mbedtls_pk_verify_ext() to explicitly select a different + * mbedtls_pk_sign_ext() to explicitly select a different * algorithm. * * \return 0 on success, or a specific error code. diff --git a/vendor/mbedtls/include/mbedtls/platform.h b/vendor/mbedtls/include/mbedtls/platform.h index de3d71d..f1ec997 100644 --- a/vendor/mbedtls/include/mbedtls/platform.h +++ b/vendor/mbedtls/include/mbedtls/platform.h @@ -385,6 +385,37 @@ int mbedtls_platform_set_exit(void (*exit_func)(int status)); #define MBEDTLS_EXIT_FAILURE 1 #endif +#if defined(MBEDTLS_ENTROPY_C) && \ + !defined(MBEDTLS_NO_PLATFORM_ENTROPY) && \ + !(defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)) +/* Platforms where MBEDTLS_PLATFORM_DEV_RANDOM is used + * unless a dedicated system call is available both at + * compile time and at run time. */ +#define MBEDTLS_PLATFORM_HAVE_DEV_RANDOM +#endif + +#if !defined(MBEDTLS_PLATFORM_DEV_RANDOM) +#define MBEDTLS_PLATFORM_DEV_RANDOM "/dev/random" +#endif + +/* Arrange for mbedtls_platform_dev_random to always be visible to + * Doxygen, because it's linked from the documentation of + * MBEDTLS_PLATFORM_DEV_RANDOM and that documentation can be visible + * even in configurations where it isn't used. */ +#if defined(MBEDTLS_PLATFORM_HAVE_DEV_RANDOM) || defined(__DOXYGEN__) +/** + * Path to a special file that returns cryptographic-quality random bytes + * when read. + * + * This variable is only declared on platforms where it is used. + * It is available when the macro `MBEDTLS_PLATFORM_HAVE_DEV_RANDOM` is defined. + * + * The default value is #MBEDTLS_PLATFORM_DEV_RANDOM. + * See the documentation of this option for guidance. + */ +extern const char *mbedtls_platform_dev_random; +#endif + /* * The function pointers for reading from and writing a seed file to * Non-Volatile storage (NV) in a platform-independent way diff --git a/vendor/mbedtls/include/mbedtls/ssl.h b/vendor/mbedtls/include/mbedtls/ssl.h index 3cdddf7..43d8175 100644 --- a/vendor/mbedtls/include/mbedtls/ssl.h +++ b/vendor/mbedtls/include/mbedtls/ssl.h @@ -3357,6 +3357,27 @@ int mbedtls_ssl_set_session(mbedtls_ssl_context *ssl, const mbedtls_ssl_session * On server, this can be used for alternative implementations * of session cache or session tickets. * + * \warning The serialized data contains highly sensitive material, + * including a resumption key (TLS 1.3) or the master secret + * (TLS 1.2) from which the session's traffic keys are derived. + * + * The serialized data is not cryptographically protected. + * It is the responsibility of the user of the + * mbedtls_ssl_session_save() and + * mbedtls_ssl_session_load() APIs to ensure both its + * confidentiality and integrity while stored or transported. + * + * A breach of confidentiality could result in full compromise + * of the associated TLS session, including loss of + * confidentiality and integrity of past and future + * application data protected under that session. + * + * A breach of integrity may allow modification of the + * serialized data prior to restoration. As it represents + * trusted internal context, tampering could potentially result + * in arbitrary code execution or other severe compromise of + * the hosting process. + * * \warning If a peer certificate chain is associated with the session, * the serialized state will only contain the peer's * end-entity certificate and the result of the chain @@ -3395,6 +3416,19 @@ int mbedtls_ssl_session_load(mbedtls_ssl_session *session, * * \see mbedtls_ssl_session_load() * + * \warning The serialized data contains highly sensitive material, + * including a resumption key (TLS 1.3) or the master secret + * (TLS 1.2) from which the session's traffic keys are derived. + * + * The serialized data is not cryptographically protected. + * It is the responsibility of the user of the + * mbedtls_ssl_session_save() and + * mbedtls_ssl_session_load() APIs to ensure both its + * confidentiality and integrity while stored or transported. + * + * See the mbedtls_ssl_session_load() documentation for + * additional information. + * * \param session The session structure to be saved. * \param buf The buffer to write the serialized data to. It must be a * writeable buffer of at least \p buf_len bytes, or may be \c @@ -5084,13 +5118,6 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * supported with some limitations (those limitations do * not apply to DTLS, where defragmentation is fully * supported): - * - On an Mbed TLS server that only accepts TLS 1.2, - * the initial ClientHello message must not be fragmented. - * A TLS 1.2 ClientHello may be fragmented if the server - * also accepts TLS 1.3 connections (meaning - * that #MBEDTLS_SSL_PROTO_TLS1_3 enabled, and the - * accepted versions have not been restricted with - * mbedtls_ssl_conf_max_tls_version() or the like). * - The first fragment of a handshake message must be * at least 4 bytes long. * - Non-handshake records must not be interleaved between @@ -5577,6 +5604,19 @@ void mbedtls_ssl_free(mbedtls_ssl_context *ssl); * * \see mbedtls_ssl_context_load() * + * \warning The serialized data contains highly sensitive material, + * including the master secret from which the session's traffic + * keys are derived. + * + * The serialized data is not cryptographically protected. + * It is the responsibility of the user of the + * mbedtls_ssl_context_save() and + * mbedtls_ssl_context_load() APIs to ensure both its + * confidentiality and integrity while stored or transported. + * + * See the mbedtls_ssl_context_load() documentation for + * additional information. + * * \note The serialized data only contains the data that is * necessary to resume the connection: negotiated protocol * options, session identifier, keys, etc. @@ -5643,6 +5683,27 @@ int mbedtls_ssl_context_save(mbedtls_ssl_context *ssl, * more than one context would cause severe security failures * including but not limited to loss of confidentiality. * + * \warning The serialized data contains highly sensitive material, + * including the master secret from which the session's traffic + * keys are derived. + * + * The serialized data is not cryptographically protected. + * It is the responsibility of the user of the + * mbedtls_ssl_context_save() and + * mbedtls_ssl_context_load() APIs to ensure both its + * confidentiality and integrity while stored or transported. + * + * A breach of confidentiality could result in full compromise + * of the associated TLS session, including loss of + * confidentiality and integrity of past and future + * application data protected under that session. + * + * A breach of integrity may allow modification of the + * serialized data prior to restoration. As it represents + * trusted internal context, tampering could potentially result + * in arbitrary code execution or other severe compromise of + * the hosting process. + * * \note Before calling this function, the SSL context must be * prepared in one of the two following ways. The first way is * to take a context freshly initialised with diff --git a/vendor/mbedtls/include/psa/crypto_extra.h b/vendor/mbedtls/include/psa/crypto_extra.h index a710397..0356630 100644 --- a/vendor/mbedtls/include/psa/crypto_extra.h +++ b/vendor/mbedtls/include/psa/crypto_extra.h @@ -33,13 +33,32 @@ extern "C" { #endif /* If the size of static key slots is not explicitly defined by the user, then - * set it to the maximum between PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE and - * PSA_CIPHER_MAX_KEY_LENGTH. - * See mbedtls_config.h for the definition. */ + * try to guess it based on some of the most common the key types enabled in the build. + * See mbedtls_config.h for the definition of MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE. */ #if !defined(MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE) -#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE \ - ((PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE > PSA_CIPHER_MAX_KEY_LENGTH) ? \ - PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE : PSA_CIPHER_MAX_KEY_LENGTH) + +#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE 1 + +#if PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE > MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE +#undef MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE +#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE +#endif + +/* This covers ciphers, AEADs and CMAC. */ +#if PSA_CIPHER_MAX_KEY_LENGTH > MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE +#undef MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE +#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE PSA_CIPHER_MAX_KEY_LENGTH +#endif + +/* For HMAC, it's typical but not mandatory to use a key size that is equal to + * the hash size. */ +#if defined(PSA_WANT_ALG_HMAC) +#if PSA_HASH_MAX_SIZE > MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE +#undef MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE +#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE PSA_HASH_MAX_SIZE +#endif +#endif /* PSA_WANT_ALG_HMAC */ + #endif /* !MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE*/ /** \addtogroup attributes @@ -434,7 +453,7 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, /**@}*/ -/** \defgroup psa_external_rng External random generator +/** \defgroup psa_rng Random generator * @{ */ @@ -483,6 +502,155 @@ psa_status_t mbedtls_psa_external_get_random( uint8_t *output, size_t output_size, size_t *output_length); #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ +/** Force an immediate reseed of the PSA random generator. + * + * The entropy source(s) are the ones configured at compile time. + * + * The random generator is always seeded automatically before use, and + * it is reseeded as needed based on the configured policy, so most + * applications do not need to call this function. + * + * The main reason to call this function is in scenarios where the process + * state is cloned (i.e. duplicated) while the random generator is active. + * In such scenarios, you must call this function in every clone of + * the original process before performing any cryptographic operation + * that uses randomness. (Note that any operation that uses a private or + * secret key may use randomness internally even if the result is not + * randomized, but hashing and signature verification are ok.) For example: + * + * - If the process is part of a live virtual machine that is cloned, + * call this function after cloning so that the new instance has a + * distinct random generator state. + * - If the process is part of a hibernated image that may be resumed + * multiple times, call this function after resuming so that each + * resumed instance has a distinct random generator state. + * - If the process is cloned through the fork() system call, the + * child process should call this function before using the random + * generator. + * + * An additional consideration applies in configurations where there is no + * actual entropy source, only a nonvolatile seed (i.e. + * #MBEDTLS_ENTROPY_NV_SEED is enabled, #MBEDTLS_NO_PLATFORM_ENTROPY is + * enabled and #MBEDTLS_ENTROPY_HARDWARE_ALT is disabled). + * In such configurations, simply calling psa_random_reseed() in multiple + * cloned processes would result in the same random generator state in + * all the clones. To avoid this, in such configurations, you must pass + * a unique \p perso string in every clone. + * + * \note This function has no effect when the compilation option + * #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled. + * + * \note In client-server builds, this function may not be available + * from clients, since the decision to reseed is generally based + * on the server state. + * + * \note If the entropy source fails, the random generator remains usable: + * subsequent calls to generate random data will succeed until + * the random generator itself decides to reseed. If you want to + * force a reseed, either treat the failure as a fatal error, + * or call psa_random_deplete() instead of this function (or in + * addition). + * + * \param[in] perso A personalization string, i.e. a byte string to + * inject into the random generator state in addition + * to entropy obtained from the normal source(s). + * In most cases, it is fine for \c perso to be + * empty. The main use case for a personalization + * string is when the random generator state is cloned, + * as described above, and there is no actual entropy + * source. + * \param perso_size Length of \c perso in bytes. + * + * \retval #PSA_SUCCESS + * The reseed succeeded. + * \retval #PSA_ERROR_BAD_STATE + * The PSA random generator is not active. + * \retval #PSA_ERROR_NOT_SUPPORTED + * PSA uses an external random generator because the compilation + * option #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled. This + * configuration does not support explicit reseeding. + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * The entropy source failed. + */ +psa_status_t psa_random_reseed(const uint8_t *perso, size_t perso_size); + +/** Force a reseed of the PSA random generator the next time it is used. + * + * The entropy source(s) are the ones configured at compile time. + * + * The random generator is always seeded automatically before use, and + * it is reseeded as needed based on the configured policy, so most + * applications do not need to call this function. + * + * This function has a similar purpose as psa_random_reseed(), + * but the reseed will happen the next time the random generator is used. + * The advantage of this function is that it does not fail unless the + * system is in an unintended state, so it can be used in contexts where + * propagating errors is difficult. + * + * \note This function has no effect when #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + * is enabled. + * + * \note If prediction resistance is enabled (either explicitly, or because + * the reseed interval is set to 1), calling this function is + * unnecessary since the random generator will always reseed anyway. + * + * \retval #PSA_SUCCESS + * The reseed succeeded. + * \retval #PSA_ERROR_BAD_STATE + * The PSA random generator is not active. + * \retval #PSA_ERROR_NOT_SUPPORTED + * PSA uses an external random generator because the compilation + * option #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled. This + * configuration does not support explicit reseeding. + */ +psa_status_t psa_random_deplete(void); + +/** Enable or disable prediction resistance in the PSA random generator. + * + * When prediction resistance is enabled, the random generator + * injects extra entropy before each request regardless of its size. + * As a consequence, a temporary compromise of the random generator + * state does not, by itself, compromise future steps. + * Furthermore, duplicating the random generator state (because the + * running application instance is cloned) is safe since it will + * not lead to identical random generator outputs in the clones. + * + * When prediction resistance is disabled, the random generator injects + * extra entropy periodically only as determined by + * #MBEDTLS_CTR_DRBG_RESEED_INTERVAL if #MBEDTLS_CTR_DRBG_C + * is enabled, or #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL otherwise. + * + * Prediction resistance is disabled by default, although setting + * #MBEDTLS_CTR_DRBG_RESEED_INTERVAL or #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL + * to \c 1 satisfies the prediction resistance property even when the + * option is disabled. + * + * \note This function has no effect when #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + * is enabled. + * + * \note Prediction resistance cannot be enabled when the only entropy source + * is a nonvolatile seed, since prediction resistance is effectively + * impossible to achieve without actual entropy. + * + * \param enabled \c 1 to enable prediction resistance. + * \c 0 to disable prediction resistance. + * + * \retval #PSA_SUCCESS + * The PSA random generator is active, and prediction resistance + * has been changed to the desired option. + * \retval #PSA_ERROR_BAD_STATE + * The PSA random generator is not active. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p enabled is not valid. + * \retval #PSA_ERROR_NOT_SUPPORTED + * PSA uses an external random generator because the compilation + * option #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled. + * Or, the random generator only has a nonvolatile seed but no entropy + * source, and prediction resistance has been requested. + */ +psa_status_t psa_random_set_prediction_resistance(unsigned enabled); + /**@}*/ /** \defgroup psa_builtin_keys Built-in keys diff --git a/vendor/mbedtls/include/psa/crypto_sizes.h b/vendor/mbedtls/include/psa/crypto_sizes.h index 87b8c39..1bf84de 100644 --- a/vendor/mbedtls/include/psa/crypto_sizes.h +++ b/vendor/mbedtls/include/psa/crypto_sizes.h @@ -912,15 +912,11 @@ * If the parameters are not valid, the return value is unspecified. */ #define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \ - (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \ - PSA_KEY_TYPE_IS_DH(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \ - (key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \ + ((key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \ (key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ - (key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \ - (key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \ PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ - 0u) + PSA_BITS_TO_BYTES(key_bits)) /*unstructured; FFDH public or private*/ /** Sufficient output buffer size for psa_export_public_key(). * @@ -1038,10 +1034,16 @@ PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) #endif -#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \ +/* This is the name that was standardized in PSA Crypto v1.3 */ +#define PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE \ ((PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \ PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) +/* This is our old custom name from before it was in the spec, + * keep it around in case users were relying on it. */ +#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \ + PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE + /** Sufficient output buffer size for psa_raw_key_agreement(). * * This macro returns a compile-time constant if its arguments are diff --git a/vendor/mbedtls/library/aesce.c b/vendor/mbedtls/library/aesce.c index 6a9e0a1..06a8bdc 100644 --- a/vendor/mbedtls/library/aesce.c +++ b/vendor/mbedtls/library/aesce.c @@ -16,15 +16,16 @@ #endif #if defined(MBEDTLS_AESCE_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO) -/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged. - * - * The intrinsic declaration are guarded by predefined ACLE macros in clang: +/* The intrinsic declaration are guarded by predefined ACLE macros in clang: * these are normally only enabled by the -march option on the command line. * By defining the macros ourselves we gain access to those declarations without * requiring -march on the command line. * * `arm_neon.h` is included by common.h, so we put these defines - * at the top of this file, before any includes. + * at the top of this file, before any includes. This is necessary with + * Clang <=15.x. With Clang 16.0 and above, these macro definitions are + * no longer required, but they're harmless. See + * https://reviews.llvm.org/D131064 */ #define __ARM_FEATURE_CRYPTO 1 /* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions @@ -38,11 +39,12 @@ #endif /* defined(__clang__) && (__clang_major__ >= 4) */ -#include #include "common.h" #if defined(MBEDTLS_AESCE_C) +#include + #include "aesce.h" #if defined(MBEDTLS_AESCE_HAVE_CODE) @@ -86,7 +88,11 @@ # define MBEDTLS_POP_TARGET_PRAGMA # endif # elif defined(__clang__) -# pragma clang attribute push (__attribute__((target("aes"))), apply_to=function) +# if __clang_major__ < 7 +# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function) +# else +# pragma clang attribute push (__attribute__((target("aes"))), apply_to=function) +# endif # define MBEDTLS_POP_TARGET_PRAGMA # elif defined(__GNUC__) # pragma GCC push_options diff --git a/vendor/mbedtls/library/alignment.h b/vendor/mbedtls/library/alignment.h index a17001d..d304133 100644 --- a/vendor/mbedtls/library/alignment.h +++ b/vendor/mbedtls/library/alignment.h @@ -15,6 +15,7 @@ #include #include +#if !defined(MBEDTLS_ALIGNMENT_DISABLE_EFFICENT_UNALIGNED_ACCESS) //no-check-names /* * Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory * accesses are known to be efficient. @@ -35,7 +36,9 @@ * device memory). */ #define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS -#endif +#endif /* __ARM_FEATURE_UNALIGNED || MBEDTLS_ARCH_IS_X86 || MBEDTLS_ARCH_IS_X64 || + * MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64 */ +#endif /* MBEDTLS_ALIGNMENT_DISABLE_EFFICENT_UNALIGNED_ACCESS */ //no-check-names #if defined(__IAR_SYSTEMS_ICC__) && \ (defined(MBEDTLS_ARCH_IS_ARM64) || defined(MBEDTLS_ARCH_IS_ARM32) \ @@ -85,13 +88,13 @@ typedef uint64_t __packed mbedtls_uint64_unaligned_t; #define UINT_UNALIGNED_STRUCT typedef struct { uint16_t x; -} __attribute__((packed)) mbedtls_uint16_unaligned_t; +} __attribute__((packed, may_alias)) mbedtls_uint16_unaligned_t; typedef struct { uint32_t x; -} __attribute__((packed)) mbedtls_uint32_unaligned_t; +} __attribute__((packed, may_alias)) mbedtls_uint32_unaligned_t; typedef struct { uint64_t x; -} __attribute__((packed)) mbedtls_uint64_unaligned_t; +} __attribute__((packed, may_alias)) mbedtls_uint64_unaligned_t; #endif /* @@ -277,15 +280,15 @@ static inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x) /* * Detect GCC built-in byteswap routines */ -#if defined(__GNUC__) && defined(__GNUC_PREREQ) -#if __GNUC_PREREQ(4, 8) +#if defined(__GNUC__) +#if MBEDTLS_GCC_VERSION >= 40800 #define MBEDTLS_BSWAP16 __builtin_bswap16 -#endif /* __GNUC_PREREQ(4,8) */ -#if __GNUC_PREREQ(4, 3) +#endif +#if MBEDTLS_GCC_VERSION >= 40300 #define MBEDTLS_BSWAP32 __builtin_bswap32 #define MBEDTLS_BSWAP64 __builtin_bswap64 -#endif /* __GNUC_PREREQ(4,3) */ -#endif /* defined(__GNUC__) && defined(__GNUC_PREREQ) */ +#endif +#endif /* defined(__GNUC__) */ /* * Detect Clang built-in byteswap routines diff --git a/vendor/mbedtls/library/base64.c b/vendor/mbedtls/library/base64.c index 388fa9f..25c960a 100644 --- a/vendor/mbedtls/library/base64.c +++ b/vendor/mbedtls/library/base64.c @@ -5,8 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ -#include - #include "common.h" #if defined(MBEDTLS_BASE64_C) @@ -16,6 +14,7 @@ #include "constant_time_internal.h" #include "mbedtls/error.h" +#include #include #if defined(MBEDTLS_SELF_TEST) diff --git a/vendor/mbedtls/library/ccm.c b/vendor/mbedtls/library/ccm.c index 969c6c7..6a4fbb0 100644 --- a/vendor/mbedtls/library/ccm.c +++ b/vendor/mbedtls/library/ccm.c @@ -177,6 +177,7 @@ static int ccm_calculate_first_block_if_ready(mbedtls_ccm_context *ctx) ctx->plaintext_len = 0; return 0; } else { + ctx->state |= CCM_STATE__ERROR; return MBEDTLS_ERR_CCM_BAD_INPUT; } } @@ -480,6 +481,14 @@ int mbedtls_ccm_finish(mbedtls_ccm_context *ctx, return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; } + if (!(ctx->state & CCM_STATE__STARTED)) { + return MBEDTLS_ERR_CCM_BAD_INPUT; + } + + if (!(ctx->state & CCM_STATE__LENGTHS_SET)) { + return MBEDTLS_ERR_CCM_BAD_INPUT; + } + if (ctx->add_len > 0 && !(ctx->state & CCM_STATE__AUTH_DATA_FINISHED)) { return MBEDTLS_ERR_CCM_BAD_INPUT; } @@ -488,6 +497,10 @@ int mbedtls_ccm_finish(mbedtls_ccm_context *ctx, return MBEDTLS_ERR_CCM_BAD_INPUT; } + if (tag_len != ctx->tag_len) { + return MBEDTLS_ERR_CCM_BAD_INPUT; + } + /* * Authentication: reset counter and crypt/mask internal tag */ diff --git a/vendor/mbedtls/library/check_crypto_config.h b/vendor/mbedtls/library/check_crypto_config.h index 6469e9f..f1ed7f5 100644 --- a/vendor/mbedtls/library/check_crypto_config.h +++ b/vendor/mbedtls/library/check_crypto_config.h @@ -128,11 +128,6 @@ #error "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE defined, but feature is not supported" #endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_USE_PSA_CRYPTO) && \ - !(defined(PSA_WANT_ALG_SHA_1) || defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_512)) -#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" -#endif - #if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) && \ !defined(PSA_WANT_ALG_SHA_256) #error "PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS defined, but not all prerequisites" diff --git a/vendor/mbedtls/library/common.h b/vendor/mbedtls/library/common.h index 50f2a29..1f59b32 100644 --- a/vendor/mbedtls/library/common.h +++ b/vendor/mbedtls/library/common.h @@ -27,6 +27,24 @@ #define MBEDTLS_HAVE_NEON_INTRINSICS #endif +/* Decide whether we're built for a Unix-like platform. + */ +#if defined(MBEDTLS_TEST_PLATFORM_IS_NOT_UNIXLIKE) //no-check-names +/* We may be building on a Unix-like platform, but for test purposes, + * do not try to use Unix features. */ +#elif defined(_WIN32) +/* If Windows platform interfaces are available, we use them, even if + * a Unix-like might also to be available. */ +/* defined(_WIN32) ==> we can include */ +#elif defined(unix) || defined(__unix) || defined(__unix__) || \ + (defined(__APPLE__) && defined(__MACH__)) || \ + defined(__HAIKU__) || \ + defined(__midipix__) || \ + /* Add other Unix-like platform indicators here ^^^^ */ 0 +/* defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) ==> we can include */ +#define MBEDTLS_PLATFORM_IS_UNIXLIKE +#endif + /** Helper to define a function as static except when building invasive tests. * * If a function is only used inside its own source file and should be @@ -99,6 +117,13 @@ extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const cha * fall back to the unsafe implementation. */ #define ARRAY_LENGTH(array) ARRAY_LENGTH_UNSAFE(array) #endif + +#if defined(__has_builtin) +#define MBEDTLS_HAS_BUILTIN(x) __has_builtin(x) +#else +#define MBEDTLS_HAS_BUILTIN(x) 0 +#endif + /** Allow library to access its structs' private members. * * Although structs defined in header files are publicly available, @@ -208,6 +233,11 @@ static inline void mbedtls_xor(unsigned char *r, return; } #endif +#if defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_HAS_BUILTIN(__builtin_constant_p) + if (__builtin_constant_p(n) && n % 16 == 0) { + return; + } +#endif #elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64) /* This codepath probably only makes sense on architectures with 64-bit registers */ for (; (i + 8) <= n; i += 8) { @@ -219,6 +249,11 @@ static inline void mbedtls_xor(unsigned char *r, return; } #endif +#if defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_HAS_BUILTIN(__builtin_constant_p) + if (__builtin_constant_p(n) && n % 8 == 0) { + return; + } +#endif #else for (; (i + 4) <= n; i += 4) { uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); @@ -229,6 +264,11 @@ static inline void mbedtls_xor(unsigned char *r, return; } #endif +#if defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_HAS_BUILTIN(__builtin_constant_p) + if (__builtin_constant_p(n) && n % 4 == 0) { + return; + } +#endif #endif #endif for (; i < n; i++) { @@ -367,12 +407,6 @@ static inline void mbedtls_xor_no_simd(unsigned char *r, struct ISO_C_does_not_allow_extra_semicolon_outside_of_a_function #endif -#if defined(__has_builtin) -#define MBEDTLS_HAS_BUILTIN(x) __has_builtin(x) -#else -#define MBEDTLS_HAS_BUILTIN(x) 0 -#endif - /* Define compiler branch hints */ #if MBEDTLS_HAS_BUILTIN(__builtin_expect) #define MBEDTLS_LIKELY(x) __builtin_expect(!!(x), 1) diff --git a/vendor/mbedtls/library/constant_time.c b/vendor/mbedtls/library/constant_time.c index d212ddf..afea99c 100644 --- a/vendor/mbedtls/library/constant_time.c +++ b/vendor/mbedtls/library/constant_time.c @@ -10,15 +10,14 @@ * might be translated to branches by some compilers on some platforms. */ -#include -#include - #include "common.h" #include "constant_time_internal.h" #include "mbedtls/constant_time.h" #include "mbedtls/error.h" #include "mbedtls/platform_util.h" +#include +#include #include #if !defined(MBEDTLS_CT_ASM) diff --git a/vendor/mbedtls/library/ctr_drbg.c b/vendor/mbedtls/library/ctr_drbg.c index b82044e..bbbfdac 100644 --- a/vendor/mbedtls/library/ctr_drbg.c +++ b/vendor/mbedtls/library/ctr_drbg.c @@ -494,7 +494,7 @@ static int mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context *ctx, if ((ret = ctr_drbg_update_internal(ctx, seed)) != 0) { goto exit; } - ctx->reseed_counter = 1; + ctx->reseed_counter = 0; exit: mbedtls_platform_zeroize(seed, sizeof(seed)); @@ -629,7 +629,7 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, memset(locals.add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN); - if (ctx->reseed_counter > ctx->reseed_interval || + if (ctx->reseed_counter >= ctx->reseed_interval || ctx->prediction_resistance) { if ((ret = mbedtls_ctr_drbg_reseed(ctx, additional, add_len)) != 0) { return ret; diff --git a/vendor/mbedtls/library/debug.c b/vendor/mbedtls/library/debug.c index c36ed3c..24c6253 100644 --- a/vendor/mbedtls/library/debug.c +++ b/vendor/mbedtls/library/debug.c @@ -21,6 +21,16 @@ /* DEBUG_BUF_SIZE must be at least 2 */ #define DEBUG_BUF_SIZE 512 +int mbedtls_debug_snprintf(char *dest, size_t maxlen, + const char *format, ...) +{ + va_list argp; + va_start(argp, format); + int ret = mbedtls_vsnprintf(dest, maxlen, format, argp); + va_end(argp); + return ret; +} + static int debug_threshold = 0; void mbedtls_debug_set_threshold(int threshold) diff --git a/vendor/mbedtls/library/debug_internal.h b/vendor/mbedtls/library/debug_internal.h index 4523b46..2dd2599 100644 --- a/vendor/mbedtls/library/debug_internal.h +++ b/vendor/mbedtls/library/debug_internal.h @@ -12,6 +12,19 @@ #include "mbedtls/debug.h" +/* This should be equivalent to mbedtls_snprintf(). But it might not be due + * to platform shenanigans. For example, Mbed TLS and TF-PSA-Crypto could + * have inconsistent platform definitions. On Mingw, some code might + * be built with a different setting of __USE_MINGW_ANSI_STDIO, resulting + * in an old non-C99 printf being used somewhere. + * + * Our library assumes that mbedtls_snprintf() and other printf functions + * are consistent throughout. This function is not an official API and + * is not meant to be used inside the library. It is provided to help + * debugging printf inconsistencies issues. If you need it, good luck! + */ +int mbedtls_debug_snprintf(char *dest, size_t maxlen, + const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(3, 4); /** * \brief Print a message to the debug output. This function is always used * through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl diff --git a/vendor/mbedtls/library/entropy_poll.c b/vendor/mbedtls/library/entropy_poll.c index 611768c..1c8a29d 100644 --- a/vendor/mbedtls/library/entropy_poll.c +++ b/vendor/mbedtls/library/entropy_poll.c @@ -147,6 +147,8 @@ static int sysctl_arnd_wrapper(unsigned char *buf, size_t buflen) #include +const char *mbedtls_platform_dev_random = MBEDTLS_PLATFORM_DEV_RANDOM; + int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen) { @@ -180,7 +182,7 @@ int mbedtls_platform_entropy_poll(void *data, *olen = 0; - file = fopen("/dev/urandom", "rb"); + file = fopen(mbedtls_platform_dev_random, "rb"); if (file == NULL) { return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; } diff --git a/vendor/mbedtls/library/hmac_drbg.c b/vendor/mbedtls/library/hmac_drbg.c index 90174d5..d519628 100644 --- a/vendor/mbedtls/library/hmac_drbg.c +++ b/vendor/mbedtls/library/hmac_drbg.c @@ -196,7 +196,7 @@ static int hmac_drbg_reseed_core(mbedtls_hmac_drbg_context *ctx, } /* 3. Reset reseed_counter */ - ctx->reseed_counter = 1; + ctx->reseed_counter = 0; exit: /* 4. Done */ @@ -326,7 +326,7 @@ int mbedtls_hmac_drbg_random_with_add(void *p_rng, /* 1. (aka VII and IX) Check reseed counter and PR */ if (ctx->f_entropy != NULL && /* For no-reseeding instances */ (ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || - ctx->reseed_counter > ctx->reseed_interval)) { + ctx->reseed_counter >= ctx->reseed_interval)) { if ((ret = mbedtls_hmac_drbg_reseed(ctx, additional, add_len)) != 0) { return ret; } diff --git a/vendor/mbedtls/library/net_sockets.c b/vendor/mbedtls/library/net_sockets.c index 1419c78..c919f6f 100644 --- a/vendor/mbedtls/library/net_sockets.c +++ b/vendor/mbedtls/library/net_sockets.c @@ -19,9 +19,7 @@ #if defined(MBEDTLS_NET_C) -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) && !defined(__midipix__) +#if !defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) && !defined(_WIN32) #error "This module only works on Unix and Windows, see MBEDTLS_NET_C in mbedtls_config.h" #endif diff --git a/vendor/mbedtls/library/pk.c b/vendor/mbedtls/library/pk.c index 51f0c24..b5d76db 100644 --- a/vendor/mbedtls/library/pk.c +++ b/vendor/mbedtls/library/pk.c @@ -35,6 +35,31 @@ #include #include +#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) +#include "mbedtls/platform.h" // for calloc/free +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +#define MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) + +#define MBEDTLS_PK_MAX_RSA_PUBKEY_RAW_LEN \ + PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) + +#define MBEDTLS_PK_MAX_PUBKEY_RAW_LEN 0 +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && \ + MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN > MBEDTLS_PK_MAX_PUBKEY_RAW_LEN +#undef MBEDTLS_PK_MAX_PUBKEY_RAW_LEN +#define MBEDTLS_PK_MAX_PUBKEY_RAW_LEN MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN +#endif +#if (defined(MBEDTLS_RSA_C) || \ + (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))) && \ + MBEDTLS_PK_MAX_RSA_PUBKEY_RAW_LEN > MBEDTLS_PK_MAX_PUBKEY_RAW_LEN +#undef MBEDTLS_PK_MAX_PUBKEY_RAW_LEN +#define MBEDTLS_PK_MAX_PUBKEY_RAW_LEN MBEDTLS_PK_MAX_RSA_PUBKEY_RAW_LEN +#endif +#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ + /* * Initialise a mbedtls_pk_context */ @@ -586,19 +611,44 @@ int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_USE_PSA_CRYPTO) static psa_status_t export_import_into_psa(mbedtls_svc_key_id_t old_key_id, + psa_key_type_t old_type, size_t old_bits, const psa_key_attributes_t *attributes, mbedtls_svc_key_id_t *new_key_id) { - unsigned char key_buffer[PSA_EXPORT_KEY_PAIR_MAX_SIZE]; +#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) + unsigned char *key_buffer = NULL; + size_t key_buffer_size = 0; +#else + unsigned char key_buffer[PK_EXPORT_KEY_STACK_BUFFER_SIZE]; + const size_t key_buffer_size = sizeof(key_buffer); +#endif size_t key_length = 0; + + /* We are exporting from a PK object, so we know key type is valid for PK */ +#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) + key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(old_type, old_bits); + key_buffer = mbedtls_calloc(1, key_buffer_size); + if (key_buffer == NULL) { + return MBEDTLS_ERR_PK_ALLOC_FAILED; + } +#else + (void) old_type; + (void) old_bits; +#endif + psa_status_t status = psa_export_key(old_key_id, - key_buffer, sizeof(key_buffer), + key_buffer, key_buffer_size, &key_length); if (status != PSA_SUCCESS) { - return status; + goto cleanup; } status = psa_import_key(attributes, key_buffer, key_length, new_key_id); mbedtls_platform_zeroize(key_buffer, key_length); + +cleanup: +#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) + mbedtls_free(key_buffer); +#endif return status; } @@ -628,11 +678,13 @@ static int copy_into_psa(mbedtls_svc_key_id_t old_key_id, return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } psa_key_type_t old_type = psa_get_key_type(&old_attributes); + size_t old_bits = psa_get_key_bits(&old_attributes); psa_reset_key_attributes(&old_attributes); if (old_type != psa_get_key_type(attributes)) { return MBEDTLS_ERR_PK_TYPE_MISMATCH; } - status = export_import_into_psa(old_key_id, attributes, new_key_id); + status = export_import_into_psa(old_key_id, old_type, old_bits, + attributes, new_key_id); } return PSA_PK_TO_MBEDTLS_ERR(status); } @@ -649,20 +701,25 @@ static int import_pair_into_psa(const mbedtls_pk_context *pk, if (psa_get_key_type(attributes) != PSA_KEY_TYPE_RSA_KEY_PAIR) { return MBEDTLS_ERR_PK_TYPE_MISMATCH; } - unsigned char key_buffer[ - PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; - unsigned char *const key_end = key_buffer + sizeof(key_buffer); + size_t key_bits = psa_get_key_bits(attributes); + size_t key_buffer_size = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits); + unsigned char *key_buffer = mbedtls_calloc(1, key_buffer_size); + if (key_buffer == NULL) { + return MBEDTLS_ERR_PK_ALLOC_FAILED; + } + unsigned char *const key_end = key_buffer + key_buffer_size; unsigned char *key_data = key_end; int ret = mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), key_buffer, &key_data); if (ret < 0) { - return ret; + goto cleanup_rsa; } size_t key_length = key_end - key_data; ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, key_data, key_length, key_id)); - mbedtls_platform_zeroize(key_data, key_length); +cleanup_rsa: + mbedtls_zeroize_and_free(key_buffer, key_buffer_size); return ret; } #endif /* MBEDTLS_RSA_C */ @@ -741,7 +798,7 @@ static int import_public_into_psa(const mbedtls_pk_context *pk, #if defined(MBEDTLS_RSA_C) || \ (defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)) || \ defined(MBEDTLS_USE_PSA_CRYPTO) - unsigned char key_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; + unsigned char key_buffer[MBEDTLS_PK_MAX_PUBKEY_RAW_LEN]; #endif unsigned char *key_data = NULL; size_t key_length = 0; @@ -857,6 +914,21 @@ int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, } } +static int is_valid_for_pk(psa_key_type_t key_type) +{ +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) + if (PSA_KEY_TYPE_IS_ECC(key_type)) { + return 1; + } +#endif +#if defined(MBEDTLS_RSA_C) + if (PSA_KEY_TYPE_IS_RSA(key_type)) { + return 1; + } +#endif + return 0; +} + static int copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk, int public_only) @@ -865,8 +937,13 @@ static int copy_from_psa(mbedtls_svc_key_id_t key_id, psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; psa_key_type_t key_type; size_t key_bits; - /* Use a buffer size large enough to contain either a key pair or public key. */ - unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE]; +#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) + unsigned char *exp_key = NULL; + size_t exp_key_size = 0; +#else + unsigned char exp_key[PK_EXPORT_KEY_STACK_BUFFER_SIZE]; + const size_t exp_key_size = sizeof(exp_key); +#endif size_t exp_key_len; int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; @@ -879,10 +956,28 @@ static int copy_from_psa(mbedtls_svc_key_id_t key_id, return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } + key_type = psa_get_key_type(&key_attr); + if (!is_valid_for_pk(key_type)) { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + if (public_only) { - status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); + key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); + } + key_bits = psa_get_key_bits(&key_attr); + +#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) + exp_key_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits); + exp_key = mbedtls_calloc(1, exp_key_size); + if (exp_key == NULL) { + return MBEDTLS_ERR_PK_ALLOC_FAILED; + } +#endif + + if (public_only) { + status = psa_export_public_key(key_id, exp_key, exp_key_size, &exp_key_len); } else { - status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); + status = psa_export_key(key_id, exp_key, exp_key_size, &exp_key_len); } if (status != PSA_SUCCESS) { ret = PSA_PK_TO_MBEDTLS_ERR(status); @@ -964,12 +1059,16 @@ static int copy_from_psa(mbedtls_svc_key_id_t key_id, #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ { (void) key_bits; - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; + goto exit; } exit: + mbedtls_platform_zeroize(exp_key, exp_key_size); +#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) + mbedtls_free(exp_key); +#endif psa_reset_key_attributes(&key_attr); - mbedtls_platform_zeroize(exp_key, sizeof(exp_key)); return ret; } @@ -1146,7 +1245,7 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, #if defined(MBEDTLS_USE_PSA_CRYPTO) if (pss_opts->mgf1_hash_id == md_alg) { - unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES]; + unsigned char buf[PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; unsigned char *p; int key_len; size_t signature_length; diff --git a/vendor/mbedtls/library/pk_internal.h b/vendor/mbedtls/library/pk_internal.h index e86a3a0..d1c2642 100644 --- a/vendor/mbedtls/library/pk_internal.h +++ b/vendor/mbedtls/library/pk_internal.h @@ -44,6 +44,40 @@ #define PEM_BEGIN_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----BEGIN ENCRYPTED PRIVATE KEY-----" #define PEM_END_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----END ENCRYPTED PRIVATE KEY-----" +/* + * We're trying to statisfy two kinds of users: + * - those who don't want to use the heap; + * - those who can't afford large stack buffers. + * + * The current compromise is that if ECC is the only key type supported in PK, + * then we export keys on the stack, and otherwise we use the heap. + * + * RSA can either be used directly or indirectly via opaque keys if enabled. + * (RSA_ALT is not relevant here as we can't export from such contexts.) + */ +#if !defined(MBEDTLS_RSA_C) && \ + !(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)) +#define PK_EXPORT_KEYS_ON_THE_STACK +#endif + +#if defined(PK_EXPORT_KEYS_ON_THE_STACK) +/* We know for ECC, pubkey are longer than privkeys, but double check. + * Also, take the maximum size of legacy and PSA, as PSA might be disabled. */ +#define PK_EXPORT_KEY_STACK_BUFFER_SIZE MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH +#if PK_EXPORT_KEY_STACK_BUFFER_SIZE < MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH +#undef PK_EXPORT_KEY_STACK_BUFFER_SIZE +#define PK_EXPORT_KEY_STACK_BUFFER_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH +#endif +#if PK_EXPORT_KEY_STACK_BUFFER_SIZE < MBEDTLS_ECP_MAX_BYTES +#undef PK_EXPORT_KEY_STACK_BUFFER_SIZE +#define PK_EXPORT_KEY_STACK_BUFFER_SIZE MBEDTLS_ECP_MAX_BYTES +#endif +#if PK_EXPORT_KEY_STACK_BUFFER_SIZE < MBEDTLS_ECP_MAX_PT_LEN +#undef PK_EXPORT_KEY_STACK_BUFFER_SIZE +#define PK_EXPORT_KEY_STACK_BUFFER_SIZE MBEDTLS_ECP_MAX_PT_LEN +#endif +#endif + #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA) /** * Public function mbedtls_pk_ec() can be used to get direct access to the diff --git a/vendor/mbedtls/library/pk_wrap.c b/vendor/mbedtls/library/pk_wrap.c index 19196b5..5265469 100644 --- a/vendor/mbedtls/library/pk_wrap.c +++ b/vendor/mbedtls/library/pk_wrap.c @@ -72,7 +72,7 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; psa_status_t status; int key_len; - unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES]; + unsigned char buf[PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; unsigned char *p = buf + sizeof(buf); psa_algorithm_t psa_alg_md; size_t rsa_len = mbedtls_rsa_get_len(rsa); @@ -288,9 +288,6 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk, psa_algorithm_t psa_md_alg, decrypt_alg; psa_status_t status; int key_len; - unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES]; - unsigned char *p = buf + sizeof(buf); - ((void) f_rng); ((void) p_rng); @@ -298,6 +295,13 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk, return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; } + const size_t key_bits = mbedtls_pk_get_bitlen(pk); + /* mbedtls_rsa_write_key() uses the same format as PSA export, which + * actually calls it under the hood, so we can use the PSA size macro. */ + const size_t buf_size = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits); + unsigned char *buf = mbedtls_calloc(1, buf_size); + + unsigned char *p = buf + buf_size; key_len = mbedtls_rsa_write_key(rsa, buf, &p); if (key_len <= 0) { return MBEDTLS_ERR_PK_BAD_INPUT_DATA; @@ -314,7 +318,7 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk, psa_set_key_algorithm(&attributes, decrypt_alg); status = psa_import_key(&attributes, - buf + sizeof(buf) - key_len, key_len, + buf + buf_size - key_len, key_len, &key_id); if (status != PSA_SUCCESS) { ret = PSA_PK_TO_MBEDTLS_ERR(status); @@ -333,7 +337,7 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk, ret = 0; cleanup: - mbedtls_platform_zeroize(buf, sizeof(buf)); + mbedtls_zeroize_and_free(buf, buf_size); status = psa_destroy_key(key_id); if (ret == 0 && status != PSA_SUCCESS) { ret = PSA_PK_TO_MBEDTLS_ERR(status); @@ -371,7 +375,7 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk, psa_algorithm_t psa_md_alg, psa_encrypt_alg; psa_status_t status; int key_len; - unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES]; + unsigned char buf[PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; unsigned char *p = buf + sizeof(buf); ((void) f_rng); @@ -1336,7 +1340,6 @@ static int rsa_alt_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { - unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; unsigned char hash[32]; size_t sig_len = 0; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -1345,21 +1348,29 @@ static int rsa_alt_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv, return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; } + size_t sig_size = (rsa_get_bitlen(pub) + 7) / 8; + unsigned char *sig = mbedtls_calloc(1, sig_size); + if (sig == NULL) { + return MBEDTLS_ERR_PK_ALLOC_FAILED; + } + memset(hash, 0x2a, sizeof(hash)); if ((ret = rsa_alt_sign_wrap(prv, MBEDTLS_MD_NONE, hash, sizeof(hash), - sig, sizeof(sig), &sig_len, + sig, sig_size, &sig_len, f_rng, p_rng)) != 0) { - return ret; + goto cleanup; } if (rsa_verify_wrap(pub, MBEDTLS_MD_NONE, hash, sizeof(hash), sig, sig_len) != 0) { - return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; } - return 0; +cleanup: + mbedtls_zeroize_and_free(sig, sig_size); + return ret; } #endif /* MBEDTLS_RSA_C */ diff --git a/vendor/mbedtls/library/pkwrite.c b/vendor/mbedtls/library/pkwrite.c index 2a69844..d264abf 100644 --- a/vendor/mbedtls/library/pkwrite.c +++ b/vendor/mbedtls/library/pkwrite.c @@ -45,10 +45,10 @@ /* Helpers for properly sizing buffers aimed at holding public keys or * key-pairs based on build symbols. */ #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -#define PK_MAX_EC_PUBLIC_KEY_SIZE PSA_EXPORT_PUBLIC_KEY_MAX_SIZE +#define PK_MAX_EC_PUBLIC_KEY_SIZE MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH #define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH #elif defined(MBEDTLS_USE_PSA_CRYPTO) -#define PK_MAX_EC_PUBLIC_KEY_SIZE PSA_EXPORT_PUBLIC_KEY_MAX_SIZE +#define PK_MAX_EC_PUBLIC_KEY_SIZE MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH #define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH #else #define PK_MAX_EC_PUBLIC_KEY_SIZE MBEDTLS_ECP_MAX_PT_LEN @@ -64,22 +64,24 @@ static int pk_write_rsa_der(unsigned char **p, unsigned char *buf, { #if defined(MBEDTLS_USE_PSA_CRYPTO) if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { - uint8_t tmp[PSA_EXPORT_KEY_PAIR_MAX_SIZE]; - size_t tmp_len = 0; + psa_status_t status; + size_t buf_size = (size_t) (*p - buf); + size_t key_len = 0; - if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - /* Ensure there's enough space in the provided buffer before copying data into it. */ - if (tmp_len > (size_t) (*p - buf)) { - mbedtls_platform_zeroize(tmp, sizeof(tmp)); + status = psa_export_key(pk->priv_id, buf, buf_size, &key_len); + if (status == PSA_ERROR_BUFFER_TOO_SMALL) { return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } else if (status != PSA_SUCCESS) { + return PSA_PK_RSA_TO_MBEDTLS_ERR(status); } - *p -= tmp_len; - memcpy(*p, tmp, tmp_len); - mbedtls_platform_zeroize(tmp, sizeof(tmp)); - return (int) tmp_len; + /* We wrote to the beginning of the buffer while + * we were supposed to write to its end. */ + *p -= key_len; + memmove(*p, buf, key_len); + mbedtls_platform_zeroize(buf, *p - buf); + + return (int) key_len; } #endif /* MBEDTLS_USE_PSA_CRYPTO */ return mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), buf, p); diff --git a/vendor/mbedtls/library/platform_util.c b/vendor/mbedtls/library/platform_util.c index 19ef07a..1cab42f 100644 --- a/vendor/mbedtls/library/platform_util.c +++ b/vendor/mbedtls/library/platform_util.c @@ -147,12 +147,9 @@ void mbedtls_zeroize_and_free(void *buf, size_t len) #if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) #include -#if !defined(_WIN32) && (defined(unix) || \ - defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__)) || defined(__midipix__)) +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) #include -#endif /* !_WIN32 && (unix || __unix || __unix__ || - * (__APPLE__ && __MACH__) || __midipix__) */ +#endif #if !((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || \ (defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \ @@ -218,12 +215,10 @@ void (*mbedtls_test_hook_test_fail)(const char *, int, const char *); #if defined(MBEDTLS_HAVE_TIME) && !defined(MBEDTLS_PLATFORM_MS_TIME_ALT) #include -#if !defined(_WIN32) && \ - (defined(unix) || defined(__unix) || defined(__unix__) || \ - (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__) || defined(__midipix__)) +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) #include -#endif \ - /* !_WIN32 && (unix || __unix || __unix__ || (__APPLE__ && __MACH__) || __HAIKU__ || __midipix__) */ +#endif + #if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 199309L) || defined(__HAIKU__) mbedtls_ms_time_t mbedtls_ms_time(void) { diff --git a/vendor/mbedtls/library/psa_crypto.c b/vendor/mbedtls/library/psa_crypto.c index 9e17e27..63b16f9 100644 --- a/vendor/mbedtls/library/psa_crypto.c +++ b/vendor/mbedtls/library/psa_crypto.c @@ -37,6 +37,7 @@ * stored keys. */ #include "psa_crypto_storage.h" +#include "psa_crypto_random.h" #include "psa_crypto_random_impl.h" #include @@ -4412,25 +4413,8 @@ static psa_status_t psa_generate_random_internal(uint8_t *output, return PSA_SUCCESS; #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - - while (output_size > 0) { - int ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; - size_t request_size = - (output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ? - MBEDTLS_PSA_RANDOM_MAX_REQUEST : - output_size); -#if defined(MBEDTLS_CTR_DRBG_C) - ret = mbedtls_ctr_drbg_random(&global_data.rng.drbg, output, request_size); -#elif defined(MBEDTLS_HMAC_DRBG_C) - ret = mbedtls_hmac_drbg_random(&global_data.rng.drbg, output, request_size); -#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */ - if (ret != 0) { - return mbedtls_to_psa_error(ret); - } - output_size -= request_size; - output += request_size; - } - return PSA_SUCCESS; + return psa_random_internal_generate(&global_data.rng, + output, output_size); #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ } @@ -5523,6 +5507,10 @@ psa_status_t psa_aead_update(psa_aead_operation_t *operation, static psa_status_t psa_aead_final_checks(const psa_aead_operation_t *operation) { + if (operation->alg == PSA_ALG_CCM && !operation->lengths_set) { + return PSA_ERROR_BAD_STATE; + } + if (operation->id == 0 || !operation->nonce_set) { return PSA_ERROR_BAD_STATE; } @@ -7923,10 +7911,8 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, * for the output size. The PSA specification only guarantees that this * function works if output_size >= PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(...), * but it might be nice to allow smaller buffers if the output fits. - * At the time of writing this comment, with only ECDH implemented, - * PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is exact so the point is moot. - * If FFDH is implemented, PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() can easily - * be exact for it as well. */ + * At the time of writing this comment, for both FFDH and ECDH, + * PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is exact so the point is moot. */ expected_length = PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(slot->attr.type, slot->attr.bits); if (output_size < expected_length) { @@ -7986,28 +7972,7 @@ static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng) #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) memset(rng, 0, sizeof(*rng)); #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - - /* Set default configuration if - * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */ - if (rng->entropy_init == NULL) { - rng->entropy_init = mbedtls_entropy_init; - } - if (rng->entropy_free == NULL) { - rng->entropy_free = mbedtls_entropy_free; - } - - rng->entropy_init(&rng->entropy); -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ - defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) - /* The PSA entropy injection feature depends on using NV seed as an entropy - * source. Add NV seed as an entropy source for PSA entropy injection. */ - mbedtls_entropy_add_source(&rng->entropy, - mbedtls_nv_seed_poll, NULL, - MBEDTLS_ENTROPY_BLOCK_SIZE, - MBEDTLS_ENTROPY_SOURCE_STRONG); -#endif - - mbedtls_psa_drbg_init(&rng->drbg); + psa_random_internal_init(rng); #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ } @@ -8021,8 +7986,7 @@ static void mbedtls_psa_random_free(mbedtls_psa_random_context_t *rng) #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) memset(rng, 0, sizeof(*rng)); #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - mbedtls_psa_drbg_free(&rng->drbg); - rng->entropy_free(&rng->entropy); + psa_random_internal_free(rng); #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ } @@ -8035,13 +7999,87 @@ static psa_status_t mbedtls_psa_random_seed(mbedtls_psa_random_context_t *rng) (void) rng; return PSA_SUCCESS; #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - const unsigned char drbg_seed[] = "PSA"; - int ret = mbedtls_psa_drbg_seed(&rng->drbg, &rng->entropy, - drbg_seed, sizeof(drbg_seed) - 1); + return psa_random_internal_seed(rng); +#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ +} + +psa_status_t psa_random_reseed(const uint8_t *perso, size_t perso_size) +{ + GUARD_MODULE_INITIALIZED; +#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + (void) perso; + (void) perso_size; + return PSA_ERROR_NOT_SUPPORTED; +#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ +#if defined(MBEDTLS_THREADING_C) + if (mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex) != 0) { + return PSA_ERROR_SERVICE_FAILURE; + } +#endif /* defined(MBEDTLS_THREADING_C) */ + int ret = mbedtls_psa_drbg_reseed(&global_data.rng.drbg, + perso, perso_size); +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ return mbedtls_to_psa_error(ret); #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ } +psa_status_t psa_random_deplete(void) +{ + GUARD_MODULE_INITIALIZED; +#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + return PSA_ERROR_NOT_SUPPORTED; +#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ +#if defined(MBEDTLS_THREADING_C) + if (mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex) != 0) { + return PSA_ERROR_SERVICE_FAILURE; + } +#endif /* defined(MBEDTLS_THREADING_C) */ + mbedtls_psa_drbg_deplete(&global_data.rng.drbg); +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + return PSA_SUCCESS; +#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ +} + +psa_status_t psa_random_set_prediction_resistance(unsigned enabled) +{ + GUARD_MODULE_INITIALIZED; + +#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + (void) enabled; + return PSA_ERROR_NOT_SUPPORTED; +#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ + + if (enabled != 0 && enabled != 1) { + return PSA_ERROR_INVALID_ARGUMENT; + } + +#if MBEDTLS_ENTROPY_TRUE_SOURCES > 0 +#if defined(MBEDTLS_THREADING_C) + if (mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex) != 0) { + return PSA_ERROR_SERVICE_FAILURE; + } +#endif /* defined(MBEDTLS_THREADING_C) */ + mbedtls_psa_drbg_set_prediction_resistance(&global_data.rng.drbg, enabled); +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + return PSA_SUCCESS; + +#else /* MBEDTLS_ENTROPY_TRUE_SOURCES > 0 */ + if (enabled) { + return PSA_ERROR_NOT_SUPPORTED; + } else { + return PSA_SUCCESS; + } + +#endif /* MBEDTLS_ENTROPY_TRUE_SOURCES > 0 */ +#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ +} + psa_status_t psa_generate_random(uint8_t *output_external, size_t output_size) { diff --git a/vendor/mbedtls/library/psa_crypto_aead.c b/vendor/mbedtls/library/psa_crypto_aead.c index a201985..307bfe7 100644 --- a/vendor/mbedtls/library/psa_crypto_aead.c +++ b/vendor/mbedtls/library/psa_crypto_aead.c @@ -310,9 +310,6 @@ psa_status_t mbedtls_psa_aead_decrypt( exit: mbedtls_psa_aead_abort(&operation); - if (status == PSA_SUCCESS) { - *plaintext_length = ciphertext_length - operation.tag_length; - } return status; } diff --git a/vendor/mbedtls/library/psa_crypto_ffdh.c b/vendor/mbedtls/library/psa_crypto_ffdh.c index ae38f6d..c759aff 100644 --- a/vendor/mbedtls/library/psa_crypto_ffdh.c +++ b/vendor/mbedtls/library/psa_crypto_ffdh.c @@ -168,6 +168,10 @@ psa_status_t mbedtls_psa_ffdh_export_public_key( mbedtls_mpi_init(&X); mbedtls_mpi_init(&P); size_t key_len = PSA_BITS_TO_BYTES(attributes->bits); + if (key_len > data_size) { + status = PSA_ERROR_BUFFER_TOO_SMALL; + goto cleanup; + } status = mbedtls_psa_ffdh_set_prime_generator(key_len, &P, &G); @@ -266,35 +270,71 @@ psa_status_t mbedtls_psa_ffdh_key_agreement( { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi P, G, X, GY, K; - const size_t calculated_shared_secret_size = peer_key_length; + mbedtls_mpi P, X, GY, K; + const size_t calculated_shared_secret_size = key_buffer_size; - if (peer_key_length != key_buffer_size || - calculated_shared_secret_size > shared_secret_size) { + if (!PSA_KEY_TYPE_IS_DH_KEY_PAIR(psa_get_key_type(attributes))) { return PSA_ERROR_INVALID_ARGUMENT; } - if (!PSA_KEY_TYPE_IS_DH_KEY_PAIR(psa_get_key_type(attributes))) { + if (peer_key_length != key_buffer_size) { return PSA_ERROR_INVALID_ARGUMENT; } - mbedtls_mpi_init(&P); mbedtls_mpi_init(&G); + /* This has been checked by the core, but keep a local check too. */ + if (calculated_shared_secret_size > shared_secret_size) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + mbedtls_mpi_init(&P); mbedtls_mpi_init(&X); mbedtls_mpi_init(&GY); mbedtls_mpi_init(&K); status = mbedtls_psa_ffdh_set_prime_generator( - PSA_BITS_TO_BYTES(attributes->bits), &P, &G); + PSA_BITS_TO_BYTES(attributes->bits), &P, NULL); if (status != PSA_SUCCESS) { goto cleanup; } - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer, - key_buffer_size)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&GY, peer_key, peer_key_length)); + /* RFC 7919 5.1: validate the peer's public key: 1 < GY < P-1 + * + * This check is sufficient to ensure GY is not of low order, because we're + * using a safe prime (that is, q = (p-1) / 2 is also prime), so the only + * group elements of low order are 1 and p-1. (Obviously we also want to + * exclude 0 that is not a group element, and values >= p as they are not + * residues mod p.) + * + * Note: we know we're using a safe prime because the only FFDH groups + * defined by the PSA spec are from RFC 7919 (since version 1.0) and RFC + * 3525 (since v1.4, not yet supported in tf-psa-crypto as of writing this + * comment), which both use safe primes. + * + * Note: NIST SP 800-56Ar3 5.7.1.1 (2) has the check on the shared secret, + * but checking before is equivalent (unless our secret key is exactly + * (p-1)/2, which has negligible probability and can't be influenced by the + * adversary). Checking before is cleaner in terms of side channel analysis, + * as we haven't loaded our secret yet, so no worries about branches. + * + * Use X as a temporary, since we haven't loaded it yet. + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&X, &P, 1)); // x = p - 1 + if (mbedtls_mpi_cmp_mpi(&GY, &X) >= 0) { + status = PSA_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&X, 1)); // x = 1 + if (mbedtls_mpi_cmp_mpi(&GY, &X) <= 0) { + status = PSA_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer, + key_buffer_size)); + /* Calculate shared secret public key: K = G^(XY) mod P = GY^X mod P */ MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &GY, &X, &P, NULL)); @@ -306,7 +346,7 @@ psa_status_t mbedtls_psa_ffdh_key_agreement( ret = 0; cleanup: - mbedtls_mpi_free(&P); mbedtls_mpi_free(&G); + mbedtls_mpi_free(&P); mbedtls_mpi_free(&X); mbedtls_mpi_free(&GY); mbedtls_mpi_free(&K); diff --git a/vendor/mbedtls/library/psa_crypto_random.c b/vendor/mbedtls/library/psa_crypto_random.c new file mode 100644 index 0000000..af6e5de --- /dev/null +++ b/vendor/mbedtls/library/psa_crypto_random.c @@ -0,0 +1,181 @@ +/* + * PSA crypto random generator. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +#if defined(MBEDTLS_PSA_CRYPTO_C) && !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + +#include "psa_crypto_core.h" +#include "psa_crypto_random.h" +#include "psa_crypto_random_impl.h" +#include "threading_internal.h" + +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) +#include "entropy_poll.h" +#endif + +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) +/* For getpid(), for fork protection */ +#include +#if defined(MBEDTLS_HAVE_TIME) +#include +#else +/* For gettimeofday(), for fork protection without actual entropy */ +#include +#endif +#endif + +void psa_random_internal_init(mbedtls_psa_random_context_t *rng) +{ + /* Set default configuration if + * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */ + if (rng->entropy_init == NULL) { + rng->entropy_init = mbedtls_entropy_init; + } + if (rng->entropy_free == NULL) { + rng->entropy_free = mbedtls_entropy_free; + } + + rng->entropy_init(&rng->entropy); +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) + /* The PSA entropy injection feature depends on using NV seed as an entropy + * source. Add NV seed as an entropy source for PSA entropy injection. */ + mbedtls_entropy_add_source(&rng->entropy, + mbedtls_nv_seed_poll, NULL, + MBEDTLS_ENTROPY_BLOCK_SIZE, + MBEDTLS_ENTROPY_SOURCE_STRONG); +#endif + + mbedtls_psa_drbg_init(&rng->drbg); +} + +void psa_random_internal_free(mbedtls_psa_random_context_t *rng) +{ + mbedtls_psa_drbg_free(&rng->drbg); + rng->entropy_free(&rng->entropy); +} +psa_status_t psa_random_internal_seed(mbedtls_psa_random_context_t *rng) +{ + const unsigned char drbg_seed[] = "PSA"; + int ret = mbedtls_psa_drbg_seed(&rng->drbg, &rng->entropy, + drbg_seed, sizeof(drbg_seed) - 1); +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) + rng->pid = getpid(); +#endif + return mbedtls_to_psa_error(ret); +} + +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) +static psa_status_t psa_random_internal_reseed_child( + mbedtls_psa_random_context_t *rng, + intmax_t pid) +{ + /* Reseeding from actual entropy gives the child a unique RNG state + * which the parent process cannot predict, and wipes the + * parent's RNG state from the child. + * + * However, in some library configurations, there is no actual + * entropy source, only a nonvolatile seed (MBEDTLS_ENTROPY_NV_SEED + * enabled and no actual entropy source enabled). In such a + * configuration, the reseed operation is deterministic and + * always injects the same content, so with the DRBG reseed + * process alone, for example, two child processes forked in + * close sequence would end up with the same RNG state. + + * To avoid this, we use a personalization string that has a high + * likelihood of being unique. This way, the child has a unique state. + * The parent can predict the child's RNG state until the next time + * it reseeds or generates some random output, but that's + * unavoidable in the absence of actual entropy. + */ + struct { + /* Using the PID mostly guarantees that each child gets a + * unique state. */ + /* Use intmax_t, not pid_t, because some Unix-like platforms + * don't define pid_t, or more likely nowadays they define + * pid_t but only with certain platform macros which might not + * be the exact ones we use. In practice, this only costs + * a couple of instructions to pass and compare two words + * rather than one. + */ + intmax_t pid; + /* In case an old child had died and its PID is reused for + * a new child of the same process, also include the time. */ +#if defined(MBEDTLS_HAVE_TIME) + mbedtls_ms_time_t now; +#else + struct timeval now; +#endif + } perso; + memset(&perso, 0, sizeof(perso)); + perso.pid = pid; +#if defined(MBEDTLS_HAVE_TIME) + perso.now = mbedtls_ms_time(); +#else + /* We don't have mbedtls_ms_time(), but the platform has getpid(). + * Use gettimeofday(), which is a classic Unix function. Modern POSIX + * has stopped requiring gettimeofday() (in favor of clock_gettime()), + * but this is fallback code for restricted configurations, so it's + * more likely to be used on embedded platforms that only have a subset + * of Unix APIs and are more likely to have the classic gettimeofday(). */ + if (gettimeofday(&perso.now, NULL) == -1) { + return PSA_ERROR_INSUFFICIENT_ENTROPY; + } +#endif + int ret = mbedtls_psa_drbg_reseed(&rng->drbg, + (unsigned char *) &perso, sizeof(perso)); + return mbedtls_to_psa_error(ret); +} +#endif /* MBEDTLS_PLATFORM_IS_UNIXLIKE */ + +psa_status_t psa_random_internal_generate( + mbedtls_psa_random_context_t *rng, + uint8_t *output, size_t output_size) +{ +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) + intmax_t pid = getpid(); + if (pid != rng->pid) { + /* This is a (grand...)child of the original process, but + * we inherited the RNG state from our parent. We must reseed! */ +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + psa_status_t status = psa_random_internal_reseed_child(rng, pid); + if (status == PSA_SUCCESS) { + rng->pid = pid; + } +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + if (status != PSA_SUCCESS) { + return status; + } + } +#endif /* MBEDTLS_PLATFORM_IS_UNIXLIKE */ + + while (output_size > 0) { + size_t request_size = + (output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ? + MBEDTLS_PSA_RANDOM_MAX_REQUEST : + output_size); +#if defined(MBEDTLS_CTR_DRBG_C) + int ret = mbedtls_ctr_drbg_random(&rng->drbg, output, request_size); +#elif defined(MBEDTLS_HMAC_DRBG_C) + int ret = mbedtls_hmac_drbg_random(&rng->drbg, output, request_size); +#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */ + if (ret != 0) { + return mbedtls_to_psa_error(ret); + } + output_size -= request_size; + output += request_size; + } + return PSA_SUCCESS; +} + +#endif /* MBEDTLS_PSA_CRYPTO_C && !MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ diff --git a/vendor/mbedtls/library/psa_crypto_random.h b/vendor/mbedtls/library/psa_crypto_random.h new file mode 100644 index 0000000..167bb23 --- /dev/null +++ b/vendor/mbedtls/library/psa_crypto_random.h @@ -0,0 +1,72 @@ +/* + * PSA crypto random generator internal functions. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef PSA_CRYPTO_RANDOM_H +#define PSA_CRYPTO_RANDOM_H + +#include "common.h" + +#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + +#include +#include "psa_crypto_random_impl.h" + +/** Initialize the PSA random generator. + * + * \param[out] rng The random generator context to initialize. + */ +void psa_random_internal_init(mbedtls_psa_random_context_t *rng); + +/** Deinitialize the PSA random generator. + * + * \param[in,out] rng The random generator context to deinitialize. + */ +void psa_random_internal_free(mbedtls_psa_random_context_t *rng); + +/** Seed the PSA random generator. + * + * \note This function is not thread-safe. + * + * \param[in,out] rng The random generator context to seed. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * The entropy source failed. + */ +psa_status_t psa_random_internal_seed(mbedtls_psa_random_context_t *rng); + +/** + * \brief Generate random bytes. Like psa_generate_random(), but for use + * inside the library. + * + * This function is thread-safe. + * + * \warning This function **can** fail! Callers MUST check the return status + * and MUST NOT use the content of the output buffer if the return + * status is not #PSA_SUCCESS. + * + * \param[in,out] rng The random generator context to seed. + * \param[out] output Output buffer for the generated data. + * \param output_size Number of bytes to generate and output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * The random generator needed to reseed, and the entropy + * source failed. + * \retval #PSA_ERROR_HARDWARE_FAILURE + * A hardware accelerator failed. + */ +psa_status_t psa_random_internal_generate( + mbedtls_psa_random_context_t *rng, + uint8_t *output, size_t output_size); + +#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */ + +#endif /* PSA_CRYPTO_RANDOM_H */ diff --git a/vendor/mbedtls/library/psa_crypto_random_impl.h b/vendor/mbedtls/library/psa_crypto_random_impl.h index 5b51631..68bb3a3 100644 --- a/vendor/mbedtls/library/psa_crypto_random_impl.h +++ b/vendor/mbedtls/library/psa_crypto_random_impl.h @@ -70,6 +70,23 @@ typedef struct { void (* entropy_free)(mbedtls_entropy_context *ctx); mbedtls_entropy_context entropy; mbedtls_psa_drbg_context_t drbg; +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) + /* Fork protection: normally pid = getpid(). If the value changes, + * we are in a (grand)*child of the original process, so reseed + * the RNG to ensure that the child and the original process have + * distinct RNG states. See psa_random_internal_generate(). + * + * The type is intmax_t, not pid_t, for portability reasons: + * pid_t is defined in `unistd.h`, but on some platforms, it may + * only be defined if a certain compatibility level is requested + * by defining a macro such as _POSIX_C_SOURCE or _XOPEN_SOURCE. + * The macro needs to be defined before any system header, which + * may be hard to do in some C files that include this header + * (e.g. test suites). So we sidestep this complication, at the + * cost of possibly a few more instructions to compare pid values. + */ + intmax_t pid; +#endif } mbedtls_psa_random_context_t; /** Initialize the PSA DRBG. @@ -100,6 +117,8 @@ static inline void mbedtls_psa_drbg_free(mbedtls_psa_drbg_context_t *p_rng) /** Seed the PSA DRBG. * + * \param drbg_ctx The DRBG context to seed. + * It must be initialized but not active. * \param entropy An entropy context to read the seed from. * \param custom The personalization string. * This can be \c NULL, in which case the personalization @@ -121,6 +140,61 @@ static inline int mbedtls_psa_drbg_seed(mbedtls_psa_drbg_context_t *drbg_ctx, #endif } +/** Reseed the PSA DRBG. + * + * \param drbg_ctx The DRBG context to reseed. + * It must be active. + * \param additional Additional data to inject. + * \param len The length of \p additional in bytes. + * This can be 0 to simply reseed from the entropy source. + * + * \return \c 0 on success. + * \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure. + */ +static inline int mbedtls_psa_drbg_reseed(mbedtls_psa_drbg_context_t *drbg_ctx, + const unsigned char *additional, + size_t len) +{ +#if defined(MBEDTLS_CTR_DRBG_C) + return mbedtls_ctr_drbg_reseed(drbg_ctx, additional, len); +#elif defined(MBEDTLS_HMAC_DRBG_C) + return mbedtls_hmac_drbg_reseed(drbg_ctx, additional, len); +#endif +} + +/** Deplete the PSA DRBG, i.e. cause it to reseed the next time it is used. + * + * \note This function is not thread-safe. + * + * \param drbg_ctx The DRBG context to deplete. + * It must be active. + */ +static inline void mbedtls_psa_drbg_deplete(mbedtls_psa_drbg_context_t *drbg_ctx) +{ + drbg_ctx->reseed_counter = drbg_ctx->reseed_interval; +} + +#if MBEDTLS_ENTROPY_TRUE_SOURCES > 0 +/** Set prediction resistance in the PSA DRBG. + * + * \note This function is not thread-safe. + * + * \param drbg_ctx The DRBG context to reconfigure. + * It must be active. + * \param enabled \c 1 to enable, or \c 0 to disable. + */ +static inline void mbedtls_psa_drbg_set_prediction_resistance( + mbedtls_psa_drbg_context_t *drbg_ctx, + unsigned enabled) +{ +#if defined(MBEDTLS_CTR_DRBG_C) + mbedtls_ctr_drbg_set_prediction_resistance(drbg_ctx, enabled); +#elif defined(MBEDTLS_HMAC_DRBG_C) + mbedtls_hmac_drbg_set_prediction_resistance(drbg_ctx, enabled); +#endif +} +#endif /* MBEDTLS_ENTROPY_TRUE_SOURCES > 0 */ + #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ #endif /* PSA_CRYPTO_RANDOM_IMPL_H */ diff --git a/vendor/mbedtls/library/psa_crypto_slot_management.c b/vendor/mbedtls/library/psa_crypto_slot_management.c index f1a651f..d514d1a 100644 --- a/vendor/mbedtls/library/psa_crypto_slot_management.c +++ b/vendor/mbedtls/library/psa_crypto_slot_management.c @@ -684,6 +684,12 @@ static psa_status_t psa_load_persistent_key_into_slot(psa_key_slot_t *slot) psa_status_t status = PSA_SUCCESS; uint8_t *key_data = NULL; size_t key_data_length = 0; + psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id); + + /* Do not try to load a persistent key whose ID is in the volatile range. */ + if ((key_id >= PSA_KEY_ID_VOLATILE_MIN) && (key_id <= PSA_KEY_ID_VOLATILE_MAX)) { + return PSA_ERROR_DOES_NOT_EXIST; + } status = psa_load_persistent_key(&slot->attr, &key_data, &key_data_length); diff --git a/vendor/mbedtls/library/rsa.c b/vendor/mbedtls/library/rsa.c index 08267db..2eb042f 100644 --- a/vendor/mbedtls/library/rsa.c +++ b/vendor/mbedtls/library/rsa.c @@ -1101,7 +1101,6 @@ int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx, * if it exists (FIPS 186-4 §B.3.1 criterion 2(a)) */ ret = mbedtls_rsa_deduce_private_exponent(&ctx->P, &ctx->Q, &ctx->E, &ctx->D); if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { - mbedtls_mpi_lset(&ctx->D, 0); /* needed for the next call */ continue; } if (ret != 0) { @@ -1268,6 +1267,117 @@ int mbedtls_rsa_public(mbedtls_rsa_context *ctx, return 0; } +#if !defined(MBEDTLS_RSA_NO_CRT) +/* + * Compute T such that T = TP mod P and T = TQ mod Q. + * (This is the Chinese Remainder Theorem - CRT.) + */ +static int rsa_apply_crt(mbedtls_mpi *T, + const mbedtls_mpi *TP, + const mbedtls_mpi *TQ, + const mbedtls_rsa_context *ctx) +{ + int ret; + + /* + * Set T = ((TP - TQ) * (Q^-1 mod P) mod P) * Q + TQ + * + * That way we have both: + * mod P: T = (TP - TQ) * (Q^-1 * Q) + TQ = (TP - TQ) * 1 + TQ = TP + * mod Q: T = (...) * Q + TQ = TQ + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(T, TP, TQ)); // T = TP - TQ + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(T, T, &ctx->QP)); // T *= Q^-1 mod P + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(T, T, &ctx->P)); // T %= P + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(T, T, &ctx->Q)); // T *= Q + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(T, T, TQ)); // T += TQ + +cleanup: + return ret; +} +#endif + +/* Generate random A and B such that A^-1 = B mod N */ +static int rsa_gen_rand_with_inverse(const mbedtls_rsa_context *ctx, + mbedtls_mpi *A, + mbedtls_mpi *B, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ +#if defined(MBEDTLS_RSA_NO_CRT) + int ret; + mbedtls_mpi G; + + mbedtls_mpi_init(&G); + + MBEDTLS_MPI_CHK(mbedtls_mpi_random(A, 1, &ctx->N, f_rng, p_rng)); + MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, B, A, &ctx->N)); + + if (mbedtls_mpi_cmp_int(&G, 1) != 0) { + /* This happens if we're unlucky enough to draw a multiple of P or Q, + * or if (at least) one of them is not a prime, and we drew a multiple + * of one of its factors. */ + ret = MBEDTLS_ERR_RSA_RNG_FAILED; + goto cleanup; + } + +cleanup: + mbedtls_mpi_free(&G); + + return ret; +#else + int ret; + mbedtls_mpi Ap, Aq, Bp, Bq, G; + + mbedtls_mpi_init(&Ap); mbedtls_mpi_init(&Aq); + mbedtls_mpi_init(&Bp); mbedtls_mpi_init(&Bq); + mbedtls_mpi_init(&G); + + /* + * Instead of generating A, B = A^-1 (mod N) directly, generate one Ap, Bp + * pair (mod P) and one pair (mod Q) and use Chinese Remainder Theorem to + * construct an A and B from those. + * + * This works because the CRT correspondence is a ring isomorphism between + * Z/NZ (integers mod N) and Z/PZ x Z/QZ (pairs of integers mod P and Q): + * - it is a bijection (one-to-one correspondence); + * - doing a ring operation (modular +, -, *, ^-1 when possible) on one side is + * the same as doing it on the other side. + * So, drawing uniformly at random an invertible A mod N is the same as + * drawing uniformly at random pairs of invertible Ap mod P, Aq mod Q. + */ + + /* Generate Ap in [1, P) and compute Bp = Ap^-1 mod P */ + MBEDTLS_MPI_CHK(mbedtls_mpi_random(&Ap, 1, &ctx->P, f_rng, p_rng)); + MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &Bp, &Ap, &ctx->P)); + if (mbedtls_mpi_cmp_int(&G, 1) != 0) { + /* This can only happen if P was not a prime. */ + ret = MBEDTLS_ERR_RSA_RNG_FAILED; + goto cleanup; + } + + /* Generate Aq in [1, Q) and compute Bq = Aq^-1 mod Q */ + MBEDTLS_MPI_CHK(mbedtls_mpi_random(&Aq, 1, &ctx->Q, f_rng, p_rng)); + MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &Bq, &Aq, &ctx->Q)); + if (mbedtls_mpi_cmp_int(&G, 1) != 0) { + /* This can only happen if Q was not a prime. */ + ret = MBEDTLS_ERR_RSA_RNG_FAILED; + goto cleanup; + } + + /* Reconstruct A and B */ + MBEDTLS_MPI_CHK(rsa_apply_crt(A, &Ap, &Aq, ctx)); + MBEDTLS_MPI_CHK(rsa_apply_crt(B, &Bp, &Bq, ctx)); + +cleanup: + mbedtls_mpi_free(&Ap); mbedtls_mpi_free(&Aq); + mbedtls_mpi_free(&Bp); mbedtls_mpi_free(&Bq); + mbedtls_mpi_free(&G); + + return ret; +#endif +} + /* * Generate or update blinding values, see section 10 of: * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, @@ -1277,10 +1387,7 @@ int mbedtls_rsa_public(mbedtls_rsa_context *ctx, static int rsa_prepare_blinding(mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { - int ret, count = 0; - mbedtls_mpi R; - - mbedtls_mpi_init(&R); + int ret; if (ctx->Vf.p != NULL) { /* We already have blinding values, just update them by squaring */ @@ -1288,30 +1395,17 @@ static int rsa_prepare_blinding(mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N)); MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf)); MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->N)); - goto cleanup; } /* Unblinding value: Vf = random number, invertible mod N */ - mbedtls_mpi_lset(&R, 0); - do { - if (count++ > 10) { - ret = MBEDTLS_ERR_RSA_RNG_FAILED; - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_random(&ctx->Vf, 1, &ctx->N, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&R, &ctx->Vi, &ctx->Vf, &ctx->N)); - } while (mbedtls_mpi_cmp_int(&R, 1) != 0); + MBEDTLS_MPI_CHK(rsa_gen_rand_with_inverse(ctx, &ctx->Vf, &ctx->Vi, f_rng, p_rng)); /* Blinding value: Vi = Vf^(-e) mod N * (Vi already contains Vf^-1 at this point) */ MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN)); - cleanup: - mbedtls_mpi_free(&R); - return ret; } @@ -1511,19 +1605,7 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TP, &T, &DP_blind, &ctx->P, &ctx->RP)); MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TQ, &T, &DQ_blind, &ctx->Q, &ctx->RQ)); - - /* - * T = (TP - TQ) * (Q^-1 mod P) mod P - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&T, &TP, &TQ)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&TP, &T, &ctx->QP)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &TP, &ctx->P)); - - /* - * T = TQ + T * Q - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&TP, &T, &ctx->Q)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&T, &TQ, &TP)); + MBEDTLS_MPI_CHK(rsa_apply_crt(&T, &TP, &TQ, ctx)); #endif /* MBEDTLS_RSA_NO_CRT */ /* Verify the result to prevent glitching attacks. */ diff --git a/vendor/mbedtls/library/rsa_alt_helpers.c b/vendor/mbedtls/library/rsa_alt_helpers.c index 50a5c4e..8a09f93 100644 --- a/vendor/mbedtls/library/rsa_alt_helpers.c +++ b/vendor/mbedtls/library/rsa_alt_helpers.c @@ -188,7 +188,7 @@ int mbedtls_rsa_deduce_private_exponent(mbedtls_mpi const *P, int ret = 0; mbedtls_mpi K, L; - if (D == NULL || mbedtls_mpi_cmp_int(D, 0) != 0) { + if (D == NULL) { return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; } diff --git a/vendor/mbedtls/library/sha256.c b/vendor/mbedtls/library/sha256.c index 159accc..4f1ac3e 100644 --- a/vendor/mbedtls/library/sha256.c +++ b/vendor/mbedtls/library/sha256.c @@ -10,6 +10,11 @@ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf */ +/* Ensure that SIG_SETMASK is defined when -std=c99 is used. */ +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE +#endif + #if defined(__clang__) && (__clang_major__ >= 4) /* Ideally, we would simply use MBEDTLS_ARCH_IS_ARMV8_A in the following #if, @@ -21,15 +26,18 @@ #endif #if defined(MBEDTLS_SHA256_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO) -/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged. - * +/* * The intrinsic declaration are guarded by predefined ACLE macros in clang: * these are normally only enabled by the -march option on the command line. * By defining the macros ourselves we gain access to those declarations without * requiring -march on the command line. * * `arm_neon.h` is included by common.h, so we put these defines - * at the top of this file, before any includes. + * at the top of this file, before any includes but after the intrinsic + * declaration. This is necessary with + * Clang <=15.x. With Clang 16.0 and above, these macro definitions are + * no longer required, but they're harmless. See + * https://reviews.llvm.org/D131064 */ #define __ARM_FEATURE_CRYPTO 1 /* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions @@ -43,11 +51,6 @@ #endif /* defined(__clang__) && (__clang_major__ >= 4) */ -/* Ensure that SIG_SETMASK is defined when -std=c99 is used. */ -#if !defined(_GNU_SOURCE) -#define _GNU_SOURCE -#endif - #include "common.h" #if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C) diff --git a/vendor/mbedtls/library/sha512.c b/vendor/mbedtls/library/sha512.c index 6dcea8d..286cbdf 100644 --- a/vendor/mbedtls/library/sha512.c +++ b/vendor/mbedtls/library/sha512.c @@ -12,15 +12,18 @@ #if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \ defined(__clang__) && __clang_major__ >= 7 -/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged. - * +/* * The intrinsic declaration are guarded by predefined ACLE macros in clang: * these are normally only enabled by the -march option on the command line. * By defining the macros ourselves we gain access to those declarations without * requiring -march on the command line. * * `arm_neon.h` is included by common.h, so we put these defines - * at the top of this file, before any includes. + * at the top of this file, before any includes but after the intrinsic + * declaration. This is necessary with + * Clang <=15.x. With Clang 16.0 and above, these macro definitions are + * no longer required, but they're harmless. See + * https://reviews.llvm.org/D131064 */ #define __ARM_FEATURE_SHA512 1 #define MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG diff --git a/vendor/mbedtls/library/ssl_debug_helpers.h b/vendor/mbedtls/library/ssl_debug_helpers.h index 4889e77..38ef763 100644 --- a/vendor/mbedtls/library/ssl_debug_helpers.h +++ b/vendor/mbedtls/library/ssl_debug_helpers.h @@ -38,6 +38,8 @@ const char *mbedtls_ssl_named_group_to_str(uint16_t in); const char *mbedtls_ssl_get_extension_name(unsigned int extension_type); +const char *mbedtls_ssl_get_hs_msg_name(int hs_msg_type); + void mbedtls_ssl_print_extensions(const mbedtls_ssl_context *ssl, int level, const char *file, int line, int hs_msg_type, uint32_t extensions_mask, diff --git a/vendor/mbedtls/library/ssl_misc.h b/vendor/mbedtls/library/ssl_misc.h index faa1b5e..218a30d 100644 --- a/vendor/mbedtls/library/ssl_misc.h +++ b/vendor/mbedtls/library/ssl_misc.h @@ -1351,14 +1351,14 @@ static inline void mbedtls_ssl_handshake_set_state(mbedtls_ssl_context *ssl, mbedtls_ssl_states state) { MBEDTLS_SSL_DEBUG_MSG(3, ("handshake state: %d (%s) -> %d (%s)", - ssl->state, mbedtls_ssl_states_str(ssl->state), + ssl->state, mbedtls_ssl_states_str((mbedtls_ssl_states) ssl->state), (int) state, mbedtls_ssl_states_str(state))); ssl->state = (int) state; } static inline void mbedtls_ssl_handshake_increment_state(mbedtls_ssl_context *ssl) { - mbedtls_ssl_handshake_set_state(ssl, ssl->state + 1); + mbedtls_ssl_handshake_set_state(ssl, (mbedtls_ssl_states) (ssl->state + 1)); } MBEDTLS_CHECK_RETURN_CRITICAL diff --git a/vendor/mbedtls/library/ssl_msg.c b/vendor/mbedtls/library/ssl_msg.c index 38fd262..b0ab608 100644 --- a/vendor/mbedtls/library/ssl_msg.c +++ b/vendor/mbedtls/library/ssl_msg.c @@ -19,6 +19,7 @@ #include "mbedtls/ssl.h" #include "ssl_misc.h" #include "debug_internal.h" +#include "ssl_debug_helpers.h" #include "mbedtls/error.h" #include "mbedtls/platform_util.h" #include "mbedtls/version.h" @@ -321,7 +322,7 @@ int mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl, size_t buflen) { int ret = 0; - MBEDTLS_SSL_DEBUG_MSG(1, ("=> mbedtls_ssl_check_record")); + MBEDTLS_SSL_DEBUG_MSG(3, ("=> mbedtls_ssl_check_record")); MBEDTLS_SSL_DEBUG_BUF(3, "record buffer", buf, buflen); /* We don't support record checking in TLS because @@ -363,7 +364,7 @@ int mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl, ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; } - MBEDTLS_SSL_DEBUG_MSG(1, ("<= mbedtls_ssl_check_record")); + MBEDTLS_SSL_DEBUG_MSG(3, ("<= mbedtls_ssl_check_record")); return ret; } @@ -375,6 +376,7 @@ int mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl, /* Forward declarations for functions related to message buffering. */ static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl, uint8_t slot); +static void ssl_buffering_shift_slots(mbedtls_ssl_context *ssl, unsigned shift); static void ssl_free_buffered_record(mbedtls_ssl_context *ssl); MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_load_buffered_message(mbedtls_ssl_context *ssl); @@ -2618,7 +2620,8 @@ int mbedtls_ssl_flight_transmit(mbedtls_ssl_context *ssl) max_hs_frag_len : rem_len; if (frag_off == 0 && cur_hs_frag_len != hs_len) { - MBEDTLS_SSL_DEBUG_MSG(2, ("fragmenting handshake message (%u > %u)", + MBEDTLS_SSL_DEBUG_MSG(2, ("fragmenting %s handshake message (%u > %u)", + mbedtls_ssl_get_hs_msg_name(cur->p[0]), (unsigned) cur_hs_frag_len, (unsigned) max_hs_frag_len)); } @@ -3259,6 +3262,54 @@ int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_INVALID_RECORD; } + if (ssl->in_msg[0] == MBEDTLS_SSL_HS_CLIENT_HELLO && + ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { + if (ssl->state == MBEDTLS_SSL_CLIENT_HELLO +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE +#endif + ) { + /* + * When establishing the connection, the client may go through + * a series of ClientHello and HelloVerifyRequest requests and + * responses. The server intentionally does not keep trace of + * these initial round trips: minimum allocated ressources as + * long as the reachability of the client has not been + * confirmed. When receiving the "first ClientHello" from + * server perspective, we may thus need to adapt the next + * expected `message_seq` for the incoming and outgoing + * handshake messages. + */ + if ((ssl->handshake->in_msg_seq == 0) && (recv_msg_seq > 0)) { + MBEDTLS_SSL_DEBUG_MSG(3, ("shift slots by %u", recv_msg_seq)); + ssl_buffering_shift_slots(ssl, recv_msg_seq); + ssl->handshake->in_msg_seq = recv_msg_seq; + ssl->handshake->out_msg_seq = recv_msg_seq; + } + + /* Epoch should be 0 for initial handshakes */ + if (ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0) { + MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); + return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; + } + + memcpy(&ssl->cur_out_ctr[2], ssl->in_ctr + 2, + sizeof(ssl->cur_out_ctr) - 2); + + } else if (mbedtls_ssl_is_handshake_over(ssl) == 1) { + /* In case of a post-handshake ClientHello that initiates a + * renegotiation check that the handshake message sequence + * number is zero. + */ + if (recv_msg_seq != 0) { + MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: " + "%u (expected 0)", + recv_msg_seq)); + return MBEDTLS_ERR_SSL_DECODE_ERROR; + } + } + } + if (ssl->handshake != NULL && ((mbedtls_ssl_is_handshake_over(ssl) == 0 && recv_msg_seq != ssl->handshake->in_msg_seq) || @@ -3427,28 +3478,10 @@ int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_PROTO_DTLS) if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && ssl->handshake != NULL) { - unsigned offset; - mbedtls_ssl_hs_buffer *hs_buf; /* Increment handshake sequence number */ hs->in_msg_seq++; - - /* - * Clear up handshake buffering and reassembly structure. - */ - - /* Free first entry */ - ssl_buffering_free_slot(ssl, 0); - - /* Shift all other entries */ - for (offset = 0, hs_buf = &hs->buffering.hs[0]; - offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS; - offset++, hs_buf++) { - *hs_buf = *(hs_buf + 1); - } - - /* Create a fresh last entry */ - memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer)); + ssl_buffering_shift_slots(ssl, 1); } #endif return 0; @@ -3865,7 +3898,7 @@ static int ssl_parse_record_header(mbedtls_ssl_context const *ssl, ( "datagram of length %u too small to hold DTLS record header of length %u", (unsigned) len, - (unsigned) (rec_hdr_len_len + rec_hdr_len_len))); + (unsigned) (rec_hdr_len_offset + rec_hdr_len_len))); return MBEDTLS_ERR_SSL_INVALID_RECORD; } @@ -4449,7 +4482,9 @@ static int ssl_load_buffered_message(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_INTERNAL_ERROR; } - MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message has been buffered - load")); + MBEDTLS_SSL_DEBUG_MSG(2, ("%s handshake message has been buffered%s", + mbedtls_ssl_get_hs_msg_name(hs_buf->data[0]), + hs_buf->is_fragmented ? " and reassembled" : "")); MBEDTLS_SSL_DEBUG_BUF(3, "Buffered handshake message (incl. header)", hs_buf->data, msg_len + 12); @@ -4995,6 +5030,31 @@ static int ssl_get_next_record(mbedtls_ssl_context *ssl) ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; } +#if defined(MBEDTLS_SSL_SRV_C) + /* + * In DTLS, invalid records are usually ignored because it is easy + * for an attacker to inject UDP datagrams, and we do not want such + * packets to disrupt the entire connection. + * + * However, when expecting the ClientHello, we reject invalid or + * unexpected records. This avoids waiting for further records + * before receiving at least one valid message. Such records could + * be leftover messages from a previous connection, accidental + * input, or part of a DoS attempt. + * + * Since no valid message has been received yet, immediately + * closing the connection does not result in any loss. + */ + if ((ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) && + (ssl->state == MBEDTLS_SSL_CLIENT_HELLO) +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && (ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE) +#endif + ) { + return ret; + } +#endif /* MBEDTLS_SSL_SRV_C */ + if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) { #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) /* Reset in pointers to default state for TLS/DTLS records, @@ -5133,14 +5193,9 @@ static int ssl_get_next_record(mbedtls_ssl_context *ssl) /* The record content type may change during decryption, * so re-read it. */ ssl->in_msgtype = rec.type; - /* Also update the input buffer, because unfortunately - * the server-side ssl_parse_client_hello() reparses the - * record header when receiving a ClientHello initiating - * a renegotiation. */ - ssl->in_hdr[0] = rec.type; + ssl->in_msg = rec.buf + rec.data_offset; ssl->in_msglen = rec.data_len; - MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->in_len, 0); return 0; } @@ -5826,6 +5881,11 @@ static int ssl_tls12_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl) ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; } #endif + + /* Keep the ClientHello message for ssl_parse_client_hello() */ + if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { + ssl->keep_current_message = 1; + } ret = mbedtls_ssl_start_renegotiation(ssl); if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && ret != 0) { @@ -6423,6 +6483,42 @@ static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl, } } +/* + * Shift the buffering slots to the left by `shift` positions. + * After the operation, slot i contains the previous slot i + shift. + */ +static void ssl_buffering_shift_slots(mbedtls_ssl_context *ssl, + unsigned shift) +{ + mbedtls_ssl_handshake_params * const hs = ssl->handshake; + unsigned offset; + + if (shift == 0) { + return; + } + + if (shift >= MBEDTLS_SSL_MAX_BUFFERED_HS) { + shift = MBEDTLS_SSL_MAX_BUFFERED_HS; + } + + /* Free discarded entries */ + for (offset = 0; offset < shift; offset++) { + ssl_buffering_free_slot(ssl, offset); + } + + /* Shift remaining entries left */ + for (offset = 0; offset + shift < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) { + hs->buffering.hs[offset] = hs->buffering.hs[offset + shift]; + } + + /* Reset the remaining entries at the end. Some may already have been + * cleared by the loop freeing the discarded entries, but resetting all + * of them is simpler and avoids tracking which ones were already handled. + */ + for (; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) { + memset(&hs->buffering.hs[offset], 0, sizeof(hs->buffering.hs[offset])); + } +} #endif /* MBEDTLS_SSL_PROTO_DTLS */ /* diff --git a/vendor/mbedtls/library/ssl_tls.c b/vendor/mbedtls/library/ssl_tls.c index 30cde27..1185b0b 100644 --- a/vendor/mbedtls/library/ssl_tls.c +++ b/vendor/mbedtls/library/ssl_tls.c @@ -685,7 +685,7 @@ const char *mbedtls_ssl_get_extension_name(unsigned int extension_type) mbedtls_ssl_get_extension_id(extension_type)]; } -static const char *ssl_tls13_get_hs_msg_name(int hs_msg_type) +const char *mbedtls_ssl_get_hs_msg_name(int hs_msg_type) { switch (hs_msg_type) { case MBEDTLS_SSL_HS_CLIENT_HELLO: @@ -700,8 +700,16 @@ static const char *ssl_tls13_get_hs_msg_name(int hs_msg_type) return "EncryptedExtensions"; case MBEDTLS_SSL_HS_CERTIFICATE: return "Certificate"; + case MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE: + return "ServerKeyExchange"; case MBEDTLS_SSL_HS_CERTIFICATE_REQUEST: return "CertificateRequest"; + case MBEDTLS_SSL_HS_CERTIFICATE_VERIFY: + return "CertificateVerify"; + case MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE: + return "ClientKeyExchange"; + case MBEDTLS_SSL_HS_FINISHED: + return "Finished"; } return "Unknown"; } @@ -716,7 +724,7 @@ void mbedtls_ssl_print_extension(const mbedtls_ssl_context *ssl, mbedtls_debug_print_msg( ssl, level, file, line, "%s: %s(%u) extension %s %s.", - ssl_tls13_get_hs_msg_name(hs_msg_type), + mbedtls_ssl_get_hs_msg_name(hs_msg_type), mbedtls_ssl_get_extension_name(extension_type), extension_type, extra_msg0, extra_msg1); @@ -727,7 +735,7 @@ void mbedtls_ssl_print_extension(const mbedtls_ssl_context *ssl, if (extra_msg) { mbedtls_debug_print_msg( ssl, level, file, line, - "%s: %s(%u) extension %s.", ssl_tls13_get_hs_msg_name(hs_msg_type), + "%s: %s(%u) extension %s.", mbedtls_ssl_get_hs_msg_name(hs_msg_type), mbedtls_ssl_get_extension_name(extension_type), extension_type, extra_msg); return; @@ -735,7 +743,7 @@ void mbedtls_ssl_print_extension(const mbedtls_ssl_context *ssl, mbedtls_debug_print_msg( ssl, level, file, line, - "%s: %s(%u) extension.", ssl_tls13_get_hs_msg_name(hs_msg_type), + "%s: %s(%u) extension.", mbedtls_ssl_get_hs_msg_name(hs_msg_type), mbedtls_ssl_get_extension_name(extension_type), extension_type); } @@ -1048,6 +1056,8 @@ void mbedtls_ssl_transform_init(mbedtls_ssl_transform *transform) void mbedtls_ssl_session_init(mbedtls_ssl_session *session) { memset(session, 0, sizeof(mbedtls_ssl_session)); + /* Set verify_result to -1u to indicate 'result not available'. */ + session->verify_result = 0xFFFFFFFF; } MBEDTLS_CHECK_RETURN_CRITICAL @@ -3278,13 +3288,6 @@ size_t mbedtls_ssl_get_output_max_frag_len(const mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_PROTO_DTLS) size_t mbedtls_ssl_get_current_mtu(const mbedtls_ssl_context *ssl) { - /* Return unlimited mtu for client hello messages to avoid fragmentation. */ - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && - (ssl->state == MBEDTLS_SSL_CLIENT_HELLO || - ssl->state == MBEDTLS_SSL_SERVER_HELLO)) { - return 0; - } - if (ssl->handshake == NULL || ssl->handshake->mtu == 0) { return ssl->mtu; } @@ -5003,6 +5006,9 @@ void mbedtls_ssl_session_free(mbedtls_ssl_session *session) #endif mbedtls_platform_zeroize(session, sizeof(mbedtls_ssl_session)); + + /* Set verify_result to -1u to indicate 'result not available'. */ + session->verify_result = 0xFFFFFFFF; } #if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) @@ -7929,6 +7935,7 @@ static int ssl_parse_certificate_coordinate(mbedtls_ssl_context *ssl, ssl->handshake->ciphersuite_info; if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) { + ssl->session_negotiate->verify_result = 0; return SSL_CERTIFICATE_SKIP; } @@ -9873,6 +9880,7 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, void *rs_ctx) { if (authmode == MBEDTLS_SSL_VERIFY_NONE) { + ssl->session_negotiate->verify_result = 0; return 0; } @@ -10121,7 +10129,7 @@ static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, const size_t context_len) { const psa_algorithm_t psa_hash_alg = mbedtls_md_psa_alg_from_type(hash_alg); - const size_t hash_len = PSA_HASH_LENGTH(hash_alg); + const size_t hash_len = PSA_HASH_LENGTH(psa_hash_alg); const unsigned char *secret = ssl->session->app_secrets.exporter_master_secret; /* The length of the label must be at most 249 bytes to fit into the HkdfLabel diff --git a/vendor/mbedtls/library/ssl_tls12_client.c b/vendor/mbedtls/library/ssl_tls12_client.c index 65d6dbd..0196c0c 100644 --- a/vendor/mbedtls/library/ssl_tls12_client.c +++ b/vendor/mbedtls/library/ssl_tls12_client.c @@ -2078,6 +2078,46 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_parse_signature_algorithm(mbedtls_ssl_context *ssl, + uint16_t sig_alg, + mbedtls_md_type_t *md_alg, + mbedtls_pk_type_t *pk_alg) +{ + if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(sig_alg, pk_alg, md_alg) != 0) { + MBEDTLS_SSL_DEBUG_MSG(1, + ("Server used unsupported value in SigAlg extension 0x%04x", + sig_alg)); + return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; + } + + /* + * mbedtls_ssl_get_pk_sigalg_and_md_alg_from_sig_alg() understands sig_alg code points across + * TLS versions. Make sure that the received sig_alg extension is valid in TLS 1.2. + */ + if (!mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) { + MBEDTLS_SSL_DEBUG_MSG(1, + ("Server used unsupported value in SigAlg extension 0x%04x", + sig_alg)); + return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; + } + + /* + * Check if the signature algorithm is acceptable + */ + if (!mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg)) { + MBEDTLS_SSL_DEBUG_MSG(1, ("Server used SigAlg value 0x%04x that was not offered", sig_alg)); + return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; + } + + MBEDTLS_SSL_DEBUG_MSG(2, ("Server used SignatureAlgorithm %d", sig_alg & 0x00FF)); + MBEDTLS_SSL_DEBUG_MSG(2, ("Server used HashAlgorithm %d", sig_alg >> 8)); + + return 0; +} +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) */ + MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl) { @@ -2300,7 +2340,6 @@ static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl) unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); size_t params_len = (size_t) (p - params); void *rs_ctx = NULL; - uint16_t sig_alg; mbedtls_pk_context *peer_pk; @@ -2319,11 +2358,8 @@ static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl) * Handle the digitally-signed structure */ MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - sig_alg = MBEDTLS_GET_UINT16_BE(p, 0); - if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg( - sig_alg, &pk_alg, &md_alg) != 0 && - !mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg) && - !mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) { + uint16_t sig_alg = MBEDTLS_GET_UINT16_BE(p, 0); + if (ssl_parse_signature_algorithm(ssl, sig_alg, &md_alg, &pk_alg) != 0) { MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); mbedtls_ssl_send_alert_message( @@ -2764,7 +2800,7 @@ static int ssl_write_client_key_exchange(mbedtls_ssl_context *ssl) header_len = 4; - MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation.")); + MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based ECDH computation.")); /* * Generate EC private key for ECDHE exchange. @@ -2936,7 +2972,7 @@ static int ssl_write_client_key_exchange(mbedtls_ssl_context *ssl) header_len += ssl->conf->psk_identity_len; - MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation.")); + MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based ECDH computation.")); /* * Generate EC private key for ECDHE exchange. diff --git a/vendor/mbedtls/library/ssl_tls12_server.c b/vendor/mbedtls/library/ssl_tls12_server.c index 2d73855..d2ee9a0 100644 --- a/vendor/mbedtls/library/ssl_tls12_server.c +++ b/vendor/mbedtls/library/ssl_tls12_server.c @@ -912,132 +912,70 @@ static int ssl_parse_client_hello(mbedtls_ssl_context *ssl) MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client hello")); - int renegotiating; - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -read_record_header: -#endif - /* - * If renegotiating, then the input was read with mbedtls_ssl_read_record(), - * otherwise read it ourselves manually in order to support SSLv2 - * ClientHello, which doesn't use the same record layer format. - * Otherwise in a scenario of TLS 1.3/TLS 1.2 version negotiation, the - * ClientHello has been already fully fetched by the TLS 1.3 code and the - * flag ssl->keep_current_message is raised. - */ - renegotiating = 0; -#if defined(MBEDTLS_SSL_RENEGOTIATION) - renegotiating = (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE); -#endif - if (!renegotiating && !ssl->keep_current_message) { - if ((ret = mbedtls_ssl_fetch_input(ssl, 5)) != 0) { - /* No alert on a read error. */ - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret); - return ret; - } - } - - buf = ssl->in_hdr; - - MBEDTLS_SSL_DEBUG_BUF(4, "record header", buf, mbedtls_ssl_in_hdr_len(ssl)); - /* - * TLS Client Hello - * - * Record layer: - * 0 . 0 message type - * 1 . 2 protocol version - * 3 . 11 DTLS: epoch + record sequence number - * 3 . 4 message length + * Fetch the expected ClientHello handshake message. Do not ask + * mbedtls_ssl_read_record() to update the handshake digest, because the + * ClientHello may already have been read in ssl_tls13_process_client_hello() + * or as a post-handshake message (renegotiation). In those cases we need + * to update the digest ourselves, and it is simpler to do so + * unconditionally than to track whether it is needed. */ - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message type: %d", - buf[0])); - - if (buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } + if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record ", ret); - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message len.: %d", - MBEDTLS_GET_UINT16_BE(ssl->in_len, 0))); - - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, protocol version: [%d:%d]", - buf[1], buf[2])); - - /* For DTLS if this is the initial handshake, remember the client sequence - * number to use it in our next message (RFC 6347 4.2.1) */ #if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM + /* + * In the case of an alert message corresponding to the termination of + * a previous connection, `ssl_parse_record_header()` and then + * `mbedtls_ssl_read_record()` may return + * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD because of a non zero epoch. + * + * Historically, the library has returned + * MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE in this situation. + * The sample program dtls_server.c relies on this behavior + * (see + * https://github.com/Mbed-TLS/mbedtls/blob/d5e35a376bee23fad0b17f2e3e94a32ce4017c64/programs/ssl/dtls_server.c#L295), + * and user applications may rely on it as well. + * + * For compatibility, map MBEDTLS_ERR_SSL_UNEXPECTED_RECORD + * to MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE here. + * + * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD does not appear to be + * used to detect a specific error condition, so this mapping + * should not remove any meaningful distinction. + */ + if ((ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) #if defined(MBEDTLS_SSL_RENEGOTIATION) - && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE + && (ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE) #endif - ) { - /* Epoch should be 0 for initial handshakes */ - if (ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - memcpy(&ssl->cur_out_ctr[2], ssl->in_ctr + 2, - sizeof(ssl->cur_out_ctr) - 2); - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - if (mbedtls_ssl_dtls_replay_check(ssl) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record, discarding")); - ssl->next_record_offset = 0; - ssl->in_left = 0; - goto read_record_header; + ) { + if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) { + MBEDTLS_SSL_DEBUG_MSG(1, ("mapping UNEXPECTED_RECORD to UNEXPECTED_MESSAGE")); + ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; + } } - - /* No MAC to check yet, so we can update right now */ - mbedtls_ssl_dtls_replay_update(ssl); -#endif - } #endif /* MBEDTLS_SSL_PROTO_DTLS */ - msg_len = MBEDTLS_GET_UINT16_BE(ssl->in_len, 0); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { - /* Set by mbedtls_ssl_read_record() */ - msg_len = ssl->in_hslen; - } else -#endif - { - if (ssl->keep_current_message) { - ssl->keep_current_message = 0; - } else { - if (msg_len > MBEDTLS_SSL_IN_CONTENT_LEN) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - if ((ret = mbedtls_ssl_fetch_input(ssl, - mbedtls_ssl_in_hdr_len(ssl) + msg_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret); - return ret; - } - - /* Done reading this record, get ready for the next one */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len(ssl); - } else -#endif - ssl->in_left = 0; - } + return ret; } - buf = ssl->in_msg; - - MBEDTLS_SSL_DEBUG_BUF(4, "record contents", buf, msg_len); - - ret = ssl->handshake->update_checksum(ssl, buf, msg_len); + /* + * Update the handshake checksum. + * + * Note that the checksum must be updated before parsing the extensions + * because ssl_parse_session_ticket_ext() may decrypt the ticket in place + * and therefore modify the ClientHello message. This occurs when using + * the Mbed TLS ssl_ticket.c implementation. + */ + ret = mbedtls_ssl_update_handshake_status(ssl); if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); + MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret); return ret; } + buf = ssl->in_msg; + msg_len = ssl->in_hslen; + /* * Handshake layer: * 0 . 0 handshake type @@ -1046,64 +984,12 @@ static int ssl_parse_client_hello(mbedtls_ssl_context *ssl) * 6 . 8 DTLS only: fragment offset * 9 . 11 DTLS only: fragment length */ - if (msg_len < mbedtls_ssl_hs_hdr_len(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake type: %d", buf[0])); - - if (buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) { + if ((ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) || + (buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO)) { MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; } -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - /* - * Copy the client's handshake message_seq on initial handshakes, - * check sequence number on renego. - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { - /* This couldn't be done in ssl_prepare_handshake_record() */ - unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4); - if (cli_msg_seq != ssl->handshake->in_msg_seq) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: " - "%u (expected %u)", cli_msg_seq, - ssl->handshake->in_msg_seq)); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - ssl->handshake->in_msg_seq++; - } else -#endif - { - unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4); - ssl->handshake->out_msg_seq = cli_msg_seq; - ssl->handshake->in_msg_seq = cli_msg_seq + 1; - } - { - /* - * For now we don't support fragmentation, so make sure - * fragment_offset == 0 and fragment_length == length - */ - size_t fragment_offset, fragment_length, length; - fragment_offset = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6); - fragment_length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9); - length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1); - MBEDTLS_SSL_DEBUG_MSG( - 4, ("fragment_offset=%u fragment_length=%u length=%u", - (unsigned) fragment_offset, (unsigned) fragment_length, - (unsigned) length)); - if (fragment_offset != 0 || length != fragment_length) { - MBEDTLS_SSL_DEBUG_MSG(1, ("ClientHello fragmentation not supported")); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - buf += mbedtls_ssl_hs_hdr_len(ssl); msg_len -= mbedtls_ssl_hs_hdr_len(ssl); @@ -1433,7 +1319,11 @@ static int ssl_parse_client_hello(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_SESSION_TICKETS) case MBEDTLS_TLS_EXT_SESSION_TICKET: MBEDTLS_SSL_DEBUG_MSG(3, ("found session ticket extension")); - + /* + * If the Mbed TLS ssl_ticket.c implementation is used, the + * ticket is decrypted in place. This modifies the ClientHello + * message in the input buffer. + */ ret = ssl_parse_session_ticket_ext(ssl, ext + 4, ext_size); if (ret != 0) { return ret; @@ -2982,7 +2872,7 @@ static int ssl_prepare_server_key_exchange(mbedtls_ssl_context *ssl, psa_key_type_t key_type = PSA_KEY_TYPE_NONE; size_t ec_bits = 0; - MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation.")); + MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based ECDH computation.")); /* Convert EC's TLS ID to PSA key type. */ if (mbedtls_ssl_get_psa_curve_info_from_tls_id(*curr_tls_id, diff --git a/vendor/mbedtls/library/ssl_tls13_client.c b/vendor/mbedtls/library/ssl_tls13_client.c index 78a069f..752bc03 100644 --- a/vendor/mbedtls/library/ssl_tls13_client.c +++ b/vendor/mbedtls/library/ssl_tls13_client.c @@ -2270,6 +2270,9 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) { mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED); + + /* Since we're not using a certificate, set verify_result to success */ + ssl->session_negotiate->verify_result = 0; } else { mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_REQUEST); } diff --git a/vendor/mbedtls/library/ssl_tls13_server.c b/vendor/mbedtls/library/ssl_tls13_server.c index 5757d20..a72ed25 100644 --- a/vendor/mbedtls/library/ssl_tls13_server.c +++ b/vendor/mbedtls/library/ssl_tls13_server.c @@ -1776,6 +1776,11 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; } + if (handshake->key_exchange_mode != + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) { + hrr_required = (no_usable_share_for_key_agreement != 0); + } + #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) if (handshake->key_exchange_mode & MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL) { @@ -1786,17 +1791,12 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, ((unsigned) psk.ciphersuite_info->id), psk.ciphersuite_info->name)); - if (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) { + if (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION && (!hrr_required)) { handshake->resume = 1; } } #endif - if (handshake->key_exchange_mode != - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) { - hrr_required = (no_usable_share_for_key_agreement != 0); - } - mbedtls_ssl_optimize_checksum(ssl, handshake->ciphersuite_info); return hrr_required ? SSL_CLIENT_HELLO_HRR_REQUIRED : SSL_CLIENT_HELLO_OK; @@ -1969,6 +1969,9 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl) /* * Version 1.2 of the protocol has to be used for the handshake. + * If we have sent an HRR, then the second ClientHello is inconsistent + * with the first one and we abort the handshake with an `illegal_parameter` + * fatal alert. * If TLS 1.2 is not supported, abort the handshake. Otherwise, set the * ssl->keep_current_message flag for the ClientHello to be kept and parsed * as a TLS 1.2 ClientHello. We also change ssl->tls_version to @@ -1976,7 +1979,12 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl) * will dispatch to the TLS 1.2 state machine. */ if (SSL_CLIENT_HELLO_TLS1_2 == parse_client_hello_ret) { - /* Check if server supports TLS 1.2 */ + if (ssl->handshake->hello_retry_request_flag) { + MBEDTLS_SSL_DEBUG_MSG(1, ("Non compliant 2nd ClientHello, TLS 1.2 version")); + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, + MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); + return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; + } if (!mbedtls_ssl_conf_is_tls12_enabled(ssl->conf)) { MBEDTLS_SSL_DEBUG_MSG( 1, ("TLS 1.2 not supported.")); @@ -2637,6 +2645,9 @@ static int ssl_tls13_write_encrypted_extensions(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) { mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED); + + /* Since we're not using a certificate, set verify_result to success */ + ssl->session_negotiate->verify_result = 0; } else { mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_REQUEST); } diff --git a/vendor/mbedtls/library/threading.c b/vendor/mbedtls/library/threading.c index ff8183e..8764b3e 100644 --- a/vendor/mbedtls/library/threading.c +++ b/vendor/mbedtls/library/threading.c @@ -21,9 +21,7 @@ #if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) -#if !defined(_WIN32) && (defined(unix) || \ - defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__))) +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) #include #endif /* !_WIN32 && (unix || __unix || __unix__ || * (__APPLE__ && __MACH__)) */ diff --git a/vendor/mbedtls/library/timing.c b/vendor/mbedtls/library/timing.c index 58f1c1e..e3e9da5 100644 --- a/vendor/mbedtls/library/timing.c +++ b/vendor/mbedtls/library/timing.c @@ -13,9 +13,7 @@ #if !defined(MBEDTLS_TIMING_ALT) -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) && !defined(__midipix__) +#if !defined(_WIN32) && !defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) #error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in mbedtls_config.h" #endif diff --git a/vendor/mbedtls/library/x509_create.c b/vendor/mbedtls/library/x509_create.c index 420e36b..fc23fb8 100644 --- a/vendor/mbedtls/library/x509_create.c +++ b/vendor/mbedtls/library/x509_create.c @@ -310,6 +310,9 @@ int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *nam } else { oid.len = strlen(attr_descr->oid); oid.p = mbedtls_calloc(1, oid.len); + if (oid.p == NULL) { + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } memcpy(oid.p, attr_descr->oid, oid.len); numericoid = 0; } diff --git a/vendor/mbedtls/library/x509_crt.c b/vendor/mbedtls/library/x509_crt.c index 53cdcf0..f15aa99 100644 --- a/vendor/mbedtls/library/x509_crt.c +++ b/vendor/mbedtls/library/x509_crt.c @@ -2748,22 +2748,25 @@ static int x509_inet_pton_ipv6(const char *src, void *dst) if (*p == '\0') { break; } else if (*p == '.') { - /* Don't accept IPv4 too early or late */ - if ((nonzero_groups == 0 && zero_group_start == -1) || + /* Don't accept IPv4 too early or late: + * - The first 6 nonzero groups must be 16 bit pieces of address delimited by ':' + * - This might be fully or partially represented with compressed syntax (a zero + * group "::") + */ + if ((nonzero_groups < 6 && zero_group_start == -1) || nonzero_groups >= 7) { break; } - /* Walk back to prior ':', then parse as IPv4-mapped */ - int steps = 4; + /* Walk back to prior ':', then parse as IPv4-mapped. + * At this point nonzero_groups == 6 or zero_group_start >= 0. Either way we have a + * ':' before the current position and still inside the buffer. Thus it is safe to + * search back for that ':' without any further checks. + */ do { p--; - steps--; - } while (*p != ':' && steps > 0); + } while (*p != ':'); - if (*p != ':') { - break; - } p++; nonzero_groups--; if (x509_inet_pton_ipv4((const char *) p,