feat: modules moved and engine moved to submodule

This commit is contained in:
Jan van der Weide 2025-04-12 18:40:44 +02:00
parent dfb5e645cd
commit c33d2130cc
5136 changed files with 225275 additions and 64485 deletions

View file

@ -489,7 +489,7 @@ int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx,
"movdqu %%xmm0, (%4) \n\t" // export output
:
: "r" (ctx->nr), "r" (ctx->buf + ctx->rk_offset), "r" (mode), "r" (input), "r" (output)
: "memory", "cc", "xmm0", "xmm1");
: "memory", "cc", "xmm0", "xmm1", "0", "1");
return 0;
@ -679,7 +679,7 @@ static void aesni_setkey_enc_128(unsigned char *rk,
AESKEYGENA(xmm0_xmm1, "0x36") "call 1b \n\t"
:
: "r" (rk), "r" (key)
: "memory", "cc", "0");
: "memory", "cc", "xmm0", "xmm1", "0");
}
/*
@ -737,7 +737,7 @@ static void aesni_setkey_enc_192(unsigned char *rk,
:
: "r" (rk), "r" (key)
: "memory", "cc", "0");
: "memory", "cc", "xmm0", "xmm1", "xmm2", "0");
}
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
@ -805,7 +805,7 @@ static void aesni_setkey_enc_256(unsigned char *rk,
AESKEYGENA(xmm1_xmm2, "0x40") "call 1b \n\t"
:
: "r" (rk), "r" (key)
: "memory", "cc", "0");
: "memory", "cc", "xmm0", "xmm1", "xmm2", "0");
}
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */

View file

@ -747,8 +747,8 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A,
}
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
// Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
int mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
void (*mbedtls_safe_codepath_hook)(void) = NULL;
void (*mbedtls_unsafe_codepath_hook)(void) = NULL;
#endif
/*
@ -781,7 +781,9 @@ static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint
*E_bit_index = E_bits % biL;
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC;
if (mbedtls_unsafe_codepath_hook != NULL) {
mbedtls_unsafe_codepath_hook();
}
#endif
} else {
/*
@ -791,9 +793,8 @@ static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint
*E_limb_index = E_limbs;
*E_bit_index = 0;
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
// Only mark the codepath safe if there wasn't an unsafe codepath before
if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) {
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET;
if (mbedtls_safe_codepath_hook != NULL) {
mbedtls_safe_codepath_hook();
}
#endif
}
@ -813,7 +814,9 @@ static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselec
if (window_public == MBEDTLS_MPI_IS_PUBLIC) {
memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL);
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC;
if (mbedtls_unsafe_codepath_hook != NULL) {
mbedtls_unsafe_codepath_hook();
}
#endif
} else {
/* Select Wtable[window] without leaking window through
@ -821,9 +824,8 @@ static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselec
mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
AN_limbs, welem, window);
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
// Only mark the codepath safe if there wasn't an unsafe codepath before
if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) {
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET;
if (mbedtls_safe_codepath_hook != NULL) {
mbedtls_safe_codepath_hook();
}
#endif
}
@ -857,8 +859,8 @@ static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X,
/* We'll process the bits of E from most significant
* (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
* (limb_index=0, E_bit_index=0). */
size_t E_limb_index;
size_t E_bit_index;
size_t E_limb_index = E_limbs;
size_t E_bit_index = 0;
exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public,
&E_limb_index, &E_bit_index);

View file

@ -70,9 +70,7 @@
#include "common.h"
#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
#endif
#include "constant_time_internal.h"
@ -106,10 +104,17 @@
* } else {
* // safe path
* }
* not the other way round, in order to prevent misuse. (This is, if a value
* other than the two below is passed, default to the safe path.) */
* not the other way round, in order to prevent misuse. (That is, if a value
* other than the two below is passed, default to the safe path.)
*
* The value of MBEDTLS_MPI_IS_PUBLIC is chosen in a way that is unlikely to happen by accident, but
* which can be used as an immediate value in a Thumb2 comparison (for code size). */
#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a2a2a
#define MBEDTLS_MPI_IS_SECRET 0
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
// Default value for testing that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
#define MBEDTLS_MPI_IS_TEST 1
#endif
/** Count leading zero bits in a given integer.
*
@ -817,17 +822,4 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X,
mbedtls_mpi_uint mm,
mbedtls_mpi_uint *T);
/*
* Can't define thread local variables with our abstraction layer: do nothing if threading is on.
*/
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
extern int mbedtls_mpi_optionally_safe_codepath;
static inline void mbedtls_mpi_optionally_safe_codepath_reset(void)
{
// Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
}
#endif
#endif /* MBEDTLS_BIGNUM_CORE_H */

View file

@ -170,11 +170,12 @@ static int ccm_calculate_first_block_if_ready(mbedtls_ccm_context *ctx)
}
/* CCM expects non-empty tag.
* CCM* allows empty tag. For CCM* without tag, ignore plaintext length.
* CCM* allows empty tag. For CCM* without tag, the tag calculation is skipped.
*/
if (ctx->tag_len == 0) {
if (ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT || ctx->mode == MBEDTLS_CCM_STAR_DECRYPT) {
ctx->plaintext_len = 0;
return 0;
} else {
return MBEDTLS_ERR_CCM_BAD_INPUT;
}

View file

@ -36,24 +36,9 @@
#pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
/* Disable asm under Memsan because it confuses Memsan and generates false errors.
*
* We also disable under Valgrind by default, because it's more useful
* for Valgrind to test the plain C implementation. MBEDTLS_TEST_CONSTANT_FLOW_ASM //no-check-names
* may be set to permit building asm under Valgrind.
*/
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) || \
(defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND) && !defined(MBEDTLS_TEST_CONSTANT_FLOW_ASM)) //no-check-names
#define MBEDTLS_CT_NO_ASM
#elif defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define MBEDTLS_CT_NO_ASM
#endif
#endif
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && (!defined(__ARMCC_VERSION) || \
__ARMCC_VERSION >= 6000000) && !defined(MBEDTLS_CT_NO_ASM)
__ARMCC_VERSION >= 6000000)
#define MBEDTLS_CT_ASM
#if (defined(__arm__) || defined(__thumb__) || defined(__thumb2__))
#define MBEDTLS_CT_ARM_ASM

View file

@ -3056,7 +3056,7 @@ int mbedtls_ecp_check_privkey(const mbedtls_ecp_group *grp,
/* see RFC 7748 sec. 5 para. 5 */
if (mbedtls_mpi_get_bit(d, 0) != 0 ||
mbedtls_mpi_get_bit(d, 1) != 0 ||
mbedtls_mpi_bitlen(d) - 1 != grp->nbits) { /* mbedtls_mpi_bitlen is one-based! */
mbedtls_mpi_bitlen(d) != grp->nbits + 1) { /* mbedtls_mpi_bitlen is one-based! */
return MBEDTLS_ERR_ECP_INVALID_KEY;
}

View file

@ -479,6 +479,8 @@ const char *mbedtls_high_level_strerr(int error_code)
return( "SSL - An operation failed due to an unexpected version or configuration" );
case -(MBEDTLS_ERR_SSL_BAD_CONFIG):
return( "SSL - Invalid value in SSL config" );
case -(MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME):
return( "SSL - Attempt to verify a certificate without an expected hostname. This is usually insecure. In TLS clients, when a client authenticates a server through its certificate, the client normally checks three things: - the certificate chain must be valid; - the chain must start from a trusted CA; - the certificate must cover the server name that is expected by the client. Omitting any of these checks is generally insecure, and can allow a malicious server to impersonate a legitimate server. The third check may be safely skipped in some unusual scenarios, such as networks where eavesdropping is a risk but not active attacks, or a private PKI where the client equally trusts all servers that are accredited by the root CA. You should call mbedtls_ssl_set_hostname() with the expected server name before starting a TLS handshake on a client (unless the client is set up to only use PSK-based authentication, which does not rely on the host name). If you have determined that server name verification is not required for security in your scenario, call mbedtls_ssl_set_hostname() with \\p NULL as the server name. This error is raised if all of the following conditions are met: - A TLS client is configured with the authentication mode #MBEDTLS_SSL_VERIFY_REQUIRED (default). - Certificate authentication is enabled. - The client does not call mbedtls_ssl_set_hostname(). - The configuration option #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME is not enabled" );
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
@ -873,8 +875,4 @@ void mbedtls_strerror(int ret, char *buf, size_t buflen)
#endif /* MBEDTLS_ERROR_C */
#if defined(MBEDTLS_TEST_HOOKS)
void (*mbedtls_test_hook_error_add)(int, int, const char *, int);
#endif
#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */

View file

@ -190,7 +190,7 @@ int mbedtls_net_connect(mbedtls_net_context *ctx, const char *host,
break;
}
close(ctx->fd);
mbedtls_net_close(ctx);
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
}
@ -237,13 +237,13 @@ int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char *
n = 1;
if (setsockopt(ctx->fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &n, sizeof(n)) != 0) {
close(ctx->fd);
mbedtls_net_close(ctx);
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
continue;
}
if (bind(ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen) != 0) {
close(ctx->fd);
mbedtls_net_close(ctx);
ret = MBEDTLS_ERR_NET_BIND_FAILED;
continue;
}
@ -251,7 +251,7 @@ int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char *
/* Listen only makes sense for TCP */
if (proto == MBEDTLS_NET_PROTO_TCP) {
if (listen(ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG) != 0) {
close(ctx->fd);
mbedtls_net_close(ctx);
ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
continue;
}
@ -524,8 +524,8 @@ void mbedtls_net_usleep(unsigned long usec)
#else
struct timeval tv;
tv.tv_sec = usec / 1000000;
#if defined(__unix__) || defined(__unix) || \
(defined(__APPLE__) && defined(__MACH__))
#if (defined(__unix__) || defined(__unix) || \
(defined(__APPLE__) && defined(__MACH__))) && !defined(__DJGPP__)
tv.tv_usec = (suseconds_t) usec % 1000000;
#else
tv.tv_usec = usec % 1000000;

View file

@ -35,10 +35,6 @@
#include <limits.h>
#include <stdint.h>
#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_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
/*
* Initialise a mbedtls_pk_context
*/

View file

@ -705,6 +705,11 @@ MBEDTLS_STATIC_TESTABLE psa_status_t psa_mac_key_can_do(
psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot,
size_t buffer_length)
{
#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
if (buffer_length > ((size_t) MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE)) {
return PSA_ERROR_NOT_SUPPORTED;
}
#else
if (slot->key.data != NULL) {
return PSA_ERROR_ALREADY_EXISTS;
}
@ -713,6 +718,7 @@ psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot,
if (slot->key.data == NULL) {
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
#endif
slot->key.bytes = buffer_length;
return PSA_SUCCESS;
@ -1177,11 +1183,18 @@ static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot)
{
#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
if (slot->key.bytes > 0) {
mbedtls_platform_zeroize(slot->key.data, MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE);
}
#else
if (slot->key.data != NULL) {
mbedtls_zeroize_and_free(slot->key.data, slot->key.bytes);
}
slot->key.data = NULL;
#endif /* MBEDTLS_PSA_STATIC_KEY_SLOTS */
slot->key.bytes = 0;
return PSA_SUCCESS;
@ -2096,7 +2109,7 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
* storage ( thus not in the case of importing a key in a secure element
* with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
* buffer to hold the imported key material. */
if (slot->key.data == NULL) {
if (slot->key.bytes == 0) {
if (psa_key_lifetime_is_external(attributes->lifetime)) {
status = psa_driver_wrapper_get_key_buffer_size_from_key_data(
attributes, data, data_length, &storage_size);
@ -2306,6 +2319,58 @@ exit:
/* Message digests */
/****************************************************************/
static int is_hash_supported(psa_algorithm_t alg)
{
switch (alg) {
#if defined(PSA_WANT_ALG_MD5)
case PSA_ALG_MD5:
return 1;
#endif
#if defined(PSA_WANT_ALG_RIPEMD160)
case PSA_ALG_RIPEMD160:
return 1;
#endif
#if defined(PSA_WANT_ALG_SHA_1)
case PSA_ALG_SHA_1:
return 1;
#endif
#if defined(PSA_WANT_ALG_SHA_224)
case PSA_ALG_SHA_224:
return 1;
#endif
#if defined(PSA_WANT_ALG_SHA_256)
case PSA_ALG_SHA_256:
return 1;
#endif
#if defined(PSA_WANT_ALG_SHA_384)
case PSA_ALG_SHA_384:
return 1;
#endif
#if defined(PSA_WANT_ALG_SHA_512)
case PSA_ALG_SHA_512:
return 1;
#endif
#if defined(PSA_WANT_ALG_SHA3_224)
case PSA_ALG_SHA3_224:
return 1;
#endif
#if defined(PSA_WANT_ALG_SHA3_256)
case PSA_ALG_SHA3_256:
return 1;
#endif
#if defined(PSA_WANT_ALG_SHA3_384)
case PSA_ALG_SHA3_384:
return 1;
#endif
#if defined(PSA_WANT_ALG_SHA3_512)
case PSA_ALG_SHA3_512:
return 1;
#endif
default:
return 0;
}
}
psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
{
/* Aborting a non-active operation is allowed */
@ -2949,16 +3014,44 @@ static psa_status_t psa_sign_verify_check_alg(int input_is_message,
if (!PSA_ALG_IS_SIGN_MESSAGE(alg)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
if (PSA_ALG_IS_SIGN_HASH(alg)) {
if (!PSA_ALG_IS_HASH(PSA_ALG_SIGN_GET_HASH(alg))) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
} else {
if (!PSA_ALG_IS_SIGN_HASH(alg)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_algorithm_t hash_alg = 0;
if (PSA_ALG_IS_SIGN_HASH(alg)) {
hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
}
/* Now hash_alg==0 if alg by itself doesn't need a hash.
* This is good enough for sign-hash, but a guaranteed failure for
* sign-message which needs to hash first for all algorithms
* supported at the moment. */
if (hash_alg == 0 && input_is_message) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (hash_alg == PSA_ALG_ANY_HASH) {
return PSA_ERROR_INVALID_ARGUMENT;
}
/* Give up immediately if the hash is not supported. This has
* several advantages:
* - For mechanisms that don't use the hash at all (e.g.
* ECDSA verification, randomized ECDSA signature), without
* this check, the operation would succeed even though it has
* been given an invalid argument. This would not be insecure
* since the hash was not necessary, but it would be weird.
* - For mechanisms that do use the hash, we avoid an error
* deep inside the execution. In principle this doesn't matter,
* but there is a little more risk of a bug in error handling
* deep inside than in this preliminary check.
* - When calling a driver, the driver might be capable of using
* a hash that the core doesn't support. This could potentially
* result in a buffer overflow if the hash is larger than the
* maximum hash size assumed by the core.
* - Returning a consistent error makes it possible to test
* not-supported hashes in a consistent way.
*/
if (hash_alg != 0 && !is_hash_supported(hash_alg)) {
return PSA_ERROR_NOT_SUPPORTED;
}
return PSA_SUCCESS;
@ -3839,6 +3932,34 @@ uint32_t mbedtls_psa_verify_hash_get_num_ops(
* defined( MBEDTLS_ECP_RESTARTABLE ) */
}
/* Detect supported interruptible sign/verify mechanisms precisely.
* This is not strictly needed: we could accept everything, and let the
* code fail later during complete() if the mechanism is unsupported
* (e.g. attempting deterministic ECDSA when only the randomized variant
* is available). But it's easier for applications and especially for our
* test code to detect all not-supported errors during start().
*
* Note that this function ignores the hash component. The core code
* is supposed to check the hash part by calling is_hash_supported().
*/
static inline int can_do_interruptible_sign_verify(psa_algorithm_t alg)
{
#if defined(MBEDTLS_ECP_RESTARTABLE)
#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
return 1;
}
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA)
if (PSA_ALG_IS_RANDOMIZED_ECDSA(alg)) {
return 1;
}
#endif
#endif /* defined(MBEDTLS_ECP_RESTARTABLE) */
(void) alg;
return 0;
}
psa_status_t mbedtls_psa_sign_hash_start(
mbedtls_psa_sign_hash_interruptible_operation_t *operation,
const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
@ -3848,11 +3969,15 @@ psa_status_t mbedtls_psa_sign_hash_start(
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t required_hash_length;
if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) {
if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type)) {
return PSA_ERROR_NOT_SUPPORTED;
}
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type);
if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(curve)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (!PSA_ALG_IS_ECDSA(alg)) {
if (!can_do_interruptible_sign_verify(alg)) {
return PSA_ERROR_NOT_SUPPORTED;
}
@ -4067,8 +4192,12 @@ psa_status_t mbedtls_psa_verify_hash_start(
if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) {
return PSA_ERROR_NOT_SUPPORTED;
}
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type);
if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(curve)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (!PSA_ALG_IS_ECDSA(alg)) {
if (!can_do_interruptible_sign_verify(alg)) {
return PSA_ERROR_NOT_SUPPORTED;
}
@ -6187,7 +6316,7 @@ static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper(
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t m;
size_t m_bytes;
size_t m_bytes = 0;
mbedtls_mpi_init(&k);
mbedtls_mpi_init(&diff_N_2);
@ -6260,7 +6389,7 @@ cleanup:
status = mbedtls_to_psa_error(ret);
}
if (status != PSA_SUCCESS) {
mbedtls_free(*data);
mbedtls_zeroize_and_free(*data, m_bytes);
*data = NULL;
}
mbedtls_mpi_free(&k);
@ -6435,7 +6564,7 @@ static psa_status_t psa_generate_derived_key_internal(
}
exit:
mbedtls_free(data);
mbedtls_zeroize_and_free(data, bytes);
return status;
}
@ -7359,6 +7488,12 @@ static psa_status_t psa_key_derivation_input_internal(
psa_status_t status;
psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
if (kdf_alg == PSA_ALG_NONE) {
/* This is a blank or aborted operation. */
status = PSA_ERROR_BAD_STATE;
goto exit;
}
status = psa_key_derivation_check_input_type(step, key_type);
if (status != PSA_SUCCESS) {
goto exit;
@ -7417,6 +7552,12 @@ static psa_status_t psa_key_derivation_input_integer_internal(
psa_status_t status;
psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
if (kdf_alg == PSA_ALG_NONE) {
/* This is a blank or aborted operation. */
status = PSA_ERROR_BAD_STATE;
goto exit;
}
#if defined(PSA_HAVE_SOFT_PBKDF2)
if (PSA_ALG_IS_PBKDF2(kdf_alg)) {
status = psa_pbkdf2_set_input_cost(
@ -7430,6 +7571,7 @@ static psa_status_t psa_key_derivation_input_integer_internal(
status = PSA_ERROR_INVALID_ARGUMENT;
}
exit:
if (status != PSA_SUCCESS) {
psa_key_derivation_abort(operation);
}
@ -8013,7 +8155,7 @@ psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes,
* storage ( thus not in the case of generating a key in a secure element
* with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
* buffer to hold the generated key material. */
if (slot->key.data == NULL) {
if (slot->key.bytes == 0) {
if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime) ==
PSA_KEY_LOCATION_LOCAL_STORAGE) {
status = psa_validate_key_type_and_size_for_key_generation(
@ -9171,7 +9313,7 @@ psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len
return PSA_SUCCESS;
error:
mbedtls_free(local_input->buffer);
mbedtls_zeroize_and_free(local_input->buffer, local_input->length);
local_input->buffer = NULL;
local_input->length = 0;
return status;
@ -9179,7 +9321,7 @@ error:
void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input)
{
mbedtls_free(local_input->buffer);
mbedtls_zeroize_and_free(local_input->buffer, local_input->length);
local_input->buffer = NULL;
local_input->length = 0;
}
@ -9223,7 +9365,7 @@ psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_outpu
return status;
}
mbedtls_free(local_output->buffer);
mbedtls_zeroize_and_free(local_output->buffer, local_output->length);
local_output->buffer = NULL;
local_output->length = 0;

View file

@ -71,9 +71,6 @@ static psa_status_t mbedtls_cipher_validate_values(
#if !defined(PSA_WANT_ALG_OFB)
MBEDTLS_ASSUME(alg != PSA_ALG_OFB);
#endif
#if !defined(PSA_WANT_ALG_XTS)
MBEDTLS_ASSUME(alg != PSA_ALG_XTS);
#endif
#if !defined(PSA_WANT_ALG_ECB_NO_PADDING)
MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING);
#endif

View file

@ -24,18 +24,6 @@
#include "mbedtls/threading.h"
#endif
/**
* Tell if PSA is ready for this hash.
*
* \note For now, only checks the state of the driver subsystem,
* not the algorithm. Might do more in the future.
*
* \param hash_alg The hash algorithm (ignored for now).
*
* \return 1 if the driver subsytem is ready, 0 otherwise.
*/
int psa_can_do_hash(psa_algorithm_t hash_alg);
/**
* Tell if PSA is ready for this cipher.
*
@ -155,7 +143,11 @@ typedef struct {
/* Dynamically allocated key data buffer.
* Format as specified in psa_export_key(). */
struct key_data {
#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
uint8_t data[MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE];
#else
uint8_t *data;
#endif
size_t bytes;
} key;
} psa_key_slot_t;

View file

@ -306,8 +306,7 @@ static inline psa_status_t psa_driver_wrapper_sign_hash(
#endif /* PSA_CRYPTO_DRIVER_TEST */
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
PSA_ALG_IS_RANDOMIZED_ECDSA(alg) &&
PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
psa_get_key_bits(attributes) == 256 )
{
@ -411,7 +410,6 @@ static inline psa_status_t psa_driver_wrapper_verify_hash(
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
psa_get_key_bits(attributes) == 256 )
{

View file

@ -321,38 +321,36 @@ psa_status_t mbedtls_psa_ecp_generate_key(
const psa_key_attributes_t *attributes,
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
attributes->type);
mbedtls_ecp_group_id grp_id =
mbedtls_ecc_group_from_psa(curve, attributes->bits);
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_grp_id(grp_id);
mbedtls_ecp_keypair ecp;
if (grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL) {
if (grp_id == MBEDTLS_ECP_DP_NONE) {
return PSA_ERROR_NOT_SUPPORTED;
}
mbedtls_ecp_keypair ecp;
mbedtls_ecp_keypair_init(&ecp);
ret = mbedtls_ecp_gen_key(grp_id, &ecp,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE);
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_ecp_group_load(&ecp.grp, grp_id);
if (ret != 0) {
mbedtls_ecp_keypair_free(&ecp);
return mbedtls_to_psa_error(ret);
goto exit;
}
status = mbedtls_to_psa_error(
mbedtls_ecp_write_key_ext(&ecp, key_buffer_length,
key_buffer, key_buffer_size));
ret = mbedtls_ecp_gen_privkey(&ecp.grp, &ecp.d,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE);
if (ret != 0) {
goto exit;
}
ret = mbedtls_ecp_write_key_ext(&ecp, key_buffer_length,
key_buffer, key_buffer_size);
exit:
mbedtls_ecp_keypair_free(&ecp);
return status;
return mbedtls_to_psa_error(ret);
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE */

View file

@ -35,9 +35,9 @@ MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_USER_MIN < PSA_KEY_ID_USER_MAX,
"Empty user key ID range");
MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VENDOR_MIN < PSA_KEY_ID_VENDOR_MAX,
"Empty vendor key ID range");
MBEDTLS_STATIC_ASSERT(MBEDTLS_PSA_KEY_ID_BUILTIN_MIN < MBEDTLS_PSA_KEY_ID_BUILTIN_MAX,
MBEDTLS_STATIC_ASSERT(MBEDTLS_PSA_KEY_ID_BUILTIN_MIN <= MBEDTLS_PSA_KEY_ID_BUILTIN_MAX,
"Empty builtin key ID range");
MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MIN < PSA_KEY_ID_VOLATILE_MAX,
MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MIN <= PSA_KEY_ID_VOLATILE_MAX,
"Empty volatile key ID range");
MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_USER_MAX < PSA_KEY_ID_VENDOR_MIN ||

View file

@ -21,9 +21,16 @@ extern "C" {
#include <stdint.h>
#include <string.h>
/* Limit the maximum key size in storage. This should have no effect
* since the key size is limited in memory. */
/* Limit the maximum key size in storage. */
#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
/* Reflect the maximum size for the key buffer. */
#define PSA_CRYPTO_MAX_STORAGE_SIZE (MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE)
#else
/* Just set an upper boundary but it should have no effect since the key size
* is limited in memory. */
#define PSA_CRYPTO_MAX_STORAGE_SIZE (PSA_BITS_TO_BYTES(PSA_MAX_KEY_BITS))
#endif
/* Sanity check: a file size must fit in 32 bits. Allow a generous
* 64kB of metadata. */
#if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000

View file

@ -440,6 +440,9 @@ int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_l
unsigned char *p = der + der_size;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if (bits == 0) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
if (raw_len != (2 * coordinate_len)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
@ -559,6 +562,9 @@ int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_l
size_t coordinate_size = PSA_BITS_TO_BYTES(bits);
int ret;
if (bits == 0) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
/* The output raw buffer should be at least twice the size of a raw
* coordinate in order to store r and s. */
if (raw_size < coordinate_size * 2) {

View file

@ -29,19 +29,20 @@ static int ssl_write_hostname_ext(mbedtls_ssl_context *ssl,
size_t *olen)
{
unsigned char *p = buf;
const char *hostname = mbedtls_ssl_get_hostname_pointer(ssl);
size_t hostname_len;
*olen = 0;
if (ssl->hostname == NULL) {
if (hostname == NULL) {
return 0;
}
MBEDTLS_SSL_DEBUG_MSG(3,
("client hello, adding server name extension: %s",
ssl->hostname));
hostname));
hostname_len = strlen(ssl->hostname);
hostname_len = strlen(hostname);
MBEDTLS_SSL_CHK_BUF_PTR(p, end, hostname_len + 9);
@ -85,7 +86,7 @@ static int ssl_write_hostname_ext(mbedtls_ssl_context *ssl,
MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0);
p += 2;
memcpy(p, ssl->hostname, hostname_len);
memcpy(p, hostname, hostname_len);
*olen = hostname_len + 9;
@ -881,13 +882,14 @@ static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
const char *context_hostname = mbedtls_ssl_get_hostname_pointer(ssl);
if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
ssl->handshake->resume) {
int hostname_mismatch = ssl->hostname != NULL ||
int hostname_mismatch = context_hostname != NULL ||
session_negotiate->hostname != NULL;
if (ssl->hostname != NULL && session_negotiate->hostname != NULL) {
if (context_hostname != NULL && session_negotiate->hostname != NULL) {
hostname_mismatch = strcmp(
ssl->hostname, session_negotiate->hostname) != 0;
context_hostname, session_negotiate->hostname) != 0;
}
if (hostname_mismatch) {
@ -898,7 +900,7 @@ static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl)
}
} else {
return mbedtls_ssl_session_set_hostname(session_negotiate,
ssl->hostname);
context_hostname);
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 &&
MBEDTLS_SSL_SESSION_TICKETS &&

View file

@ -11,7 +11,7 @@
*
*/
#include "common.h"
#include "ssl_misc.h"
#if defined(MBEDTLS_DEBUG_C)

View file

@ -11,6 +11,7 @@
#define MBEDTLS_SSL_MISC_H
#include "mbedtls/build_info.h"
#include "common.h"
#include "mbedtls/error.h"
@ -47,7 +48,7 @@
#include "ssl_ciphersuites_internal.h"
#include "x509_internal.h"
#include "pk_internal.h"
#include "common.h"
/* Shorthand for restartable ECC */
#if defined(MBEDTLS_ECP_RESTARTABLE) && \
@ -2899,6 +2900,18 @@ int mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(
unsigned char *buf, unsigned char *end);
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
/** Get the host name from the SSL context.
*
* \param[in] ssl SSL context
*
* \return The \p hostname pointer from the SSL context.
* \c NULL if mbedtls_ssl_set_hostname() has never been called on
* \p ssl or if it was last called with \p NULL.
*/
const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl);
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
@ -2982,6 +2995,7 @@ static inline void mbedtls_ssl_tls13_session_clear_ticket_flags(
#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK \
(1 << MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT)
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
static inline int mbedtls_ssl_conf_get_session_tickets(
const mbedtls_ssl_config *conf)
{
@ -2989,6 +3003,7 @@ static inline int mbedtls_ssl_conf_get_session_tickets(
MBEDTLS_SSL_SESSION_TICKETS_ENABLED :
MBEDTLS_SSL_SESSION_TICKETS_DISABLED;
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
static inline int mbedtls_ssl_conf_is_signal_new_session_tickets_enabled(

View file

@ -3221,16 +3221,19 @@ static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl)
int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
{
/* First handshake fragment must at least include the header. */
if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl) && ssl->in_hslen == 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET,
ssl->in_msglen));
return MBEDTLS_ERR_SSL_INVALID_RECORD;
}
if (ssl->badmac_seen_or_in_hsfraglen == 0) {
/* The handshake message must at least include the header.
* We may not have the full message yet in case of fragmentation.
* To simplify the code, we insist on having the header (and in
* particular the handshake message length) in the first
* fragment. */
if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl)) {
MBEDTLS_SSL_DEBUG_MSG(1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET,
ssl->in_msglen));
return MBEDTLS_ERR_SSL_INVALID_RECORD;
}
if (ssl->in_hslen == 0) {
ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl);
ssl->badmac_seen_or_in_hsfraglen = 0;
}
MBEDTLS_SSL_DEBUG_MSG(3, ("handshake message: msglen ="
@ -3238,6 +3241,14 @@ int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
MBEDTLS_PRINTF_SIZET,
ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen));
if (ssl->transform_in != NULL) {
MBEDTLS_SSL_DEBUG_MSG(4, ("decrypted handshake message:"
" iv-buf=%d hdr-buf=%d hdr-buf=%d",
(int) (ssl->in_iv - ssl->in_buf),
(int) (ssl->in_hdr - ssl->in_buf),
(int) (ssl->in_msg - ssl->in_buf)));
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -3297,67 +3308,103 @@ int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
}
} else
#endif /* MBEDTLS_SSL_PROTO_DTLS */
if (ssl->badmac_seen_or_in_hsfraglen <= ssl->in_hslen) {
int ret;
{
unsigned char *const reassembled_record_start =
ssl->in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
unsigned char *const payload_start =
reassembled_record_start + mbedtls_ssl_in_hdr_len(ssl);
unsigned char *payload_end = payload_start + ssl->badmac_seen_or_in_hsfraglen;
/* How many more bytes we want to have a complete handshake message. */
const size_t hs_remain = ssl->in_hslen - ssl->badmac_seen_or_in_hsfraglen;
/* How many bytes of the current record are part of the first
* handshake message. There may be more handshake messages (possibly
* incomplete) in the same record; if so, we leave them after the
* current record, and ssl_consume_current_message() will take
* care of consuming the next handshake message. */
const size_t hs_this_fragment_len =
ssl->in_msglen > hs_remain ? hs_remain : ssl->in_msglen;
(void) hs_this_fragment_len;
MBEDTLS_SSL_DEBUG_MSG(3,
("handshake fragment: %u .. %"
MBEDTLS_PRINTF_SIZET " of %"
MBEDTLS_PRINTF_SIZET " msglen %" MBEDTLS_PRINTF_SIZET,
("%s handshake fragment: %" MBEDTLS_PRINTF_SIZET
", %u..%u of %" MBEDTLS_PRINTF_SIZET,
(ssl->badmac_seen_or_in_hsfraglen != 0 ?
"subsequent" :
hs_this_fragment_len == ssl->in_hslen ?
"sole" :
"initial"),
ssl->in_msglen,
ssl->badmac_seen_or_in_hsfraglen,
(size_t) ssl->badmac_seen_or_in_hsfraglen +
(hs_remain <= ssl->in_msglen ? hs_remain : ssl->in_msglen),
ssl->in_hslen, ssl->in_msglen));
if (ssl->in_msglen < hs_remain) {
/* ssl->in_msglen is a 25-bit value since it is the sum of the
* header length plus the payload length, the header length is 4
* and the payload length was received on the wire encoded as
* 3 octets. We don't support 16-bit platforms; more specifically,
* we assume that both unsigned and size_t are at least 32 bits.
* Therefore there is no possible integer overflow here.
*/
ssl->badmac_seen_or_in_hsfraglen += (unsigned) ssl->in_msglen;
ssl->in_hdr = ssl->in_msg + ssl->in_msglen;
ssl->badmac_seen_or_in_hsfraglen +
(unsigned) hs_this_fragment_len,
ssl->in_hslen));
/* Move the received handshake fragment to have the whole message
* (at least the part received so far) in a single segment at a
* known offset in the input buffer.
* - When receiving a non-initial handshake fragment, append it to
* the initial segment.
* - Even the initial handshake fragment is moved, if it was
* encrypted with an explicit IV: decryption leaves the payload
* after the explicit IV, but here we move it to start where the
* IV was.
*/
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
size_t const in_buf_len = ssl->in_buf_len;
#else
size_t const in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
#endif
if (payload_end + ssl->in_msglen > ssl->in_buf + in_buf_len) {
MBEDTLS_SSL_DEBUG_MSG(1,
("Shouldn't happen: no room to move handshake fragment %"
MBEDTLS_PRINTF_SIZET " from %p to %p (buf=%p len=%"
MBEDTLS_PRINTF_SIZET ")",
ssl->in_msglen,
(void *) ssl->in_msg, (void *) payload_end,
(void *) ssl->in_buf, in_buf_len));
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
memmove(payload_end, ssl->in_msg, ssl->in_msglen);
ssl->badmac_seen_or_in_hsfraglen += (unsigned) ssl->in_msglen;
payload_end += ssl->in_msglen;
if (ssl->badmac_seen_or_in_hsfraglen < ssl->in_hslen) {
MBEDTLS_SSL_DEBUG_MSG(3, ("Prepare: waiting for more handshake fragments "
"%u/%" MBEDTLS_PRINTF_SIZET,
ssl->badmac_seen_or_in_hsfraglen, ssl->in_hslen));
ssl->in_hdr = payload_end;
ssl->in_msglen = 0;
mbedtls_ssl_update_in_pointers(ssl);
return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
}
if (ssl->badmac_seen_or_in_hsfraglen > 0) {
/*
* At in_first_hdr we have a sequence of records that cover the next handshake
* record, each with its own record header that we need to remove.
* Note that the reassembled record size may not equal the size of the message,
* there may be more messages after it, complete or partial.
*/
unsigned char *in_first_hdr = ssl->in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
unsigned char *p = in_first_hdr, *q = NULL;
size_t merged_rec_len = 0;
do {
mbedtls_record rec;
ret = ssl_parse_record_header(ssl, p, mbedtls_ssl_in_hdr_len(ssl), &rec);
if (ret != 0) {
return ret;
}
merged_rec_len += rec.data_len;
p = rec.buf + rec.buf_len;
if (q != NULL) {
memmove(q, rec.buf + rec.data_offset, rec.data_len);
q += rec.data_len;
} else {
q = p;
}
} while (merged_rec_len < ssl->in_hslen);
ssl->in_hdr = in_first_hdr;
mbedtls_ssl_update_in_pointers(ssl);
ssl->in_msglen = merged_rec_len;
/* Adjust message length. */
MBEDTLS_PUT_UINT16_BE(merged_rec_len, ssl->in_len, 0);
} else {
ssl->in_msglen = ssl->badmac_seen_or_in_hsfraglen;
ssl->badmac_seen_or_in_hsfraglen = 0;
ssl->in_hdr = reassembled_record_start;
mbedtls_ssl_update_in_pointers(ssl);
/* Update the record length in the fully reassembled record */
if (ssl->in_msglen > 0xffff) {
MBEDTLS_SSL_DEBUG_MSG(1,
("Shouldn't happen: in_msglen=%"
MBEDTLS_PRINTF_SIZET " > 0xffff",
ssl->in_msglen));
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
MBEDTLS_PUT_UINT16_BE(ssl->in_msglen, ssl->in_len, 0);
size_t record_len = mbedtls_ssl_in_hdr_len(ssl) + ssl->in_msglen;
(void) record_len;
MBEDTLS_SSL_DEBUG_BUF(4, "reassembled record",
ssl->in_hdr, mbedtls_ssl_in_hdr_len(ssl) + merged_rec_len);
ssl->in_hdr, record_len);
if (ssl->in_hslen < ssl->in_msglen) {
MBEDTLS_SSL_DEBUG_MSG(3,
("More handshake messages in the record: "
"%" MBEDTLS_PRINTF_SIZET " + %" MBEDTLS_PRINTF_SIZET,
ssl->in_hslen,
ssl->in_msglen - ssl->in_hslen));
}
}
} else {
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
return 0;
@ -4704,11 +4751,9 @@ static int ssl_consume_current_message(mbedtls_ssl_context *ssl)
if (ssl->badmac_seen_or_in_hsfraglen != 0) {
/* Not all handshake fragments have arrived, do not consume. */
MBEDTLS_SSL_DEBUG_MSG(3,
("waiting for more fragments (%u of %"
MBEDTLS_PRINTF_SIZET ", %" MBEDTLS_PRINTF_SIZET " left)",
ssl->badmac_seen_or_in_hsfraglen, ssl->in_hslen,
ssl->in_hslen - ssl->badmac_seen_or_in_hsfraglen));
MBEDTLS_SSL_DEBUG_MSG(3, ("Consume: waiting for more handshake fragments "
"%u/%" MBEDTLS_PRINTF_SIZET,
ssl->badmac_seen_or_in_hsfraglen, ssl->in_hslen));
return 0;
}
@ -5103,6 +5148,18 @@ int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* If we're in the middle of a fragmented TLS handshake message,
* we don't accept any other message type. For TLS 1.3, the spec forbids
* interleaving other message types between handshake fragments. For TLS
* 1.2, the spec does not forbid it but we do. */
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM &&
ssl->badmac_seen_or_in_hsfraglen != 0 &&
ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
MBEDTLS_SSL_DEBUG_MSG(1, ("non-handshake message in the middle"
" of a fragmented handshake message"));
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
}
/*
* Handle particular types of records
*/
@ -5141,15 +5198,9 @@ int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
MBEDTLS_SSL_DEBUG_MSG(1,
MBEDTLS_SSL_DEBUG_MSG(2,
("Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"));
return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
#else
MBEDTLS_SSL_DEBUG_MSG(1,
("ChangeCipherSpec invalid in TLS 1.3 without compatibility mode"));
return MBEDTLS_ERR_SSL_INVALID_RECORD;
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
}

View file

@ -2769,6 +2769,51 @@ void mbedtls_ssl_conf_groups(mbedtls_ssl_config *conf,
}
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/* A magic value for `ssl->hostname` indicating that
* mbedtls_ssl_set_hostname() has been called with `NULL`.
* If mbedtls_ssl_set_hostname() has never been called on `ssl`, then
* `ssl->hostname == NULL`. */
static const char *const ssl_hostname_skip_cn_verification = "";
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
/** Whether mbedtls_ssl_set_hostname() has been called.
*
* \param[in] ssl SSL context
*
* \return \c 1 if mbedtls_ssl_set_hostname() has been called on \p ssl
* (including `mbedtls_ssl_set_hostname(ssl, NULL)`),
* otherwise \c 0.
*/
static int mbedtls_ssl_has_set_hostname_been_called(
const mbedtls_ssl_context *ssl)
{
return ssl->hostname != NULL;
}
#endif
/* Micro-optimization: don't export this function if it isn't needed outside
* of this source file. */
#if !defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
static
#endif
const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl)
{
if (ssl->hostname == ssl_hostname_skip_cn_verification) {
return NULL;
}
return ssl->hostname;
}
static void mbedtls_ssl_free_hostname(mbedtls_ssl_context *ssl)
{
if (ssl->hostname != NULL &&
ssl->hostname != ssl_hostname_skip_cn_verification) {
mbedtls_zeroize_and_free(ssl->hostname, strlen(ssl->hostname));
}
ssl->hostname = NULL;
}
int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname)
{
/* Initialize to suppress unnecessary compiler warning */
@ -2786,18 +2831,21 @@ int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname)
/* Now it's clear that we will overwrite the old hostname,
* so we can free it safely */
if (ssl->hostname != NULL) {
mbedtls_zeroize_and_free(ssl->hostname, strlen(ssl->hostname));
}
/* Passing NULL as hostname shall clear the old one */
mbedtls_ssl_free_hostname(ssl);
if (hostname == NULL) {
ssl->hostname = NULL;
/* Passing NULL as hostname clears the old one, but leaves a
* special marker to indicate that mbedtls_ssl_set_hostname()
* has been called. */
/* ssl->hostname should be const, but isn't. We won't actually
* write to the buffer, so it's ok to cast away the const. */
ssl->hostname = (char *) ssl_hostname_skip_cn_verification;
} else {
ssl->hostname = mbedtls_calloc(1, hostname_len + 1);
if (ssl->hostname == NULL) {
/* mbedtls_ssl_set_hostname() has been called, but unsuccessfully.
* Leave ssl->hostname in the same state as if the function had
* not been called, i.e. a null pointer. */
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
@ -5583,9 +5631,7 @@ void mbedtls_ssl_free(mbedtls_ssl_context *ssl)
}
#if defined(MBEDTLS_X509_CRT_PARSE_C)
if (ssl->hostname != NULL) {
mbedtls_zeroize_and_free(ssl->hostname, strlen(ssl->hostname));
}
mbedtls_ssl_free_hostname(ssl);
#endif
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
@ -8323,6 +8369,7 @@ int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl)
ret = ssl->handshake->calc_finished(ssl, ssl->out_msg + 4, ssl->conf->endpoint);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret);
return ret;
}
/*
@ -8436,6 +8483,7 @@ int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl)
ret = ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret);
return ret;
}
if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
@ -9796,6 +9844,27 @@ int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
return ret;
}
static int get_hostname_for_verification(mbedtls_ssl_context *ssl,
const char **hostname)
{
if (!mbedtls_ssl_has_set_hostname_been_called(ssl)) {
MBEDTLS_SSL_DEBUG_MSG(1, ("Certificate verification without having set hostname"));
#if !defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME)
if (mbedtls_ssl_conf_get_endpoint(ssl->conf) == MBEDTLS_SSL_IS_CLIENT &&
ssl->conf->authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
return MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME;
}
#endif
}
*hostname = mbedtls_ssl_get_hostname_pointer(ssl);
if (*hostname == NULL) {
MBEDTLS_SSL_DEBUG_MSG(2, ("Certificate verification without CN verification"));
}
return 0;
}
int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
int authmode,
mbedtls_x509_crt *chain,
@ -9821,7 +9890,13 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
p_vrfy = ssl->conf->p_vrfy;
}
int ret = 0;
const char *hostname = "";
int ret = get_hostname_for_verification(ssl, &hostname);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "get_hostname_for_verification", ret);
return ret;
}
int have_ca_chain_or_callback = 0;
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
if (ssl->conf->f_ca_cb != NULL) {
@ -9834,7 +9909,7 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
ssl->conf->f_ca_cb,
ssl->conf->p_ca_cb,
ssl->conf->cert_profile,
ssl->hostname,
hostname,
&ssl->session_negotiate->verify_result,
f_vrfy, p_vrfy);
} else
@ -9861,7 +9936,7 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
chain,
ca_chain, ca_crl,
ssl->conf->cert_profile,
ssl->hostname,
hostname,
&ssl->session_negotiate->verify_result,
f_vrfy, p_vrfy, rs_ctx);
}

View file

@ -1964,7 +1964,7 @@ static int ssl_write_encrypted_pms(mbedtls_ssl_context *ssl,
ssl->out_msg + offset + len_bytes, olen,
MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes,
ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_rsa_pkcs1_encrypt", ret);
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_encrypt", ret);
return ret;
}

View file

@ -319,6 +319,7 @@ static int ssl_tls13_write_key_share_ext(mbedtls_ssl_context *ssl,
ssl, group_id, p, end, &key_exchange_len);
p += key_exchange_len;
if (ret != 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("client hello: failed generating xxdh key exchange"));
return ret;
}

View file

@ -92,7 +92,7 @@ static void ssl_tls13_select_ciphersuite(
return;
}
MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%lx",
MBEDTLS_SSL_DEBUG_MSG(1, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%lx",
(unsigned) psk_ciphersuite_id,
(unsigned long) psk_hash_alg));
}
@ -1380,6 +1380,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
}
if (ret == 0) {
MBEDTLS_SSL_DEBUG_MSG(2, ("no supported_versions extension"));
return SSL_CLIENT_HELLO_TLS1_2;
}
@ -1401,6 +1402,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
* the TLS version to negotiate.
*/
if (MBEDTLS_SSL_VERSION_TLS1_2 == ret) {
MBEDTLS_SSL_DEBUG_MSG(2, ("supported_versions without 1.3"));
return SSL_CLIENT_HELLO_TLS1_2;
}
}
@ -1985,6 +1987,7 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl)
}
ssl->keep_current_message = 1;
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
MBEDTLS_SSL_DEBUG_MSG(1, ("non-1.3 ClientHello left for later processing"));
return 0;
}

View file

@ -61,7 +61,7 @@ static void threading_mutex_init_pthread(mbedtls_threading_mutex_t *mutex)
* this here in a thread safe manner without a significant performance
* hit, so state transitions are checked in tests only via the state
* variable. Please make sure any new mutex that gets added is exercised in
* tests; see tests/src/threading_helpers.c for more details. */
* tests; see framework/tests/src/threading_helpers.c for more details. */
(void) pthread_mutex_init(&mutex->mutex, NULL);
}

View file

@ -459,6 +459,9 @@ static const char * const features[] = {
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
"SSL_ASYNC_PRIVATE", //no-check-names
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
#if defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME)
"SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME", //no-check-names
#endif /* MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
"SSL_CONTEXT_SERIALIZATION", //no-check-names
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
@ -720,6 +723,9 @@ static const char * const features[] = {
#if defined(MBEDTLS_PSA_ITS_FILE_C)
"PSA_ITS_FILE_C", //no-check-names
#endif /* MBEDTLS_PSA_ITS_FILE_C */
#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
"PSA_STATIC_KEY_SLOTS", //no-check-names
#endif /* MBEDTLS_PSA_STATIC_KEY_SLOTS */
#if defined(MBEDTLS_RIPEMD160_C)
"RIPEMD160_C", //no-check-names
#endif /* MBEDTLS_RIPEMD160_C */