From 75ed58723e93a45455ba2412d1d523931de0d978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 18 Jun 2024 12:52:45 +0200 Subject: [PATCH 001/100] Add optionally unsafe variant of exp_mod for perf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Attempt to partially solve the performance regression in 3.6.0 without adding too much code size. Signed-off-by: Manuel Pégourié-Gonnard --- include/mbedtls/bignum.h | 49 ++++++++++++++++++++++++++++++++++- library/bignum.c | 23 ++++++++++++++--- library/bignum_core.c | 55 +++++++++++++++++++++++++++++++--------- library/bignum_core.h | 38 +++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 17 deletions(-) diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index 71d7b97672..bb96f4fb89 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -44,6 +44,22 @@ goto cleanup; \ } while (0) +/* Constants to identify whether a value is public or secret. + * + * Parameters should be named X_public where X is the name of the + * corresponding input parameter. + * + * Implementation should always check using + * if (X_public == MBEDTLS_MPI_IS_PUBLIC) { + * // unsafe path + * } 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.) */ +#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a +#define MBEDTLS_MPI_IS_SECRET 0 + /* * Maximum size MPIs are allowed to grow to in number of limbs. */ @@ -880,7 +896,38 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b); /** - * \brief Perform a sliding-window exponentiation: X = A^E mod N + * \brief Perform a modular exponentiation: X = A^E mod N + * + * \param X The destination MPI. This must point to an initialized MPI. + * This must not alias E or N. + * \param A The base of the exponentiation. + * This must point to an initialized MPI. + * \param E The exponent MPI. This must point to an initialized MPI. + * \param N The base for the modular reduction. This must point to an + * initialized MPI. + * \param prec_RR A helper MPI depending solely on \p N which can be used to + * speed-up multiple modular exponentiations for the same value + * of \p N. This may be \c NULL. If it is not \c NULL, it must + * point to an initialized MPI. If it hasn't been used after + * the call to mbedtls_mpi_init(), this function will compute + * the helper value and store it in \p prec_RR for reuse on + * subsequent calls to this function. Otherwise, the function + * will assume that \p prec_RR holds the helper value set by a + * previous call to mbedtls_mpi_exp_mod(), and reuse it. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or + * even, or if \c E is negative. + * \return Another negative error code on different kinds of failures. + * + */ +int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR, int E_public); + +/** + * \brief Perform a modular exponentiation: X = A^E mod N * * \param X The destination MPI. This must point to an initialized MPI. * This must not alias E or N. diff --git a/library/bignum.c b/library/bignum.c index c45fd5bf24..4db2b10544 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -1610,9 +1610,9 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s return 0; } -int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *prec_RR) +int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR, int E_public) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -1695,7 +1695,15 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, { mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p); mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T); - mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T); + mbedtls_mpi_core_exp_mod_optionally_safe(X->p, + X->p, + N->p, + N->n, + E->p, + E->n, + RR.p, + T, + E_public); mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T); } @@ -1720,6 +1728,13 @@ cleanup: return ret; } +int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR) +{ + return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, N, prec_RR, MBEDTLS_MPI_IS_SECRET); +} + /* * Greatest common divisor: G = gcd(A, B) (HAC 14.54) */ diff --git a/library/bignum_core.c b/library/bignum_core.c index 1a3e0b9b6f..518b1bd3f3 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -758,14 +758,15 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A, * (The difference is that the body in our loop processes a single bit instead * of a full window.) */ -void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - const mbedtls_mpi_uint *E, - size_t E_limbs, - const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T) +void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, + size_t AN_limbs, + const mbedtls_mpi_uint *E, + size_t E_limbs, + const mbedtls_mpi_uint *RR, + mbedtls_mpi_uint *T, + int E_public) { const size_t wsize = exp_mod_get_window_size(E_limbs * biL); const size_t welem = ((size_t) 1) << wsize; @@ -803,6 +804,14 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, * (limb_index=0, E_bit_index=0). */ size_t E_limb_index = E_limbs; size_t E_bit_index = 0; + if (E_public == MBEDTLS_MPI_IS_PUBLIC) { + size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs); + if (E_bits != 0) { + E_limb_index = E_bits / biL; + E_bit_index = E_bits % biL; + } + } + /* At any given time, window contains window_bits bits from E. * window_bits can go up to wsize. */ size_t window_bits = 0; @@ -828,10 +837,14 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, * when we've finished processing the exponent. */ if (window_bits == wsize || (E_bit_index == 0 && E_limb_index == 0)) { - /* Select Wtable[window] without leaking window through - * memory access patterns. */ - mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable, - AN_limbs, welem, window); + if (E_public == MBEDTLS_MPI_IS_PUBLIC) { + memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL); + } else { + /* Select Wtable[window] without leaking window through + * memory access patterns. */ + mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable, + AN_limbs, welem, window); + } /* Multiply X by the selected element. */ mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm, temp); @@ -841,6 +854,24 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, } while (!(E_bit_index == 0 && E_limb_index == 0)); } +void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, size_t AN_limbs, + const mbedtls_mpi_uint *E, size_t E_limbs, + const mbedtls_mpi_uint *RR, + mbedtls_mpi_uint *T) +{ + mbedtls_mpi_core_exp_mod_optionally_safe(X, + A, + N, + AN_limbs, + E, + E_limbs, + RR, + T, + MBEDTLS_MPI_IS_SECRET); +} + mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X, const mbedtls_mpi_uint *A, mbedtls_mpi_uint c, /* doubles as carry */ diff --git a/library/bignum_core.h b/library/bignum_core.h index 92c8d47db5..c63cdee465 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -604,6 +604,44 @@ int mbedtls_mpi_core_random(mbedtls_mpi_uint *X, */ size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs); +/** + * \brief Perform a modular exponentiation with public or secret exponent: + * X = A^E mod N, where \p A is already in Montgomery form. + * + * \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs == + * \p AN_limbs. + * + * \param[out] X The destination MPI, as a little endian array of length + * \p AN_limbs. + * \param[in] A The base MPI, as a little endian array of length \p AN_limbs. + * Must be in Montgomery form. + * \param[in] N The modulus, as a little endian array of length \p AN_limbs. + * \param AN_limbs The number of limbs in \p X, \p A, \p N, \p RR. + * \param[in] E The exponent, as a little endian array of length \p E_limbs. + * \param E_limbs The number of limbs in \p E. + * \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little + * endian array of length \p AN_limbs. + * \param[in,out] T Temporary storage of at least the number of limbs returned + * by `mbedtls_mpi_core_exp_mod_working_limbs()`. + * Its initial content is unused and its final content is + * indeterminate. + * It must not alias or otherwise overlap any of the other + * parameters. + * It is up to the caller to zeroize \p T when it is no + * longer needed, and before freeing it if it was dynamically + * allocated. + * \param[in] E_public Set to MBEDTLS_MPI_IS_PUBLIC to gain some performance + * when the value of E is public. + * Set to MBEDTLS_MPI_IS_SECRET when the value of E is secret. + */ +void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, size_t AN_limbs, + const mbedtls_mpi_uint *E, size_t E_limbs, + const mbedtls_mpi_uint *RR, + mbedtls_mpi_uint *T, + int E_public); + /** * \brief Perform a modular exponentiation with secret exponent: * X = A^E mod N, where \p A is already in Montgomery form. From cd693c36fd01e2342b3017271451a8f042f4b42a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 12 Jun 2024 19:13:19 +0200 Subject: [PATCH 002/100] MBEDTLS_STATIC_ASSERT: make it work outside of a function At the top level, the macro would have had to be used without a following semicolon (except with permissive compilers that accept spurious semicolons outside of a function), which is confusing to humans and indenters. Fix that. Signed-off-by: Gilles Peskine --- library/common.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/library/common.h b/library/common.h index 3936ffdfe1..7bb2674293 100644 --- a/library/common.h +++ b/library/common.h @@ -352,17 +352,19 @@ static inline void mbedtls_xor_no_simd(unsigned char *r, #endif /* Always provide a static assert macro, so it can be used unconditionally. - * It will expand to nothing on some systems. - * Can be used outside functions (but don't add a trailing ';' in that case: - * the semicolon is included here to avoid triggering -Wextra-semi when - * MBEDTLS_STATIC_ASSERT() expands to nothing). - * Can't use the C11-style `defined(static_assert)` on FreeBSD, since it + * It does nothing on systems where we don't know how to define a static assert. + */ +/* Can't use the C11-style `defined(static_assert)` on FreeBSD, since it * defines static_assert even with -std=c99, but then complains about it. */ #if defined(static_assert) && !defined(__FreeBSD__) -#define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg); +#define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg) #else -#define MBEDTLS_STATIC_ASSERT(expr, msg) +/* Make sure `MBEDTLS_STATIC_ASSERT(expr, msg);` is valid both inside and + * outside a function. We choose a struct declaration, which can be repeated + * any number of times and does not need a matching definition. */ +#define MBEDTLS_STATIC_ASSERT(expr, msg) \ + struct ISO_C_does_not_allow_extra_semicolon_outside_of_a_function #endif #if defined(__has_builtin) From 4804847b1528c00fff132fcde66f35d94e4f55b5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 20 Jun 2024 21:47:31 +0200 Subject: [PATCH 003/100] Make it possible to enable CTR_DRBG/PSA without a PSA AES driver Make it possible, but not officially supported, to switch the CTR_DRBG module to PSA mode even if MBEDTLS_AES_C is defined. This is not really useful in practice, but is convenient to test the PSA mode without setting up drivers. Signed-off-by: Gilles Peskine --- include/mbedtls/ctr_drbg.h | 25 ++++++++++++++++----- library/ctr_drbg.c | 30 ++++++++++++------------- tests/include/test/psa_crypto_helpers.h | 8 ++++--- tests/src/psa_crypto_helpers.c | 9 ++++++-- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index c00756df1b..c7db4702a9 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -32,9 +32,24 @@ #include "mbedtls/build_info.h" -/* In case AES_C is defined then it is the primary option for backward - * compatibility purposes. If that's not available, PSA is used instead */ -#if defined(MBEDTLS_AES_C) +/* The CTR_DRBG implementation can either directly call the low-level AES + * module (gated by MBEDTLS_AES_C) or call the PSA API to perform AES + * operations. Calling the AES module directly is the default, both for + * maximum backward compatibility and because it's a bit more efficient + * (less glue code). + * + * When MBEDTLS_AES_C is disabled, the CTR_DRBG module calls PSA crypto and + * thus benefits from the PSA AES accelerator driver. + * It is technically possible to enable MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO + * to use PSA even when MBEDTLS_AES_C is disabled, but there is very little + * reason to do so other than testing purposes and this is not officially + * supported. + */ +#if !defined(MBEDTLS_AES_C) +#define MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO +#endif + +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) #include "mbedtls/aes.h" #else #include "psa/crypto.h" @@ -157,7 +172,7 @@ extern "C" { #define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN (MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1) / 2 #endif -#if !defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) typedef struct mbedtls_ctr_drbg_psa_context { mbedtls_svc_key_id_t key_id; psa_cipher_operation_t operation; @@ -189,7 +204,7 @@ typedef struct mbedtls_ctr_drbg_context { * This is the maximum number of requests * that can be made between reseedings. */ -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) mbedtls_aes_context MBEDTLS_PRIVATE(aes_ctx); /*!< The AES context. */ #else mbedtls_ctr_drbg_psa_context MBEDTLS_PRIVATE(psa_ctx); /*!< The PSA context. */ diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c index 66d9d28c58..aea62bbfd1 100644 --- a/library/ctr_drbg.c +++ b/library/ctr_drbg.c @@ -26,13 +26,13 @@ #endif /* Using error translation functions from PSA to MbedTLS */ -#if !defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) #include "psa_util_internal.h" #endif #include "mbedtls/platform.h" -#if !defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) static psa_status_t ctr_drbg_setup_psa_context(mbedtls_ctr_drbg_psa_context *psa_ctx, unsigned char *key, size_t key_len) { @@ -73,7 +73,7 @@ static void ctr_drbg_destroy_psa_contex(mbedtls_ctr_drbg_psa_context *psa_ctx) void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx) { memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context)); -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) mbedtls_aes_init(&ctx->aes_ctx); #else ctx->psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT; @@ -102,7 +102,7 @@ void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx) mbedtls_mutex_free(&ctx->mutex); } #endif -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) mbedtls_aes_free(&ctx->aes_ctx); #else ctr_drbg_destroy_psa_contex(&ctx->psa_ctx); @@ -168,7 +168,7 @@ static int block_cipher_df(unsigned char *output, unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; unsigned char *p, *iv; int ret = 0; -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) mbedtls_aes_context aes_ctx; #else psa_status_t status; @@ -209,7 +209,7 @@ static int block_cipher_df(unsigned char *output, key[i] = i; } -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) mbedtls_aes_init(&aes_ctx); if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key, @@ -238,7 +238,7 @@ static int block_cipher_df(unsigned char *output, use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ? MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain)) != 0) { goto exit; @@ -264,7 +264,7 @@ static int block_cipher_df(unsigned char *output, /* * Do final encryption with reduced data */ -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { goto exit; @@ -282,7 +282,7 @@ static int block_cipher_df(unsigned char *output, p = output; for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) { -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv)) != 0) { goto exit; @@ -299,7 +299,7 @@ static int block_cipher_df(unsigned char *output, p += MBEDTLS_CTR_DRBG_BLOCKSIZE; } exit: -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) mbedtls_aes_free(&aes_ctx); #else ctr_drbg_destroy_psa_contex(&psa_ctx); @@ -336,7 +336,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, unsigned char *p = tmp; int j; int ret = 0; -#if !defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) psa_status_t status; size_t tmp_len; #endif @@ -352,7 +352,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, /* * Crypt counter block */ -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p)) != 0) { goto exit; @@ -374,7 +374,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, /* * Update key and counter */ -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { goto exit; @@ -564,7 +564,7 @@ int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx, good_nonce_len(ctx->entropy_len)); /* Initialize with an empty key. */ -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { return ret; @@ -655,7 +655,7 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, /* * Crypt counter block */ -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, locals.tmp)) != 0) { goto exit; diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index 7306d8eb10..39611a2634 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -16,6 +16,8 @@ #include #endif +#include + #if defined(MBEDTLS_PSA_CRYPTO_C) /** Initialize the PSA Crypto subsystem. */ #define PSA_INIT() PSA_ASSERT(psa_crypto_init()) @@ -430,12 +432,12 @@ uint64_t mbedtls_test_parse_binary_string(data_t *bin_string); * This is like #PSA_DONE except it does nothing under the same conditions as * #AES_PSA_INIT. */ -#if defined(MBEDTLS_AES_C) +#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) #define AES_PSA_INIT() ((void) 0) #define AES_PSA_DONE() ((void) 0) -#else /* MBEDTLS_AES_C */ +#else /* MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO */ #define AES_PSA_INIT() PSA_INIT() #define AES_PSA_DONE() PSA_DONE() -#endif /* MBEDTLS_AES_C */ +#endif /* MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO */ #endif /* PSA_CRYPTO_HELPERS_H */ diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c index e1ea2b5c81..1581eecb3b 100644 --- a/tests/src/psa_crypto_helpers.c +++ b/tests/src/psa_crypto_helpers.c @@ -13,6 +13,10 @@ #include #include +#if defined(MBEDTLS_CTR_DRBG_C) +#include +#endif + #if defined(MBEDTLS_PSA_CRYPTO_C) #include @@ -70,8 +74,9 @@ const char *mbedtls_test_helper_is_psa_leaking(void) mbedtls_psa_get_stats(&stats); -#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) && \ - !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) +#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \ + defined(MBEDTLS_CTR_DRBG_C) && \ + defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) /* When AES_C is not defined and PSA does not have an external RNG, * then CTR_DRBG uses PSA to perform AES-ECB. In this scenario 1 key * slot is used internally from PSA to hold the AES key and it should From 86c603702e74db1490579e6f0a20a8c5a2d8d6dd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 20 Jun 2024 22:08:44 +0200 Subject: [PATCH 004/100] Reorder blocks to avoid double negations Convert `#if !... A #else B #endif` to `#if ... B #else A`. No semantic change. Signed-off-by: Gilles Peskine --- include/mbedtls/ctr_drbg.h | 12 +-- library/ctr_drbg.c | 122 ++++++++++++------------ tests/include/test/psa_crypto_helpers.h | 8 +- 3 files changed, 71 insertions(+), 71 deletions(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index c7db4702a9..216169c770 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -49,10 +49,10 @@ #define MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO #endif -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) -#include "mbedtls/aes.h" -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) #include "psa/crypto.h" +#else +#include "mbedtls/aes.h" #endif #include "entropy.h" @@ -204,10 +204,10 @@ typedef struct mbedtls_ctr_drbg_context { * This is the maximum number of requests * that can be made between reseedings. */ -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - mbedtls_aes_context MBEDTLS_PRIVATE(aes_ctx); /*!< The AES context. */ -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) mbedtls_ctr_drbg_psa_context MBEDTLS_PRIVATE(psa_ctx); /*!< The PSA context. */ +#else + mbedtls_aes_context MBEDTLS_PRIVATE(aes_ctx); /*!< The AES context. */ #endif /* diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c index aea62bbfd1..b82044eb7d 100644 --- a/library/ctr_drbg.c +++ b/library/ctr_drbg.c @@ -73,11 +73,11 @@ static void ctr_drbg_destroy_psa_contex(mbedtls_ctr_drbg_psa_context *psa_ctx) void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx) { memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context)); -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - mbedtls_aes_init(&ctx->aes_ctx); -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) ctx->psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT; ctx->psa_ctx.operation = psa_cipher_operation_init(); +#else + mbedtls_aes_init(&ctx->aes_ctx); #endif /* Indicate that the entropy nonce length is not set explicitly. * See mbedtls_ctr_drbg_set_nonce_len(). */ @@ -102,10 +102,10 @@ void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx) mbedtls_mutex_free(&ctx->mutex); } #endif -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - mbedtls_aes_free(&ctx->aes_ctx); -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) ctr_drbg_destroy_psa_contex(&ctx->psa_ctx); +#else + mbedtls_aes_free(&ctx->aes_ctx); #endif mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context)); ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; @@ -168,15 +168,15 @@ static int block_cipher_df(unsigned char *output, unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; unsigned char *p, *iv; int ret = 0; -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - mbedtls_aes_context aes_ctx; -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) psa_status_t status; size_t tmp_len; mbedtls_ctr_drbg_psa_context psa_ctx; psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT; psa_ctx.operation = psa_cipher_operation_init(); +#else + mbedtls_aes_context aes_ctx; #endif int i, j; @@ -209,19 +209,19 @@ static int block_cipher_df(unsigned char *output, key[i] = i; } -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) + status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key)); + if (status != PSA_SUCCESS) { + ret = psa_generic_status_to_mbedtls(status); + goto exit; + } +#else mbedtls_aes_init(&aes_ctx); if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { goto exit; } -#else - status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key)); - if (status != PSA_SUCCESS) { - ret = psa_generic_status_to_mbedtls(status); - goto exit; - } #endif /* @@ -238,18 +238,18 @@ static int block_cipher_df(unsigned char *output, use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ? MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, - chain, chain)) != 0) { - goto exit; - } -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) status = psa_cipher_update(&psa_ctx.operation, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len); if (status != PSA_SUCCESS) { ret = psa_generic_status_to_mbedtls(status); goto exit; } +#else + if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, + chain, chain)) != 0) { + goto exit; + } #endif } @@ -264,12 +264,7 @@ static int block_cipher_df(unsigned char *output, /* * Do final encryption with reduced data */ -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp, - MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { - goto exit; - } -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) ctr_drbg_destroy_psa_contex(&psa_ctx); status = ctr_drbg_setup_psa_context(&psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE); @@ -277,32 +272,37 @@ static int block_cipher_df(unsigned char *output, ret = psa_generic_status_to_mbedtls(status); goto exit; } +#else + if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp, + MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { + goto exit; + } #endif iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; p = output; for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) { -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, - iv, iv)) != 0) { - goto exit; - } -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) status = psa_cipher_update(&psa_ctx.operation, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len); if (status != PSA_SUCCESS) { ret = psa_generic_status_to_mbedtls(status); goto exit; } +#else + if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, + iv, iv)) != 0) { + goto exit; + } #endif memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE); p += MBEDTLS_CTR_DRBG_BLOCKSIZE; } exit: -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - mbedtls_aes_free(&aes_ctx); -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) ctr_drbg_destroy_psa_contex(&psa_ctx); +#else + mbedtls_aes_free(&aes_ctx); #endif /* * tidy up the stack @@ -352,18 +352,18 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, /* * Crypt counter block */ -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, - ctx->counter, p)) != 0) { - goto exit; - } -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter), p, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len); if (status != PSA_SUCCESS) { ret = psa_generic_status_to_mbedtls(status); goto exit; } +#else + if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, + ctx->counter, p)) != 0) { + goto exit; + } #endif p += MBEDTLS_CTR_DRBG_BLOCKSIZE; @@ -374,12 +374,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, /* * Update key and counter */ -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp, - MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { - goto exit; - } -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) ctr_drbg_destroy_psa_contex(&ctx->psa_ctx); status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE); @@ -387,6 +382,11 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, ret = psa_generic_status_to_mbedtls(status); goto exit; } +#else + if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp, + MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { + goto exit; + } #endif memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE); @@ -564,12 +564,7 @@ int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx, good_nonce_len(ctx->entropy_len)); /* Initialize with an empty key. */ -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key, - MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { - return ret; - } -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) psa_status_t status; status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, key, MBEDTLS_CTR_DRBG_KEYSIZE); @@ -577,6 +572,11 @@ int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx, ret = psa_generic_status_to_mbedtls(status); return status; } +#else + if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key, + MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { + return ret; + } #endif /* Do the initial seeding. */ @@ -655,12 +655,7 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, /* * Crypt counter block */ -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, - ctx->counter, locals.tmp)) != 0) { - goto exit; - } -#else +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) psa_status_t status; size_t tmp_len; @@ -670,6 +665,11 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, ret = psa_generic_status_to_mbedtls(status); goto exit; } +#else + if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, + ctx->counter, locals.tmp)) != 0) { + goto exit; + } #endif use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE) diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index 39611a2634..fae715ca9a 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -432,12 +432,12 @@ uint64_t mbedtls_test_parse_binary_string(data_t *bin_string); * This is like #PSA_DONE except it does nothing under the same conditions as * #AES_PSA_INIT. */ -#if !defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) -#define AES_PSA_INIT() ((void) 0) -#define AES_PSA_DONE() ((void) 0) -#else /* MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO */ +#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) #define AES_PSA_INIT() PSA_INIT() #define AES_PSA_DONE() PSA_DONE() +#else /* MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO */ +#define AES_PSA_INIT() ((void) 0) +#define AES_PSA_DONE() ((void) 0) #endif /* MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO */ #endif /* PSA_CRYPTO_HELPERS_H */ From d72ad738bdb3269d31eec06a0a458442decadf2d Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 13 Jun 2024 16:06:45 +0200 Subject: [PATCH 005/100] Prevent mbedtls_psa_register_se_key with volatile keys mbedtls_psa_register_se_key() is not usable with volatile keys, since there is no way to return the implementation-chosen key identifier which would be needed to use the key. Document this limitation. Reject an attempt to create such an unusable key. Fixes #9253. Signed-off-by: Gilles Peskine --- ChangeLog.d/mbedtls_psa_register_se_key.txt | 3 +++ include/psa/crypto.h | 3 +++ include/psa/crypto_extra.h | 8 ++++++++ library/psa_crypto.c | 8 ++++++++ tests/suites/test_suite_psa_crypto_se_driver_hal.data | 11 ++++++++++- 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 ChangeLog.d/mbedtls_psa_register_se_key.txt diff --git a/ChangeLog.d/mbedtls_psa_register_se_key.txt b/ChangeLog.d/mbedtls_psa_register_se_key.txt new file mode 100644 index 0000000000..2fc2751ac0 --- /dev/null +++ b/ChangeLog.d/mbedtls_psa_register_se_key.txt @@ -0,0 +1,3 @@ +Bugfix + * Document and enforce the limitation of mbedtls_psa_register_se_key() + to persistent keys. Resolves #9253. diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 3525da221f..6d12e43d4f 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -129,6 +129,9 @@ static psa_key_attributes_t psa_key_attributes_init(void); * * \param[out] attributes The attribute structure to write to. * \param key The persistent identifier for the key. + * This can be any value in the range from + * #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX + * inclusive. */ static void psa_set_key_id(psa_key_attributes_t *attributes, mbedtls_svc_key_id_t key); diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 6ed1f6c43a..5f413d6aa3 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -154,6 +154,14 @@ static inline void psa_clear_key_slot_number( * specified in \p attributes. * * \param[in] attributes The attributes of the existing key. + * - The lifetime must be a persistent lifetime + * in a secure element. Volatile lifetimes are + * not currently supported. + * - The key identifier must be in the valid + * range for persistent keys. + * - The key type and size must be specified and + * must be consistent with the key material + * in the secure element. * * \retval #PSA_SUCCESS * The key was successfully registered. diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 8100afc471..28bcd21be2 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2149,6 +2149,14 @@ psa_status_t mbedtls_psa_register_se_key( return PSA_ERROR_NOT_SUPPORTED; } + /* Not usable with volatile keys, even with an appropriate location, + * due to the API design. + * https://github.com/Mbed-TLS/mbedtls/issues/9253 + */ + if (PSA_KEY_LIFETIME_IS_VOLATILE(psa_get_key_lifetime(attributes))) { + return PSA_ERROR_INVALID_ARGUMENT; + } + status = psa_start_key_creation(PSA_KEY_CREATION_REGISTER, attributes, &slot, &driver); if (status != PSA_SUCCESS) { diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.data b/tests/suites/test_suite_psa_crypto_se_driver_hal.data index cc89c0fc20..d028b21821 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal.data +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.data @@ -148,7 +148,16 @@ generate_key_smoke:PSA_KEY_TYPE_HMAC:256:PSA_ALG_HMAC( PSA_ALG_SHA_256 ) Key registration: smoke test register_key_smoke_test:TEST_SE_PERSISTENT_LIFETIME:7:1:1:PSA_SUCCESS -Key registration: invalid lifetime (volatile internal storage) +Key registration: invalid lifetime (volatile, in SE, id=0) +register_key_smoke_test:TEST_SE_VOLATILE_LIFETIME:7:0:0:PSA_ERROR_INVALID_ARGUMENT + +Key registration: invalid lifetime (volatile, in SE, id=1) +register_key_smoke_test:TEST_SE_VOLATILE_LIFETIME:7:1:1:PSA_ERROR_INVALID_ARGUMENT + +Key registration: invalid lifetime (volatile, internal, id=0) +register_key_smoke_test:PSA_KEY_LIFETIME_VOLATILE:7:0:0:PSA_ERROR_INVALID_ARGUMENT + +Key registration: invalid lifetime (volatile, internal, id=1) register_key_smoke_test:PSA_KEY_LIFETIME_VOLATILE:7:1:1:PSA_ERROR_INVALID_ARGUMENT Key registration: invalid lifetime (internal storage) From 543909d894cc7eaa24c1fb4327876ee5b418c3bb Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 20 Jun 2024 22:10:08 +0200 Subject: [PATCH 006/100] Add a test for the built-in key range Restricting the built-in key range would be an API break since applications can hard-code a built-in key value and expect that it won't clash with anything else. Make it harder to accidentally break the API. Signed-off-by: Gilles Peskine --- include/psa/crypto_extra.h | 2 +- .../test_suite_psa_crypto_driver_wrappers.data | 3 +++ ...test_suite_psa_crypto_driver_wrappers.function | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 5f413d6aa3..0cf42c6055 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -487,7 +487,7 @@ psa_status_t mbedtls_psa_external_get_random( * #PSA_KEY_ID_VENDOR_MIN and #PSA_KEY_ID_VENDOR_MAX and must not intersect * with any other set of implementation-chosen key identifiers. * - * This value is part of the library's ABI since changing it would invalidate + * This value is part of the library's API since changing it would invalidate * the values of built-in key identifiers in applications. */ #define MBEDTLS_PSA_KEY_ID_BUILTIN_MIN ((psa_key_id_t) 0x7fff0000) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data index 54e0892004..fb2da8c3c2 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data @@ -1,3 +1,6 @@ +Built-in key range +builtin_key_id_stability: + sign_hash transparent driver: in driver ECDSA SECP256R1 SHA-256 depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 sign_hash:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):PSA_SUCCESS:"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":0:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index e7925dd694..84611faddd 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -489,6 +489,21 @@ exit: * END_DEPENDENCIES */ +/* BEGIN_CASE */ +void builtin_key_id_stability() +{ + /* If the range of built-in keys is reduced, it's an API break, since + * it breaks user code that hard-codes the key id of built-in keys. + * It's ok to expand this range, but not to shrink it. That is, you + * may make the MIN smaller or the MAX larger at any time, but + * making the MIN larger or the MAX smaller can only be done in + * a new major version of the library. + */ + TEST_EQUAL(MBEDTLS_PSA_KEY_ID_BUILTIN_MIN, 0x7fff0000); + TEST_EQUAL(MBEDTLS_PSA_KEY_ID_BUILTIN_MAX, 0x7fffefff); +} +/* END_CASE */ + /* BEGIN_CASE */ void sign_hash(int key_type_arg, int alg_arg, From b6bf370159aaa01b9906aa7095fdcf48db0722ff Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 20 Jun 2024 22:15:42 +0200 Subject: [PATCH 007/100] Assert that key ID ranges don't overlap Ensure that a key ID can't be in range for more than one of volatile keys, persistent (i.e. user-chosen) keys or built-in keys. Signed-off-by: Gilles Peskine --- library/psa_crypto_slot_management.c | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 9986a44969..305ad6ec46 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -27,6 +27,37 @@ #include "mbedtls/threading.h" #endif + + +/* Make sure we have distinct ranges of key identifiers for distinct + * purposes. */ +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, + "Empty builtin key ID range"); +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 || + PSA_KEY_ID_VENDOR_MAX < PSA_KEY_ID_USER_MIN, + "Overlap between user key IDs and vendor key IDs"); + +MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VENDOR_MIN <= MBEDTLS_PSA_KEY_ID_BUILTIN_MIN && + MBEDTLS_PSA_KEY_ID_BUILTIN_MAX <= PSA_KEY_ID_VENDOR_MAX, + "Builtin key identifiers are not in the vendor range"); + +MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VENDOR_MIN <= PSA_KEY_ID_VOLATILE_MIN && + PSA_KEY_ID_VOLATILE_MAX <= PSA_KEY_ID_VENDOR_MAX, + "Volatile key identifiers are not in the vendor range"); + +MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN || + MBEDTLS_PSA_KEY_ID_BUILTIN_MAX < PSA_KEY_ID_VOLATILE_MIN, + "Overlap between builtin key IDs and volatile key IDs"); + + + typedef struct { psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT]; uint8_t key_slots_initialized; From 708ec09e30e1a1ccc28faf26b6d2a39249c02323 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 16 Jul 2024 20:02:37 +0200 Subject: [PATCH 008/100] Assert that the key ID range for volatile keys is large enough Signed-off-by: Gilles Peskine --- library/psa_crypto_slot_management.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 305ad6ec46..c2949a61e7 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -65,6 +65,10 @@ typedef struct { static psa_global_data_t global_data; +MBEDTLS_STATIC_ASSERT(ARRAY_LENGTH(global_data.key_slots) <= + PSA_KEY_ID_VOLATILE_MAX - PSA_KEY_ID_VOLATILE_MIN + 1, + "The volatile key range is larger than the key slot array"); + static uint8_t psa_get_key_slots_initialized(void) { uint8_t initialized; From 7dea096086854e1916e18d173cda3757f803b6a3 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 16 Jul 2024 21:24:05 +0200 Subject: [PATCH 009/100] Fix overlap between volatile keys and built-in keys Fix interference between PSA volatile keys and built-in keys when MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS is enabled and MBEDTLS_PSA_KEY_SLOT_COUNT is more than 4096. This overlap used to make it possible that a volatile key would receive the identifier of a built-in key, and is now caught by a static assertion. Signed-off-by: Gilles Peskine --- ChangeLog.d/dynamic-keystore.txt | 4 ++++ library/psa_crypto_slot_management.h | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 ChangeLog.d/dynamic-keystore.txt diff --git a/ChangeLog.d/dynamic-keystore.txt b/ChangeLog.d/dynamic-keystore.txt new file mode 100644 index 0000000000..d576dcd86f --- /dev/null +++ b/ChangeLog.d/dynamic-keystore.txt @@ -0,0 +1,4 @@ +Bugfix + * Fix interference between PSA volatile keys and built-in keys + when MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS is enabled and + MBEDTLS_PSA_KEY_SLOT_COUNT is more than 4096. diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index a84be7d837..88b7c837cc 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -15,7 +15,7 @@ /** Range of volatile key identifiers. * - * The last #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation + * The first #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation * range of key identifiers are reserved for volatile key identifiers. * A volatile key identifier is equal to #PSA_KEY_ID_VOLATILE_MIN plus the * index of the key slot containing the volatile key definition. @@ -23,12 +23,12 @@ /** The minimum value for a volatile key identifier. */ -#define PSA_KEY_ID_VOLATILE_MIN (PSA_KEY_ID_VENDOR_MAX - \ - MBEDTLS_PSA_KEY_SLOT_COUNT + 1) +#define PSA_KEY_ID_VOLATILE_MIN PSA_KEY_ID_VENDOR_MIN /** The maximum value for a volatile key identifier. */ -#define PSA_KEY_ID_VOLATILE_MAX PSA_KEY_ID_VENDOR_MAX +#define PSA_KEY_ID_VOLATILE_MAX \ + (PSA_KEY_ID_VOLATILE_MIN + MBEDTLS_PSA_KEY_SLOT_COUNT - 1) /** Test whether a key identifier is a volatile key identifier. * From 0d0f4adb41430a0d9b29d29c3d065d8493b1bbcc Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 17 Jul 2024 12:34:19 +0200 Subject: [PATCH 010/100] Update invalid key id in a test case PSA_KEY_ID_VOLATILE_MIN-1 is now in the persistent key ID range, so it's no longer an invalid key ID for registration. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_psa_crypto_se_driver_hal.data | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.data b/tests/suites/test_suite_psa_crypto_se_driver_hal.data index d028b21821..ae4ee0c25c 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal.data +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.data @@ -178,8 +178,8 @@ register_key_smoke_test:TEST_SE_PERSISTENT_LIFETIME:7:PSA_KEY_ID_VENDOR_MAX+1:-1 Key registration: key id min vendor register_key_smoke_test:TEST_SE_PERSISTENT_LIFETIME:7:PSA_KEY_ID_VENDOR_MIN:1:PSA_ERROR_INVALID_ARGUMENT -Key registration: key id max vendor except volatile -register_key_smoke_test:TEST_SE_PERSISTENT_LIFETIME:7:PSA_KEY_ID_VOLATILE_MIN-1:1:PSA_ERROR_INVALID_ARGUMENT +Key registration: key id max vendor +register_key_smoke_test:TEST_SE_PERSISTENT_LIFETIME:7:PSA_KEY_ID_VENDOR_MAX:1:PSA_ERROR_INVALID_ARGUMENT Key registration: key id min volatile register_key_smoke_test:TEST_SE_PERSISTENT_LIFETIME:7:PSA_KEY_ID_VOLATILE_MIN:1:PSA_ERROR_INVALID_ARGUMENT From e7624cabfbae8fafddb3cdc42f98eef51d9d78fc Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 16 Jul 2024 21:29:13 +0200 Subject: [PATCH 011/100] Improve the documentation of MBEDTLS_PSA_KEY_SLOT_COUNT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The description was misleading: setting the option doesn't “restrict” the number of slots, that restriction exists anyway. Setting the option merely determines the value of the limit. Signed-off-by: Gilles Peskine --- include/mbedtls/mbedtls_config.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 35921412c6..ce9a52478d 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -4025,13 +4025,18 @@ //#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 /** \def MBEDTLS_PSA_KEY_SLOT_COUNT - * Restrict the PSA library to supporting a maximum amount of simultaneously - * loaded keys. A loaded key is a key stored by the PSA Crypto core as a - * volatile key, or a persistent key which is loaded temporarily by the - * library as part of a crypto operation in flight. * - * If this option is unset, the library will fall back to a default value of - * 32 keys. + * The maximum amount of PSA keys simultaneously in memory. This counts all + * volatile keys, plus loaded persistent keys. + * + * Currently, persistent keys do not need to be loaded all the time while + * a multipart operation is in progress, only while the operation is being + * set up. This may change in future versions of the library. + * + * Currently, the library traverses of the whole table on each access to a + * persistent key. Therefore large values may cause poor performance. + * + * This option has no effect when #MBEDTLS_PSA_CRYPTO_C is disabled. */ //#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 From 8a13d8297b63120bf70f3d50828cb6eba2bb9cc5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 21 Jun 2024 00:09:07 +0200 Subject: [PATCH 012/100] Improve full-key-store tests Split the "many transient keys" test function in two: one that expects to successfully create many keys, and one that expects to fill the key store. This will make things easier when we add a dynamic key store where filling the key store is not practical unless artificially limited. Signed-off-by: Gilles Peskine --- ...test_suite_psa_crypto_slot_management.data | 19 +++- ..._suite_psa_crypto_slot_management.function | 102 +++++++++++++++++- 2 files changed, 115 insertions(+), 6 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_slot_management.data b/tests/suites/test_suite_psa_crypto_slot_management.data index 7d364acab6..560350c6ee 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.data +++ b/tests/suites/test_suite_psa_crypto_slot_management.data @@ -214,8 +214,23 @@ invalid_handle:INVALID_HANDLE_CLOSED:PSA_ERROR_INVALID_HANDLE invalid handle: huge invalid_handle:INVALID_HANDLE_HUGE:PSA_ERROR_INVALID_HANDLE -Open many transient keys -many_transient_keys:42 +Key slot count: less than maximum +many_transient_keys:MBEDTLS_PSA_KEY_SLOT_COUNT - 1 + +Key slot count: maximum +many_transient_keys:MBEDTLS_PSA_KEY_SLOT_COUNT + +Key slot count: try to overfill, destroy first +fill_key_store:0 + +Key slot count: try to overfill, destroy second +fill_key_store:1 + +Key slot count: try to overfill, destroy next-to-last +fill_key_store:-2 + +Key slot count: try to overfill, destroy last +fill_key_store:-1 # Eviction from a key slot to be able to import a new persistent key. Key slot eviction to import a new persistent key diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function index 94f26f6b42..013945e759 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.function +++ b/tests/suites/test_suite_psa_crypto_slot_management.function @@ -98,6 +98,11 @@ exit: return 0; } +/* Currently, there is always a maximum number of volatile keys that can + * realistically be reached in tests. When we add configurations where this + * is not true, undefine the macro in such configurations. */ +#define MAX_VOLATILE_KEYS MBEDTLS_PSA_KEY_SLOT_COUNT + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -813,21 +818,19 @@ void many_transient_keys(int max_keys_arg) psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA); for (i = 0; i < max_keys; i++) { + mbedtls_test_set_step(i); status = psa_import_key(&attributes, (uint8_t *) &i, sizeof(i), &keys[i]); - if (status == PSA_ERROR_INSUFFICIENT_MEMORY) { - break; - } PSA_ASSERT(status); TEST_ASSERT(!mbedtls_svc_key_id_is_null(keys[i])); for (j = 0; j < i; j++) { TEST_ASSERT(!mbedtls_svc_key_id_equal(keys[i], keys[j])); } } - max_keys = i; for (i = 1; i < max_keys; i++) { + mbedtls_test_set_step(i); PSA_ASSERT(psa_close_key(keys[i - 1])); PSA_ASSERT(psa_export_key(keys[i], exported, sizeof(exported), @@ -843,6 +846,97 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MAX_VOLATILE_KEYS */ +void fill_key_store(int key_to_destroy_arg) +{ + mbedtls_svc_key_id_t *keys = NULL; + size_t max_keys = MAX_VOLATILE_KEYS; + size_t i, j; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + uint8_t exported[sizeof(size_t)]; + size_t exported_length; + + PSA_ASSERT(psa_crypto_init()); + + mbedtls_psa_stats_t stats; + mbedtls_psa_get_stats(&stats); + /* Account for any system-created volatile key, e.g. for the RNG. */ + max_keys -= stats.volatile_slots; + TEST_CALLOC(keys, max_keys + 1); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(&attributes, 0); + psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA); + + /* Fill the key store. */ + for (i = 0; i < max_keys; i++) { + mbedtls_test_set_step(i); + status = psa_import_key(&attributes, + (uint8_t *) &i, sizeof(i), + &keys[i]); + PSA_ASSERT(status); + TEST_ASSERT(!mbedtls_svc_key_id_is_null(keys[i])); + for (j = 0; j < i; j++) { + TEST_ASSERT(!mbedtls_svc_key_id_equal(keys[i], keys[j])); + } + } + + /* Attempt to overfill. */ + mbedtls_test_set_step(max_keys); + status = psa_import_key(&attributes, + (uint8_t *) &max_keys, sizeof(max_keys), + &keys[max_keys]); + TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_MEMORY); + TEST_ASSERT(mbedtls_svc_key_id_is_null(keys[max_keys])); + + /* Check that the keys are not corrupted. */ + for (i = 0; i < max_keys; i++) { + mbedtls_test_set_step(i); + PSA_ASSERT(psa_export_key(keys[i], + exported, sizeof(exported), + &exported_length)); + TEST_MEMORY_COMPARE(exported, exported_length, + (uint8_t *) &i, sizeof(i)); + } + + /* Destroy one key and try again. */ + size_t key_to_destroy = (key_to_destroy_arg >= 0 ? + (size_t) key_to_destroy_arg : + max_keys + key_to_destroy_arg); + mbedtls_svc_key_id_t reused_id = keys[key_to_destroy]; + const uint8_t replacement_value[1] = { 0x64 }; + PSA_ASSERT(psa_destroy_key(keys[key_to_destroy])); + keys[key_to_destroy] = MBEDTLS_SVC_KEY_ID_INIT; + status = psa_import_key(&attributes, + replacement_value, sizeof(replacement_value), + &keys[key_to_destroy]); + PSA_ASSERT(status); + TEST_ASSERT(mbedtls_svc_key_id_equal(reused_id, keys[key_to_destroy])); + + /* Check that the keys are not corrupted and destroy them. */ + for (i = 0; i < max_keys; i++) { + mbedtls_test_set_step(i); + PSA_ASSERT(psa_export_key(keys[i], + exported, sizeof(exported), + &exported_length)); + if (i == key_to_destroy) { + TEST_MEMORY_COMPARE(exported, exported_length, + replacement_value, sizeof(replacement_value)); + } else { + TEST_MEMORY_COMPARE(exported, exported_length, + (uint8_t *) &i, sizeof(i)); + } + PSA_ASSERT(psa_destroy_key(keys[i])); + keys[i] = MBEDTLS_SVC_KEY_ID_INIT; + } + +exit: + PSA_DONE(); + mbedtls_free(keys); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */ void key_slot_eviction_to_import_new_key(int lifetime_arg) { From f39b2e01907fb3f583a53d1c20cb1d6ca70a9c12 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 13 Jun 2024 20:28:58 +0200 Subject: [PATCH 013/100] Fix spurious test case failure with accelerated AES When the PSA RNG uses AES through a PSA driver, it consumes one volatile key identifier. When MBEDTLS_PSA_KEY_SLOT_DYNAMIC is enabled, that identifier happens to coincide with the key ID value that the test case assumes not to exist. Use a different value that avoids this coincidence. Signed-off-by: Gilles Peskine --- .../test_suite_psa_crypto_slot_management.data | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto_slot_management.data b/tests/suites/test_suite_psa_crypto_slot_management.data index 560350c6ee..742f9b1ace 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.data +++ b/tests/suites/test_suite_psa_crypto_slot_management.data @@ -122,7 +122,18 @@ open_fail:PSA_KEY_ID_VENDOR_MAX + 1:PSA_ERROR_DOES_NOT_EXIST Open failure: invalid identifier (implementation range) depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C -open_fail:PSA_KEY_ID_USER_MAX + 1:PSA_ERROR_DOES_NOT_EXIST +# We need to avoid existing volatile key IDs. Normally there aren't any +# existing volatile keys because the test case doesn't create any, but +# in some configurations, the implementation or a driver creates a +# volatile key during initialization for its own use. At the time of +# writing, this happens in builds where AES uses a PSA driver and the +# PSA RNG uses AES-CTR_DRBG through the PSA AES. +# Pick a key id that's in the middle of the volatile key ID range. +# That works out both when MBEDTLS_PSA_KEY_SLOT_DYNAMIC is enabled and +# volatile key IDs are assigned starting with the lowest value, and when +# MBEDTLS_PSA_KEY_SLOT_DYNAMIC is disabled and volatile key IDs are assigned +# starting with the highest values. +open_fail:(PSA_KEY_ID_VOLATILE_MIN + PSA_KEY_ID_VOLATILE_MAX) / 2:PSA_ERROR_DOES_NOT_EXIST Open failure: non-existent identifier depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C From d66dc64622aaae8c47500ce081f1d6c103e204e0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 17 Jul 2024 14:00:31 +0200 Subject: [PATCH 014/100] Keep track of PSA keys used interally When PSA uses CTR_DRBG for its random generator and CTR_DRBG uses PSA for AES, as currently implemented, there is one volatile key in permanent use for the CTR_DRBG instance. Account for that in tests that want to know exactly how many volatile keys are in use, or how many volatile keys can be created. Signed-off-by: Gilles Peskine --- tests/include/test/psa_crypto_helpers.h | 20 ++++++++++++++ tests/src/psa_crypto_helpers.c | 12 --------- .../test_suite_psa_crypto_init.function | 26 +++++++++++++++++++ ...test_suite_psa_crypto_slot_management.data | 5 +--- 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index fae715ca9a..71ba0fc021 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -440,4 +440,24 @@ uint64_t mbedtls_test_parse_binary_string(data_t *bin_string); #define AES_PSA_DONE() ((void) 0) #endif /* MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO */ +#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \ + defined(MBEDTLS_CTR_DRBG_C) && \ + defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) +/* When AES_C is not defined and PSA does not have an external RNG, + * then CTR_DRBG uses PSA to perform AES-ECB. In this scenario 1 key + * slot is used internally from PSA to hold the AES key and it should + * not be taken into account when evaluating remaining open slots. */ +#define MBEDTLS_TEST_PSA_INTERNAL_KEYS_FOR_DRBG 1 +#else +#define MBEDTLS_TEST_PSA_INTERNAL_KEYS_FOR_DRBG 0 +#endif + +/** The number of volatile keys that PSA crypto uses internally. + * + * We expect that many volatile keys to be in use after a successful + * psa_crypto_init(). + */ +#define MBEDTLS_TEST_PSA_INTERNAL_KEYS \ + MBEDTLS_TEST_PSA_INTERNAL_KEYS_FOR_DRBG + #endif /* PSA_CRYPTO_HELPERS_H */ diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c index 1581eecb3b..1069eddfa1 100644 --- a/tests/src/psa_crypto_helpers.c +++ b/tests/src/psa_crypto_helpers.c @@ -74,21 +74,9 @@ const char *mbedtls_test_helper_is_psa_leaking(void) mbedtls_psa_get_stats(&stats); -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \ - defined(MBEDTLS_CTR_DRBG_C) && \ - defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - /* When AES_C is not defined and PSA does not have an external RNG, - * then CTR_DRBG uses PSA to perform AES-ECB. In this scenario 1 key - * slot is used internally from PSA to hold the AES key and it should - * not be taken into account when evaluating remaining open slots. */ if (stats.volatile_slots > 1) { return "A volatile slot has not been closed properly."; } -#else - if (stats.volatile_slots != 0) { - return "A volatile slot has not been closed properly."; - } -#endif if (stats.persistent_slots != 0) { return "A persistent slot has not been closed properly."; } diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function index 9ff33a6d84..2fd282ec61 100644 --- a/tests/suites/test_suite_psa_crypto_init.function +++ b/tests/suites/test_suite_psa_crypto_init.function @@ -8,6 +8,23 @@ #include "mbedtls/entropy.h" #include "entropy_poll.h" +static int check_stats(void) +{ + mbedtls_psa_stats_t stats; + mbedtls_psa_get_stats(&stats); + + TEST_EQUAL(stats.volatile_slots, MBEDTLS_TEST_PSA_INTERNAL_KEYS); + TEST_EQUAL(stats.persistent_slots, 0); + TEST_EQUAL(stats.external_slots, 0); + TEST_EQUAL(stats.half_filled_slots, 0); + TEST_EQUAL(stats.locked_slots, 0); + + return 1; + +exit: + return 0; +} + #define ENTROPY_MIN_NV_SEED_SIZE \ MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE) @@ -187,10 +204,19 @@ void init_deinit(int count) psa_status_t status; int i; for (i = 0; i < count; i++) { + mbedtls_test_set_step(2 * i); status = psa_crypto_init(); PSA_ASSERT(status); + if (!check_stats()) { + goto exit; + } + + mbedtls_test_set_step(2 * i); status = psa_crypto_init(); PSA_ASSERT(status); + if (!check_stats()) { + goto exit; + } PSA_DONE(); } } diff --git a/tests/suites/test_suite_psa_crypto_slot_management.data b/tests/suites/test_suite_psa_crypto_slot_management.data index 742f9b1ace..af3b946754 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.data +++ b/tests/suites/test_suite_psa_crypto_slot_management.data @@ -225,11 +225,8 @@ invalid_handle:INVALID_HANDLE_CLOSED:PSA_ERROR_INVALID_HANDLE invalid handle: huge invalid_handle:INVALID_HANDLE_HUGE:PSA_ERROR_INVALID_HANDLE -Key slot count: less than maximum -many_transient_keys:MBEDTLS_PSA_KEY_SLOT_COUNT - 1 - Key slot count: maximum -many_transient_keys:MBEDTLS_PSA_KEY_SLOT_COUNT +many_transient_keys:MBEDTLS_PSA_KEY_SLOT_COUNT - MBEDTLS_TEST_PSA_INTERNAL_KEYS Key slot count: try to overfill, destroy first fill_key_store:0 From c297c76b5bd8f4f112356f3f464809bf9ad011b6 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 18 Jul 2024 19:03:02 +0200 Subject: [PATCH 015/100] Fix copypasta Signed-off-by: Gilles Peskine --- include/mbedtls/ctr_drbg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 216169c770..0b7cce1923 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -41,7 +41,7 @@ * When MBEDTLS_AES_C is disabled, the CTR_DRBG module calls PSA crypto and * thus benefits from the PSA AES accelerator driver. * It is technically possible to enable MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO - * to use PSA even when MBEDTLS_AES_C is disabled, but there is very little + * to use PSA even when MBEDTLS_AES_C is enabled, but there is very little * reason to do so other than testing purposes and this is not officially * supported. */ From c9184fe7ab73d9cb00cc537d88d2f79d46a17ec2 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Mon, 27 May 2024 19:59:21 +0200 Subject: [PATCH 016/100] Fix server mode only build of v3.6 with MBEDTLS_SSL_CLI_C unset (fixes #9186) Signed-off-by: Michael Schuster --- ChangeLog.d/fix-server-mode-only-build.txt | 3 +++ library/ssl_misc.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 ChangeLog.d/fix-server-mode-only-build.txt diff --git a/ChangeLog.d/fix-server-mode-only-build.txt b/ChangeLog.d/fix-server-mode-only-build.txt new file mode 100644 index 0000000000..d1d8341f79 --- /dev/null +++ b/ChangeLog.d/fix-server-mode-only-build.txt @@ -0,0 +1,3 @@ +Bugfix + * Fix server mode only build when MBEDTLS_SSL_SRV_C is enabled but + MBEDTLS_SSL_CLI_C is disabled. Reported by M-Bab on GitHub in #9186. diff --git a/library/ssl_misc.h b/library/ssl_misc.h index a8807f67c6..8402fe86ae 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1507,7 +1507,7 @@ int mbedtls_ssl_psk_derive_premaster(mbedtls_ssl_context *ssl, #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) -#if defined(MBEDTLS_SSL_CLI_C) +#if defined(MBEDTLS_SSL_CLI_C) || defined(MBEDTLS_SSL_SRV_C) MBEDTLS_CHECK_RETURN_CRITICAL int mbedtls_ssl_conf_has_static_psk(mbedtls_ssl_config const *conf); #endif From 5be4fd784e74c3d975cc1b904c3463712d2dbd86 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Mon, 27 May 2024 20:07:05 +0200 Subject: [PATCH 017/100] Fix build of v3.6 with unset MBEDTLS_DHM_C but MBEDTLS_USE_PSA_CRYPTO set (fixes #9188) Avoid compiler warning about size comparison (like in commit 7910cdd): Clang builds fail, warning about comparing uint8_t to a size that may be >255. Signed-off-by: Michael Schuster --- ChangeLog.d/fix-clang-psa-build-without-dhm.txt | 3 +++ library/ssl_tls12_server.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 ChangeLog.d/fix-clang-psa-build-without-dhm.txt diff --git a/ChangeLog.d/fix-clang-psa-build-without-dhm.txt b/ChangeLog.d/fix-clang-psa-build-without-dhm.txt new file mode 100644 index 0000000000..7ae1c68a40 --- /dev/null +++ b/ChangeLog.d/fix-clang-psa-build-without-dhm.txt @@ -0,0 +1,3 @@ +Bugfix + * Fix Clang compilation error when MBEDTLS_USE_PSA_CRYPTO is enabled + but MBEDTLS_DHM_C is disabled. Reported by Michael Schuster in #9188. diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index b5b975ff40..81ee6002e1 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -3921,7 +3921,7 @@ static int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_USE_PSA_CRYPTO) psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED; - uint8_t ecpoint_len; + size_t ecpoint_len; mbedtls_ssl_handshake_params *handshake = ssl->handshake; From 83222b8c4158d1887414c59488c77de018ea08fe Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 6 Aug 2024 12:06:51 +0100 Subject: [PATCH 018/100] Add -Wmissing-prototypes to component_build_no_ssl_srv and component_build_no_ssl_cli in all.sh Signed-off-by: Michael Schuster Signed-off-by: Minos Galanakis --- tests/scripts/components-configuration-tls.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/components-configuration-tls.sh b/tests/scripts/components-configuration-tls.sh index 5511cc9fd4..7debb342b0 100644 --- a/tests/scripts/components-configuration-tls.sh +++ b/tests/scripts/components-configuration-tls.sh @@ -315,14 +315,14 @@ component_build_no_ssl_srv () { msg "build: full config except SSL server, make, gcc" # ~ 30s scripts/config.py full scripts/config.py unset MBEDTLS_SSL_SRV_C - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1' + make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1 -Wmissing-prototypes' } component_build_no_ssl_cli () { msg "build: full config except SSL client, make, gcc" # ~ 30s scripts/config.py full scripts/config.py unset MBEDTLS_SSL_CLI_C - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1' + make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1 -Wmissing-prototypes' } component_test_no_max_fragment_length () { From b4d55bb5db6d1a9361687367efbafd2c066c438f Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Wed, 29 May 2024 19:51:36 +0200 Subject: [PATCH 019/100] Add missing include in tests/src/asn1_helpers.c Signed-off-by: Michael Schuster --- tests/src/asn1_helpers.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/src/asn1_helpers.c b/tests/src/asn1_helpers.c index c8df1995e3..c63bd0cdf7 100644 --- a/tests/src/asn1_helpers.c +++ b/tests/src/asn1_helpers.c @@ -15,6 +15,8 @@ #include +#include + int mbedtls_test_asn1_skip_integer(unsigned char **p, const unsigned char *end, size_t min_bits, size_t max_bits, int must_be_odd) From 3a4c43174cd49a9fd75eb4e5c34dab148877daad Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Sat, 1 Jun 2024 21:00:33 +0200 Subject: [PATCH 020/100] Move print_buf into mbedtls_test_print_buf helper function in sample programs Reduce code duplication and fix missing-prototype error for print_buf Signed-off-by: Michael Schuster --- programs/cipher/cipher_aead_demo.c | 14 +++----------- programs/hash/md_hmac_demo.c | 16 ++++------------ programs/psa/aead_demo.c | 14 +++----------- programs/psa/hmac_demo.c | 16 ++++------------ tests/include/test/helpers.h | 3 +++ tests/src/helpers.c | 9 +++++++++ 6 files changed, 26 insertions(+), 46 deletions(-) diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c index 853ec202c6..60a5ea280e 100644 --- a/programs/cipher/cipher_aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -35,6 +35,8 @@ #include "mbedtls/cipher.h" +#include + #include #include #include @@ -78,16 +80,6 @@ const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; * 32-byte is enough to all the key size supported by this program. */ const unsigned char key_bytes[32] = { 0x2a }; -/* Print the contents of a buffer in hex */ -void print_buf(const char *title, unsigned char *buf, size_t len) -{ - printf("%s:", title); - for (size_t i = 0; i < len; i++) { - printf(" %02x", buf[i]); - } - printf("\n"); -} - /* Run an Mbed TLS function and bail out if it fails. * A string description of the error code can be recovered with: * programs/util/strerror */ @@ -198,7 +190,7 @@ static int aead_encrypt(mbedtls_cipher_context_t *ctx, size_t tag_len, p += tag_len; olen = p - out; - print_buf("out", out, olen); + mbedtls_test_print_buf("out", out, olen); exit: return ret; diff --git a/programs/hash/md_hmac_demo.c b/programs/hash/md_hmac_demo.c index 581816a1d9..a0127ed6b7 100644 --- a/programs/hash/md_hmac_demo.c +++ b/programs/hash/md_hmac_demo.c @@ -32,6 +32,8 @@ #include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize +#include + #include #include @@ -56,16 +58,6 @@ const unsigned char msg2_part2[] = { 0x06, 0x06 }; * This example program uses SHA-256, so a 32-byte key makes sense. */ const unsigned char key_bytes[32] = { 0 }; -/* Print the contents of a buffer in hex */ -void print_buf(const char *title, unsigned char *buf, size_t len) -{ - printf("%s:", title); - for (size_t i = 0; i < len; i++) { - printf(" %02x", buf[i]); - } - printf("\n"); -} - /* Run an Mbed TLS function and bail out if it fails. * A string description of the error code can be recovered with: * programs/util/strerror */ @@ -107,14 +99,14 @@ int hmac_demo(void) CHK(mbedtls_md_hmac_update(&ctx, msg1_part1, sizeof(msg1_part1))); CHK(mbedtls_md_hmac_update(&ctx, msg1_part2, sizeof(msg1_part2))); CHK(mbedtls_md_hmac_finish(&ctx, out)); - print_buf("msg1", out, mbedtls_md_get_size(info)); + mbedtls_test_print_buf("msg1", out, mbedtls_md_get_size(info)); /* compute HMAC(key, msg2_part1 | msg2_part2) */ CHK(mbedtls_md_hmac_reset(&ctx)); // prepare for new operation CHK(mbedtls_md_hmac_update(&ctx, msg2_part1, sizeof(msg2_part1))); CHK(mbedtls_md_hmac_update(&ctx, msg2_part2, sizeof(msg2_part2))); CHK(mbedtls_md_hmac_finish(&ctx, out)); - print_buf("msg2", out, mbedtls_md_get_size(info)); + mbedtls_test_print_buf("msg2", out, mbedtls_md_get_size(info)); exit: mbedtls_md_free(&ctx); diff --git a/programs/psa/aead_demo.c b/programs/psa/aead_demo.c index 619166dba4..b300e3619c 100644 --- a/programs/psa/aead_demo.c +++ b/programs/psa/aead_demo.c @@ -36,6 +36,8 @@ #include "psa/crypto.h" +#include + #include #include #include @@ -81,16 +83,6 @@ const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; * 32-byte is enough to all the key size supported by this program. */ const unsigned char key_bytes[32] = { 0x2a }; -/* Print the contents of a buffer in hex */ -void print_buf(const char *title, uint8_t *buf, size_t len) -{ - printf("%s:", title); - for (size_t i = 0; i < len; i++) { - printf(" %02x", buf[i]); - } - printf("\n"); -} - /* Run a PSA function and bail out if it fails. * The symbolic name of the error code can be recovered using: * programs/psa/psa_constant_name status */ @@ -216,7 +208,7 @@ static int aead_encrypt(psa_key_id_t key, psa_algorithm_t alg, p += olen_tag; olen = p - out; - print_buf("out", out, olen); + mbedtls_test_print_buf("out", out, olen); exit: psa_aead_abort(&op); // required on errors, harmless on success diff --git a/programs/psa/hmac_demo.c b/programs/psa/hmac_demo.c index 205505407f..6ed82989b0 100644 --- a/programs/psa/hmac_demo.c +++ b/programs/psa/hmac_demo.c @@ -32,6 +32,8 @@ #include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize +#include + #include #include @@ -58,16 +60,6 @@ const unsigned char msg2_part2[] = { 0x06, 0x06 }; * This example program uses SHA-256, so a 32-byte key makes sense. */ const unsigned char key_bytes[32] = { 0 }; -/* Print the contents of a buffer in hex */ -void print_buf(const char *title, uint8_t *buf, size_t len) -{ - printf("%s:", title); - for (size_t i = 0; i < len; i++) { - printf(" %02x", buf[i]); - } - printf("\n"); -} - /* Run a PSA function and bail out if it fails. * The symbolic name of the error code can be recovered using: * programs/psa/psa_constant_name status */ @@ -122,14 +114,14 @@ psa_status_t hmac_demo(void) PSA_CHECK(psa_mac_update(&op, msg1_part1, sizeof(msg1_part1))); PSA_CHECK(psa_mac_update(&op, msg1_part2, sizeof(msg1_part2))); PSA_CHECK(psa_mac_sign_finish(&op, out, sizeof(out), &out_len)); - print_buf("msg1", out, out_len); + mbedtls_test_print_buf("msg1", out, out_len); /* compute HMAC(key, msg2_part1 | msg2_part2) */ PSA_CHECK(psa_mac_sign_setup(&op, key, alg)); PSA_CHECK(psa_mac_update(&op, msg2_part1, sizeof(msg2_part1))); PSA_CHECK(psa_mac_update(&op, msg2_part2, sizeof(msg2_part2))); PSA_CHECK(psa_mac_sign_finish(&op, out, sizeof(out), &out_len)); - print_buf("msg2", out, out_len); + mbedtls_test_print_buf("msg2", out, out_len); exit: psa_mac_abort(&op); // needed on error, harmless on success diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h index d08100f158..10b321d781 100644 --- a/tests/include/test/helpers.h +++ b/tests/include/test/helpers.h @@ -381,6 +381,9 @@ unsigned char *mbedtls_test_unhexify_alloc(const char *ibuf, size_t *olen); int mbedtls_test_hexcmp(uint8_t *a, uint8_t *b, uint32_t a_len, uint32_t b_len); +/* Print the contents of a buffer in hex */ +void mbedtls_test_print_buf(const char *title, unsigned char *buf, size_t len); + #if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) #include "test/fake_external_rng_for_test.h" #endif diff --git a/tests/src/helpers.c b/tests/src/helpers.c index 065d17d3e0..29b2df515d 100644 --- a/tests/src/helpers.c +++ b/tests/src/helpers.c @@ -660,6 +660,15 @@ int mbedtls_test_hexcmp(uint8_t *a, uint8_t *b, return ret; } +void mbedtls_test_print_buf(const char *title, unsigned char *buf, size_t len) +{ + printf("%s:", title); + for (size_t i = 0; i < len; i++) { + printf(" %02x", buf[i]); + } + printf("\n"); +} + #if defined(MBEDTLS_TEST_HOOKS) void mbedtls_test_err_add_check(int high, int low, const char *file, int line) From 41a686bb9fd36c8eff551f0fc91f47f5631ec421 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Sat, 1 Jun 2024 21:08:45 +0200 Subject: [PATCH 021/100] Fix missing-prototype error in programs/fuzz by moving LLVMFuzzerTestOneInput prototype to common.h Signed-off-by: Michael Schuster --- programs/fuzz/common.h | 3 +++ programs/fuzz/fuzz_pkcs7.c | 1 + programs/fuzz/fuzz_pubkey.c | 1 + programs/fuzz/fuzz_x509crl.c | 1 + programs/fuzz/fuzz_x509crt.c | 1 + programs/fuzz/fuzz_x509csr.c | 1 + programs/fuzz/onefile.c | 3 +-- 7 files changed, 9 insertions(+), 2 deletions(-) diff --git a/programs/fuzz/common.h b/programs/fuzz/common.h index 094383c7a4..88dceacf72 100644 --- a/programs/fuzz/common.h +++ b/programs/fuzz/common.h @@ -23,3 +23,6 @@ int dummy_random(void *p_rng, unsigned char *output, size_t output_len); int dummy_entropy(void *data, unsigned char *output, size_t len); int fuzz_recv_timeout(void *ctx, unsigned char *buf, size_t len, uint32_t timeout); + +/* Implemented in the fuzz_*.c sources and required by onefile.c */ +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); diff --git a/programs/fuzz/fuzz_pkcs7.c b/programs/fuzz/fuzz_pkcs7.c index 2056913f25..38b4dc1399 100644 --- a/programs/fuzz/fuzz_pkcs7.c +++ b/programs/fuzz/fuzz_pkcs7.c @@ -1,5 +1,6 @@ #include #include "mbedtls/pkcs7.h" +#include "common.h" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { diff --git a/programs/fuzz/fuzz_pubkey.c b/programs/fuzz/fuzz_pubkey.c index 0b153b14d7..b2500e57c2 100644 --- a/programs/fuzz/fuzz_pubkey.c +++ b/programs/fuzz/fuzz_pubkey.c @@ -1,6 +1,7 @@ #include #include #include "mbedtls/pk.h" +#include "common.h" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { diff --git a/programs/fuzz/fuzz_x509crl.c b/programs/fuzz/fuzz_x509crl.c index 151db92c89..e8dacd90b6 100644 --- a/programs/fuzz/fuzz_x509crl.c +++ b/programs/fuzz/fuzz_x509crl.c @@ -1,5 +1,6 @@ #include #include "mbedtls/x509_crl.h" +#include "common.h" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { diff --git a/programs/fuzz/fuzz_x509crt.c b/programs/fuzz/fuzz_x509crt.c index 3eee07258b..74d3b077c6 100644 --- a/programs/fuzz/fuzz_x509crt.c +++ b/programs/fuzz/fuzz_x509crt.c @@ -1,5 +1,6 @@ #include #include "mbedtls/x509_crt.h" +#include "common.h" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { diff --git a/programs/fuzz/fuzz_x509csr.c b/programs/fuzz/fuzz_x509csr.c index 7946e57eda..4c123f8e0d 100644 --- a/programs/fuzz/fuzz_x509csr.c +++ b/programs/fuzz/fuzz_x509csr.c @@ -1,5 +1,6 @@ #include #include "mbedtls/x509_csr.h" +#include "common.h" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { diff --git a/programs/fuzz/onefile.c b/programs/fuzz/onefile.c index 3b2709f805..2d4330abc3 100644 --- a/programs/fuzz/onefile.c +++ b/programs/fuzz/onefile.c @@ -1,14 +1,13 @@ #include #include #include +#include "common.h" /* This file doesn't use any Mbed TLS function, but grab mbedtls_config.h anyway * in case it contains platform-specific #defines related to malloc or * stdio functions. */ #include "mbedtls/build_info.h" -int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); - int main(int argc, char **argv) { FILE *fp; From 6fa32fd12dd5a21334f633cfbd3bfc397164feff Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Sat, 1 Jun 2024 21:15:02 +0200 Subject: [PATCH 022/100] Fix missing-prototype errors in sample programs Signed-off-by: Michael Schuster --- programs/hash/md_hmac_demo.c | 2 +- programs/pkey/gen_key.c | 2 +- programs/psa/hmac_demo.c | 2 +- programs/psa/psa_constant_names.c | 4 ++-- programs/ssl/ssl_client2.c | 2 +- programs/ssl/ssl_context_info.c | 32 ++++++++++++------------- programs/ssl/ssl_server2.c | 26 ++++++++++---------- programs/ssl/ssl_test_common_source.c | 18 +++++++------- programs/test/metatest.c | 34 +++++++++++++-------------- programs/test/selftest.c | 4 ++-- programs/test/udp_proxy.c | 12 +++++----- programs/test/zeroize.c | 2 +- programs/util/pem2der.c | 2 +- programs/x509/cert_req.c | 2 +- programs/x509/cert_write.c | 4 ++-- programs/x509/load_roots.c | 2 +- 16 files changed, 75 insertions(+), 75 deletions(-) diff --git a/programs/hash/md_hmac_demo.c b/programs/hash/md_hmac_demo.c index a0127ed6b7..ba51bfda26 100644 --- a/programs/hash/md_hmac_demo.c +++ b/programs/hash/md_hmac_demo.c @@ -79,7 +79,7 @@ const unsigned char key_bytes[32] = { 0 }; * This function demonstrates computation of the HMAC of two messages using * the multipart API. */ -int hmac_demo(void) +static int hmac_demo(void) { int ret; const mbedtls_md_type_t alg = MBEDTLS_MD_SHA256; diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c index 194a5cbba6..4ad162978b 100644 --- a/programs/pkey/gen_key.c +++ b/programs/pkey/gen_key.c @@ -39,7 +39,7 @@ int main(void) #define DEV_RANDOM_THRESHOLD 32 -int dev_random_entropy_poll(void *data, unsigned char *output, +static int dev_random_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen) { FILE *file; diff --git a/programs/psa/hmac_demo.c b/programs/psa/hmac_demo.c index 6ed82989b0..a85de008a7 100644 --- a/programs/psa/hmac_demo.c +++ b/programs/psa/hmac_demo.c @@ -82,7 +82,7 @@ const unsigned char key_bytes[32] = { 0 }; * This function demonstrates computation of the HMAC of two messages using * the multipart API. */ -psa_status_t hmac_demo(void) +static psa_status_t hmac_demo(void) { psa_status_t status; const psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256); diff --git a/programs/psa/psa_constant_names.c b/programs/psa/psa_constant_names.c index 0baf4a065e..7905b527cc 100644 --- a/programs/psa/psa_constant_names.c +++ b/programs/psa/psa_constant_names.c @@ -192,7 +192,7 @@ typedef enum { TYPE_STATUS, } signed_value_type; -int process_signed(signed_value_type type, long min, long max, char **argp) +static int process_signed(signed_value_type type, long min, long max, char **argp) { for (; *argp != NULL; argp++) { char buffer[200]; @@ -231,7 +231,7 @@ typedef enum { TYPE_KEY_USAGE, } unsigned_value_type; -int process_unsigned(unsigned_value_type type, unsigned long max, char **argp) +static int process_unsigned(unsigned_value_type type, unsigned long max, char **argp) { for (; *argp != NULL; argp++) { char buffer[200]; diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 43133d901c..bd0735ea9f 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -597,7 +597,7 @@ static int my_verify(void *data, mbedtls_x509_crt *crt, #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -int report_cid_usage(mbedtls_ssl_context *ssl, +static int report_cid_usage(mbedtls_ssl_context *ssl, const char *additional_description) { int ret; diff --git a/programs/ssl/ssl_context_info.c b/programs/ssl/ssl_context_info.c index ee2cdb7b96..9577d2b900 100644 --- a/programs/ssl/ssl_context_info.c +++ b/programs/ssl/ssl_context_info.c @@ -111,12 +111,12 @@ const char buf_ln_err[] = "Buffer does not have enough data to complete the pars /* * Basic printing functions */ -void print_version(void) +static void print_version(void) { printf("%s v%d.%d\n", PROG_NAME, VER_MAJOR, VER_MINOR); } -void print_usage(void) +static void print_usage(void) { print_version(); printf("\nThis program is used to deserialize an Mbed TLS SSL session from the base64 code provided\n" @@ -138,7 +138,7 @@ void print_usage(void) ); } -void printf_dbg(const char *str, ...) +static void printf_dbg(const char *str, ...) { if (debug) { va_list args; @@ -151,7 +151,7 @@ void printf_dbg(const char *str, ...) } MBEDTLS_PRINTF_ATTRIBUTE(1, 2) -void printf_err(const char *str, ...) +static void printf_err(const char *str, ...) { va_list args; va_start(args, str); @@ -165,7 +165,7 @@ void printf_err(const char *str, ...) /* * Exit from the program in case of error */ -void error_exit(void) +static void error_exit(void) { if (NULL != b64_file) { fclose(b64_file); @@ -176,7 +176,7 @@ void error_exit(void) /* * This function takes the input arguments of this program */ -void parse_arguments(int argc, char *argv[]) +static void parse_arguments(int argc, char *argv[]) { int i = 1; @@ -223,7 +223,7 @@ void parse_arguments(int argc, char *argv[]) /* * This function prints base64 code to the stdout */ -void print_b64(const uint8_t *b, size_t len) +static void print_b64(const uint8_t *b, size_t len) { size_t i = 0; const uint8_t *end = b + len; @@ -247,7 +247,7 @@ void print_b64(const uint8_t *b, size_t len) * /p in_line number of bytes in one line * /p prefix prefix for the new lines */ -void print_hex(const uint8_t *b, size_t len, +static void print_hex(const uint8_t *b, size_t len, const size_t in_line, const char *prefix) { size_t i = 0; @@ -271,7 +271,7 @@ void print_hex(const uint8_t *b, size_t len, /* * Print the value of time_t in format e.g. 2020-01-23 13:05:59 */ -void print_time(const uint64_t *time) +static void print_time(const uint64_t *time) { #if defined(MBEDTLS_HAVE_TIME) char buf[20]; @@ -292,7 +292,7 @@ void print_time(const uint64_t *time) /* * Print the input string if the bit is set in the value */ -void print_if_bit(const char *str, int bit, int val) +static void print_if_bit(const char *str, int bit, int val) { if (bit & val) { printf("\t%s\n", str); @@ -302,7 +302,7 @@ void print_if_bit(const char *str, int bit, int val) /* * Return pointer to hardcoded "enabled" or "disabled" depending on the input value */ -const char *get_enabled_str(int is_en) +static const char *get_enabled_str(int is_en) { return (is_en) ? "enabled" : "disabled"; } @@ -310,7 +310,7 @@ const char *get_enabled_str(int is_en) /* * Return pointer to hardcoded MFL string value depending on the MFL code at the input */ -const char *get_mfl_str(int mfl_code) +static const char *get_mfl_str(int mfl_code) { switch (mfl_code) { case MBEDTLS_SSL_MAX_FRAG_LEN_NONE: @@ -343,7 +343,7 @@ const char *get_mfl_str(int mfl_code) * \retval number of bytes written in to the b64 buffer or 0 in case no more * data was found */ -size_t read_next_b64_code(uint8_t **b64, size_t *max_len) +static size_t read_next_b64_code(uint8_t **b64, size_t *max_len) { int valid_balance = 0; /* balance between valid and invalid characters */ size_t len = 0; @@ -443,7 +443,7 @@ size_t read_next_b64_code(uint8_t **b64, size_t *max_len) * /p ssl pointer to serialized certificate * /p len number of bytes in the buffer */ -void print_deserialized_ssl_cert(const uint8_t *ssl, uint32_t len) +static void print_deserialized_ssl_cert(const uint8_t *ssl, uint32_t len) { enum { STRLEN = 4096 }; mbedtls_x509_crt crt; @@ -509,7 +509,7 @@ void print_deserialized_ssl_cert(const uint8_t *ssl, uint32_t len) * /p len number of bytes in the buffer * /p session_cfg_flag session configuration flags */ -void print_deserialized_ssl_session(const uint8_t *ssl, uint32_t len, +static void print_deserialized_ssl_session(const uint8_t *ssl, uint32_t len, int session_cfg_flag) { const struct mbedtls_ssl_ciphersuite_t *ciphersuite_info; @@ -746,7 +746,7 @@ void print_deserialized_ssl_session(const uint8_t *ssl, uint32_t len, * /p ssl pointer to serialized session * /p len number of bytes in the buffer */ -void print_deserialized_ssl_context(const uint8_t *ssl, size_t len) +static void print_deserialized_ssl_context(const uint8_t *ssl, size_t len) { const uint8_t *end = ssl + len; uint32_t session_len; diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index a5d2ed1020..8887ddeed5 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -756,7 +756,7 @@ struct _sni_entry { sni_entry *next; }; -void sni_free(sni_entry *head) +static void sni_free(sni_entry *head) { sni_entry *cur = head, *next; @@ -786,7 +786,7 @@ void sni_free(sni_entry *head) * * Modifies the input string! This is not production quality! */ -sni_entry *sni_parse(char *sni_string) +static sni_entry *sni_parse(char *sni_string) { sni_entry *cur = NULL, *new = NULL; char *p = sni_string; @@ -878,7 +878,7 @@ error: /* * SNI callback. */ -int sni_callback(void *p_info, mbedtls_ssl_context *ssl, +static int sni_callback(void *p_info, mbedtls_ssl_context *ssl, const unsigned char *name, size_t name_len) { const sni_entry *cur = (const sni_entry *) p_info; @@ -909,7 +909,7 @@ int sni_callback(void *p_info, mbedtls_ssl_context *ssl, /* * server certificate selection callback. */ -int cert_callback(mbedtls_ssl_context *ssl) +static int cert_callback(mbedtls_ssl_context *ssl) { const sni_entry *cur = (sni_entry *) mbedtls_ssl_get_user_data_p(ssl); if (cur != NULL) { @@ -954,7 +954,7 @@ struct _psk_entry { /* * Free a list of psk_entry's */ -int psk_free(psk_entry *head) +static int psk_free(psk_entry *head) { psk_entry *next; @@ -985,7 +985,7 @@ int psk_free(psk_entry *head) * * Modifies the input string! This is not production quality! */ -psk_entry *psk_parse(char *psk_string) +static psk_entry *psk_parse(char *psk_string) { psk_entry *cur = NULL, *new = NULL; char *p = psk_string; @@ -1027,7 +1027,7 @@ error: /* * PSK callback */ -int psk_callback(void *p_info, mbedtls_ssl_context *ssl, +static int psk_callback(void *p_info, mbedtls_ssl_context *ssl, const unsigned char *name, size_t name_len) { psk_entry *cur = (psk_entry *) p_info; @@ -1055,7 +1055,7 @@ static mbedtls_net_context listen_fd, client_fd; /* Interruption handler to ensure clean exit (for valgrind testing) */ #if !defined(_WIN32) static int received_sigterm = 0; -void term_handler(int sig) +static void term_handler(int sig) { ((void) sig); received_sigterm = 1; @@ -1105,7 +1105,7 @@ typedef struct { void *p_rng; } ssl_async_key_context_t; -int ssl_async_set_key(ssl_async_key_context_t *ctx, +static int ssl_async_set_key(ssl_async_key_context_t *ctx, mbedtls_x509_crt *cert, mbedtls_pk_context *pk, int pk_take_ownership, @@ -1332,7 +1332,7 @@ static psa_status_t psa_setup_psk_key_slot(mbedtls_svc_key_id_t *slot, #endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -int report_cid_usage(mbedtls_ssl_context *ssl, +static int report_cid_usage(mbedtls_ssl_context *ssl, const char *additional_description) { int ret; @@ -1383,7 +1383,7 @@ static inline void put_unaligned_uint32(void *p, uint32_t x) } /* Functions for session ticket tests */ -int dummy_ticket_write(void *p_ticket, const mbedtls_ssl_session *session, +static int dummy_ticket_write(void *p_ticket, const mbedtls_ssl_session *session, unsigned char *start, const unsigned char *end, size_t *tlen, uint32_t *ticket_lifetime) { @@ -1410,7 +1410,7 @@ int dummy_ticket_write(void *p_ticket, const mbedtls_ssl_session *session, return 0; } -int dummy_ticket_parse(void *p_ticket, mbedtls_ssl_session *session, +static int dummy_ticket_parse(void *p_ticket, mbedtls_ssl_session *session, unsigned char *buf, size_t len) { int ret; @@ -1469,7 +1469,7 @@ int dummy_ticket_parse(void *p_ticket, mbedtls_ssl_session *session, } #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_HAVE_TIME */ -int parse_cipher(char *buf) +static int parse_cipher(char *buf) { if (strcmp(buf, "AES-128-CCM")) { return MBEDTLS_CIPHER_AES_128_CCM; diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c index 1ff2077d4a..b339a39db8 100644 --- a/programs/ssl/ssl_test_common_source.c +++ b/programs/ssl/ssl_test_common_source.c @@ -12,7 +12,7 @@ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ -void eap_tls_key_derivation(void *p_expkey, +static void eap_tls_key_derivation(void *p_expkey, mbedtls_ssl_key_export_type secret_type, const unsigned char *secret, size_t secret_len, @@ -36,7 +36,7 @@ void eap_tls_key_derivation(void *p_expkey, keys->tls_prf_type = tls_prf_type; } -void nss_keylog_export(void *p_expkey, +static void nss_keylog_export(void *p_expkey, mbedtls_ssl_key_export_type secret_type, const unsigned char *secret, size_t secret_len, @@ -106,7 +106,7 @@ exit: } #if defined(MBEDTLS_SSL_DTLS_SRTP) -void dtls_srtp_key_derivation(void *p_expkey, +static void dtls_srtp_key_derivation(void *p_expkey, mbedtls_ssl_key_export_type secret_type, const unsigned char *secret, size_t secret_len, @@ -131,7 +131,7 @@ void dtls_srtp_key_derivation(void *p_expkey, } #endif /* MBEDTLS_SSL_DTLS_SRTP */ -int ssl_check_record(mbedtls_ssl_context const *ssl, +static int ssl_check_record(mbedtls_ssl_context const *ssl, unsigned char const *buf, size_t len) { int my_ret = 0, ret_cr1, ret_cr2; @@ -195,7 +195,7 @@ cleanup: return my_ret; } -int recv_cb(void *ctx, unsigned char *buf, size_t len) +static int recv_cb(void *ctx, unsigned char *buf, size_t len) { io_ctx_t *io_ctx = (io_ctx_t *) ctx; size_t recv_len; @@ -223,7 +223,7 @@ int recv_cb(void *ctx, unsigned char *buf, size_t len) return (int) recv_len; } -int recv_timeout_cb(void *ctx, unsigned char *buf, size_t len, +static int recv_timeout_cb(void *ctx, unsigned char *buf, size_t len, uint32_t timeout) { io_ctx_t *io_ctx = (io_ctx_t *) ctx; @@ -248,7 +248,7 @@ int recv_timeout_cb(void *ctx, unsigned char *buf, size_t len, return (int) recv_len; } -int send_cb(void *ctx, unsigned char const *buf, size_t len) +static int send_cb(void *ctx, unsigned char const *buf, size_t len) { io_ctx_t *io_ctx = (io_ctx_t *) ctx; @@ -319,7 +319,7 @@ uint16_t ssl_sig_algs_for_test[] = { /** Functionally equivalent to mbedtls_x509_crt_verify_info, see that function * for more info. */ -int x509_crt_verify_info(char *buf, size_t size, const char *prefix, +static int x509_crt_verify_info(char *buf, size_t size, const char *prefix, uint32_t flags) { #if !defined(MBEDTLS_X509_REMOVE_INFO) @@ -352,7 +352,7 @@ int x509_crt_verify_info(char *buf, size_t size, const char *prefix, } #endif /* MBEDTLS_X509_CRT_PARSE_C */ -void mbedtls_print_supported_sig_algs(void) +static void mbedtls_print_supported_sig_algs(void) { mbedtls_printf("supported signature algorithms:\n"); mbedtls_printf("\trsa_pkcs1_sha256 "); diff --git a/programs/test/metatest.c b/programs/test/metatest.c index 75829ecee2..9d90d8cb72 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -76,13 +76,13 @@ void(*volatile do_nothing_with_object_but_the_compiler_does_not_know)(void *) = /* Test framework features */ /****************************************************************/ -void meta_test_fail(const char *name) +static void meta_test_fail(const char *name) { (void) name; mbedtls_test_fail("Forced test failure", __LINE__, __FILE__); } -void meta_test_not_equal(const char *name) +static void meta_test_not_equal(const char *name) { int left = 20; int right = 10; @@ -94,7 +94,7 @@ exit: ; } -void meta_test_not_le_s(const char *name) +static void meta_test_not_le_s(const char *name) { int left = 20; int right = 10; @@ -106,7 +106,7 @@ exit: ; } -void meta_test_not_le_u(const char *name) +static void meta_test_not_le_u(const char *name) { size_t left = 20; size_t right = 10; @@ -122,7 +122,7 @@ exit: /* Platform features */ /****************************************************************/ -void null_pointer_dereference(const char *name) +static void null_pointer_dereference(const char *name) { (void) name; volatile char *volatile p; @@ -131,7 +131,7 @@ void null_pointer_dereference(const char *name) mbedtls_printf("%p -> %u\n", p, (unsigned) *p); } -void null_pointer_call(const char *name) +static void null_pointer_call(const char *name) { (void) name; unsigned(*volatile p)(void); @@ -148,7 +148,7 @@ void null_pointer_call(const char *name) /* Memory */ /****************************************************************/ -void read_after_free(const char *name) +static void read_after_free(const char *name) { (void) name; volatile char *p = calloc_but_the_compiler_does_not_know(1, 1); @@ -158,7 +158,7 @@ void read_after_free(const char *name) mbedtls_printf("%u\n", (unsigned) *p); } -void double_free(const char *name) +static void double_free(const char *name) { (void) name; volatile char *p = calloc_but_the_compiler_does_not_know(1, 1); @@ -168,7 +168,7 @@ void double_free(const char *name) free_but_the_compiler_does_not_know((void *) p); } -void read_uninitialized_stack(const char *name) +static void read_uninitialized_stack(const char *name) { (void) name; char buf[1]; @@ -182,7 +182,7 @@ void read_uninitialized_stack(const char *name) } } -void memory_leak(const char *name) +static void memory_leak(const char *name) { (void) name; volatile char *p = calloc_but_the_compiler_does_not_know(1, 1); @@ -196,7 +196,7 @@ void memory_leak(const char *name) * %(start), %(offset) and %(count) are decimal integers. * %(direction) is either the character 'r' for read or 'w' for write. */ -void test_memory_poison(const char *name) +static void test_memory_poison(const char *name) { size_t start = 0, offset = 0, count = 0; char direction = 'r'; @@ -254,7 +254,7 @@ void test_memory_poison(const char *name) /* Threading */ /****************************************************************/ -void mutex_lock_not_initialized(const char *name) +static void mutex_lock_not_initialized(const char *name) { (void) name; #if defined(MBEDTLS_THREADING_C) @@ -270,7 +270,7 @@ exit: #endif } -void mutex_unlock_not_initialized(const char *name) +static void mutex_unlock_not_initialized(const char *name) { (void) name; #if defined(MBEDTLS_THREADING_C) @@ -286,7 +286,7 @@ exit: #endif } -void mutex_free_not_initialized(const char *name) +static void mutex_free_not_initialized(const char *name) { (void) name; #if defined(MBEDTLS_THREADING_C) @@ -300,7 +300,7 @@ void mutex_free_not_initialized(const char *name) #endif } -void mutex_double_init(const char *name) +static void mutex_double_init(const char *name) { (void) name; #if defined(MBEDTLS_THREADING_C) @@ -315,7 +315,7 @@ void mutex_double_init(const char *name) #endif } -void mutex_double_free(const char *name) +static void mutex_double_free(const char *name) { (void) name; #if defined(MBEDTLS_THREADING_C) @@ -330,7 +330,7 @@ void mutex_double_free(const char *name) #endif } -void mutex_leak(const char *name) +static void mutex_leak(const char *name) { (void) name; #if defined(MBEDTLS_THREADING_C) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index 043209b7ff..e72386f023 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -241,7 +241,7 @@ static void create_entropy_seed_file(void) } #endif -int mbedtls_entropy_self_test_wrapper(int verbose) +static int mbedtls_entropy_self_test_wrapper(int verbose) { #if defined(MBEDTLS_ENTROPY_NV_SEED) && !defined(MBEDTLS_NO_PLATFORM_ENTROPY) create_entropy_seed_file(); @@ -252,7 +252,7 @@ int mbedtls_entropy_self_test_wrapper(int verbose) #if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -int mbedtls_memory_buffer_alloc_free_and_self_test(int verbose) +static int mbedtls_memory_buffer_alloc_free_and_self_test(int verbose) { if (verbose != 0) { #if defined(MBEDTLS_MEMORY_DEBUG) diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c index beaa8bd5ea..bf06871319 100644 --- a/programs/test/udp_proxy.c +++ b/programs/test/udp_proxy.c @@ -483,7 +483,7 @@ typedef struct { } packet; /* Print packet. Outgoing packets come with a reason (forward, dupl, etc.) */ -void print_packet(const packet *p, const char *why) +static void print_packet(const packet *p, const char *why) { #if defined(MBEDTLS_TIMING_C) if (why == NULL) { @@ -527,7 +527,7 @@ typedef enum { static inject_clihlo_state_t inject_clihlo_state; static packet initial_clihlo; -int send_packet(const packet *p, const char *why) +static int send_packet(const packet *p, const char *why) { int ret; mbedtls_net_context *dst = p->dst; @@ -616,13 +616,13 @@ int send_packet(const packet *p, const char *why) static size_t prev_len; static packet prev[MAX_DELAYED_MSG]; -void clear_pending(void) +static void clear_pending(void) { memset(&prev, 0, sizeof(prev)); prev_len = 0; } -void delay_packet(packet *delay) +static void delay_packet(packet *delay) { if (prev_len == MAX_DELAYED_MSG) { return; @@ -631,7 +631,7 @@ void delay_packet(packet *delay) memcpy(&prev[prev_len++], delay, sizeof(packet)); } -int send_delayed(void) +static int send_delayed(void) { uint8_t offset; int ret; @@ -663,7 +663,7 @@ int send_delayed(void) static unsigned char held[2048] = { 0 }; #define HOLD_MAX 2 -int handle_message(const char *way, +static int handle_message(const char *way, mbedtls_net_context *dst, mbedtls_net_context *src) { diff --git a/programs/test/zeroize.c b/programs/test/zeroize.c index 1e9b98d71e..c1cee0d840 100644 --- a/programs/test/zeroize.c +++ b/programs/test/zeroize.c @@ -23,7 +23,7 @@ #define BUFFER_LEN 1024 -void usage(void) +static void usage(void) { mbedtls_printf("Zeroize is a simple program to assist with testing\n"); mbedtls_printf("the mbedtls_platform_zeroize() function by using the\n"); diff --git a/programs/util/pem2der.c b/programs/util/pem2der.c index d682c2b067..4d63478d75 100644 --- a/programs/util/pem2der.c +++ b/programs/util/pem2der.c @@ -45,7 +45,7 @@ struct options { const char *output_file; /* where to store the output */ } opt; -int convert_pem_to_der(const unsigned char *input, size_t ilen, +static int convert_pem_to_der(const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen) { int ret; diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c index dcfd1765c3..72d59b5687 100644 --- a/programs/x509/cert_req.c +++ b/programs/x509/cert_req.c @@ -107,7 +107,7 @@ struct options { mbedtls_md_type_t md_alg; /* Hash algorithm used for signature. */ } opt; -int write_certificate_request(mbedtls_x509write_csr *req, const char *output_file, +static int write_certificate_request(mbedtls_x509write_csr *req, const char *output_file, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c index 0b2575e84a..1aa1d0ffe8 100644 --- a/programs/x509/cert_write.c +++ b/programs/x509/cert_write.c @@ -204,7 +204,7 @@ struct options { int format; /* format */ } opt; -int write_certificate(mbedtls_x509write_cert *crt, const char *output_file, +static int write_certificate(mbedtls_x509write_cert *crt, const char *output_file, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { @@ -249,7 +249,7 @@ int write_certificate(mbedtls_x509write_cert *crt, const char *output_file, return 0; } -int parse_serial_decimal_format(unsigned char *obuf, size_t obufmax, +static int parse_serial_decimal_format(unsigned char *obuf, size_t obufmax, const char *ibuf, size_t *len) { unsigned long long int dec; diff --git a/programs/x509/load_roots.c b/programs/x509/load_roots.c index f0e6acf25a..d14537fd47 100644 --- a/programs/x509/load_roots.c +++ b/programs/x509/load_roots.c @@ -48,7 +48,7 @@ struct options { } opt; -int read_certificates(const char *const *filenames) +static int read_certificates(const char *const *filenames) { mbedtls_x509_crt cas; int ret = 0; From 82984bc1be603c7557e2b5d8defd95207d3797e6 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Wed, 12 Jun 2024 00:05:25 +0200 Subject: [PATCH 023/100] Adjust spacing in sample programs Signed-off-by: Michael Schuster --- programs/pkey/gen_key.c | 2 +- programs/ssl/ssl_client2.c | 2 +- programs/ssl/ssl_context_info.c | 4 +-- programs/ssl/ssl_server2.c | 20 ++++++------- programs/ssl/ssl_test_common_source.c | 42 +++++++++++++-------------- programs/test/udp_proxy.c | 4 +-- programs/util/pem2der.c | 2 +- programs/x509/cert_req.c | 24 +++++++-------- programs/x509/cert_write.c | 6 ++-- 9 files changed, 53 insertions(+), 53 deletions(-) diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c index 4ad162978b..83d7b71875 100644 --- a/programs/pkey/gen_key.c +++ b/programs/pkey/gen_key.c @@ -40,7 +40,7 @@ int main(void) #define DEV_RANDOM_THRESHOLD 32 static int dev_random_entropy_poll(void *data, unsigned char *output, - size_t len, size_t *olen) + size_t len, size_t *olen) { FILE *file; size_t ret, left = len; diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index bd0735ea9f..d494de3a60 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -598,7 +598,7 @@ static int my_verify(void *data, mbedtls_x509_crt *crt, #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) static int report_cid_usage(mbedtls_ssl_context *ssl, - const char *additional_description) + const char *additional_description) { int ret; unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX]; diff --git a/programs/ssl/ssl_context_info.c b/programs/ssl/ssl_context_info.c index 9577d2b900..51e87817ad 100644 --- a/programs/ssl/ssl_context_info.c +++ b/programs/ssl/ssl_context_info.c @@ -248,7 +248,7 @@ static void print_b64(const uint8_t *b, size_t len) * /p prefix prefix for the new lines */ static void print_hex(const uint8_t *b, size_t len, - const size_t in_line, const char *prefix) + const size_t in_line, const char *prefix) { size_t i = 0; const uint8_t *end = b + len; @@ -510,7 +510,7 @@ static void print_deserialized_ssl_cert(const uint8_t *ssl, uint32_t len) * /p session_cfg_flag session configuration flags */ static void print_deserialized_ssl_session(const uint8_t *ssl, uint32_t len, - int session_cfg_flag) + int session_cfg_flag) { const struct mbedtls_ssl_ciphersuite_t *ciphersuite_info; int ciphersuite_id; diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 8887ddeed5..32fcc0b62d 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -879,7 +879,7 @@ error: * SNI callback. */ static int sni_callback(void *p_info, mbedtls_ssl_context *ssl, - const unsigned char *name, size_t name_len) + const unsigned char *name, size_t name_len) { const sni_entry *cur = (const sni_entry *) p_info; @@ -1028,7 +1028,7 @@ error: * PSK callback */ static int psk_callback(void *p_info, mbedtls_ssl_context *ssl, - const unsigned char *name, size_t name_len) + const unsigned char *name, size_t name_len) { psk_entry *cur = (psk_entry *) p_info; @@ -1106,10 +1106,10 @@ typedef struct { } ssl_async_key_context_t; static int ssl_async_set_key(ssl_async_key_context_t *ctx, - mbedtls_x509_crt *cert, - mbedtls_pk_context *pk, - int pk_take_ownership, - unsigned delay) + mbedtls_x509_crt *cert, + mbedtls_pk_context *pk, + int pk_take_ownership, + unsigned delay) { if (ctx->slots_used >= sizeof(ctx->slots) / sizeof(*ctx->slots)) { return -1; @@ -1333,7 +1333,7 @@ static psa_status_t psa_setup_psk_key_slot(mbedtls_svc_key_id_t *slot, #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) static int report_cid_usage(mbedtls_ssl_context *ssl, - const char *additional_description) + const char *additional_description) { int ret; unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX]; @@ -1384,8 +1384,8 @@ static inline void put_unaligned_uint32(void *p, uint32_t x) /* Functions for session ticket tests */ static int dummy_ticket_write(void *p_ticket, const mbedtls_ssl_session *session, - unsigned char *start, const unsigned char *end, - size_t *tlen, uint32_t *ticket_lifetime) + unsigned char *start, const unsigned char *end, + size_t *tlen, uint32_t *ticket_lifetime) { int ret; unsigned char *p = start; @@ -1411,7 +1411,7 @@ static int dummy_ticket_write(void *p_ticket, const mbedtls_ssl_session *session } static int dummy_ticket_parse(void *p_ticket, mbedtls_ssl_session *session, - unsigned char *buf, size_t len) + unsigned char *buf, size_t len) { int ret; ((void) p_ticket); diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c index b339a39db8..ab41a0bf6d 100644 --- a/programs/ssl/ssl_test_common_source.c +++ b/programs/ssl/ssl_test_common_source.c @@ -13,12 +13,12 @@ */ static void eap_tls_key_derivation(void *p_expkey, - mbedtls_ssl_key_export_type secret_type, - const unsigned char *secret, - size_t secret_len, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type) + mbedtls_ssl_key_export_type secret_type, + const unsigned char *secret, + size_t secret_len, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type) { eap_tls_keys *keys = (eap_tls_keys *) p_expkey; @@ -37,12 +37,12 @@ static void eap_tls_key_derivation(void *p_expkey, } static void nss_keylog_export(void *p_expkey, - mbedtls_ssl_key_export_type secret_type, - const unsigned char *secret, - size_t secret_len, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type) + mbedtls_ssl_key_export_type secret_type, + const unsigned char *secret, + size_t secret_len, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type) { char nss_keylog_line[200]; size_t const client_random_len = 32; @@ -107,12 +107,12 @@ exit: #if defined(MBEDTLS_SSL_DTLS_SRTP) static void dtls_srtp_key_derivation(void *p_expkey, - mbedtls_ssl_key_export_type secret_type, - const unsigned char *secret, - size_t secret_len, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type) + mbedtls_ssl_key_export_type secret_type, + const unsigned char *secret, + size_t secret_len, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type) { dtls_srtp_keys *keys = (dtls_srtp_keys *) p_expkey; @@ -132,7 +132,7 @@ static void dtls_srtp_key_derivation(void *p_expkey, #endif /* MBEDTLS_SSL_DTLS_SRTP */ static int ssl_check_record(mbedtls_ssl_context const *ssl, - unsigned char const *buf, size_t len) + unsigned char const *buf, size_t len) { int my_ret = 0, ret_cr1, ret_cr2; unsigned char *tmp_buf; @@ -224,7 +224,7 @@ static int recv_cb(void *ctx, unsigned char *buf, size_t len) } static int recv_timeout_cb(void *ctx, unsigned char *buf, size_t len, - uint32_t timeout) + uint32_t timeout) { io_ctx_t *io_ctx = (io_ctx_t *) ctx; int ret; @@ -320,7 +320,7 @@ uint16_t ssl_sig_algs_for_test[] = { * for more info. */ static int x509_crt_verify_info(char *buf, size_t size, const char *prefix, - uint32_t flags) + uint32_t flags) { #if !defined(MBEDTLS_X509_REMOVE_INFO) return mbedtls_x509_crt_verify_info(buf, size, prefix, flags); diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c index bf06871319..7213f8aea0 100644 --- a/programs/test/udp_proxy.c +++ b/programs/test/udp_proxy.c @@ -664,8 +664,8 @@ static unsigned char held[2048] = { 0 }; #define HOLD_MAX 2 static int handle_message(const char *way, - mbedtls_net_context *dst, - mbedtls_net_context *src) + mbedtls_net_context *dst, + mbedtls_net_context *src) { int ret; packet cur; diff --git a/programs/util/pem2der.c b/programs/util/pem2der.c index 4d63478d75..177365b87c 100644 --- a/programs/util/pem2der.c +++ b/programs/util/pem2der.c @@ -46,7 +46,7 @@ struct options { } opt; static int convert_pem_to_der(const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen) + unsigned char *output, size_t *olen) { int ret; const unsigned char *s1, *s2, *end = input + ilen; diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c index 72d59b5687..995ee499d5 100644 --- a/programs/x509/cert_req.c +++ b/programs/x509/cert_req.c @@ -94,22 +94,22 @@ int main(void) * global options */ struct options { - const char *filename; /* filename of the key file */ - const char *password; /* password for the key file */ - int debug_level; /* level of debugging */ + const char *filename; /* filename of the key file */ + const char *password; /* password for the key file */ + int debug_level; /* level of debugging */ const char *output_file; /* where to store the constructed key file */ - const char *subject_name; /* subject name for certificate request */ - mbedtls_x509_san_list *san_list; /* subjectAltName for certificate request */ - unsigned char key_usage; /* key usage flags */ - int force_key_usage; /* Force adding the KeyUsage extension */ - unsigned char ns_cert_type; /* NS cert type */ - int force_ns_cert_type; /* Force adding NsCertType extension */ - mbedtls_md_type_t md_alg; /* Hash algorithm used for signature. */ + const char *subject_name; /* subject name for certificate request */ + mbedtls_x509_san_list *san_list; /* subjectAltName for certificate request */ + unsigned char key_usage; /* key usage flags */ + int force_key_usage; /* Force adding the KeyUsage extension */ + unsigned char ns_cert_type; /* NS cert type */ + int force_ns_cert_type; /* Force adding NsCertType extension */ + mbedtls_md_type_t md_alg; /* Hash algorithm used for signature. */ } opt; static int write_certificate_request(mbedtls_x509write_csr *req, const char *output_file, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) { int ret; FILE *f; diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c index 1aa1d0ffe8..6fd1dce1fc 100644 --- a/programs/x509/cert_write.c +++ b/programs/x509/cert_write.c @@ -205,8 +205,8 @@ struct options { } opt; static int write_certificate(mbedtls_x509write_cert *crt, const char *output_file, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) { int ret; FILE *f; @@ -250,7 +250,7 @@ static int write_certificate(mbedtls_x509write_cert *crt, const char *output_fil } static int parse_serial_decimal_format(unsigned char *obuf, size_t obufmax, - const char *ibuf, size_t *len) + const char *ibuf, size_t *len) { unsigned long long int dec; unsigned int remaining_bytes = sizeof(dec); From 8cc43f23b677ccdbccbb9ca352ac82a7ce5ddfd5 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Mon, 3 Jun 2024 19:45:34 +0200 Subject: [PATCH 024/100] Fix unused-function error for ecjpake_operation_setup in test_suite_psa_crypto.function This function is not referenced anywhere in the whole codebase. Signed-off-by: Michael Schuster --- tests/suites/test_suite_psa_crypto.function | 22 --------------------- 1 file changed, 22 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 0c8552bd55..85b2fd7567 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -39,28 +39,6 @@ #define ASSERT_OPERATION_IS_ACTIVE(operation) TEST_ASSERT(operation.id != 0) #define ASSERT_OPERATION_IS_INACTIVE(operation) TEST_ASSERT(operation.id == 0) -#if defined(PSA_WANT_ALG_JPAKE) -int ecjpake_operation_setup(psa_pake_operation_t *operation, - psa_pake_cipher_suite_t *cipher_suite, - psa_pake_role_t role, - mbedtls_svc_key_id_t key, - size_t key_available) -{ - PSA_ASSERT(psa_pake_abort(operation)); - - PSA_ASSERT(psa_pake_setup(operation, cipher_suite)); - - PSA_ASSERT(psa_pake_set_role(operation, role)); - - if (key_available) { - PSA_ASSERT(psa_pake_set_password_key(operation, key)); - } - return 0; -exit: - return 1; -} -#endif - /** An invalid export length that will never be set by psa_export_key(). */ static const size_t INVALID_EXPORT_LENGTH = ~0U; From b1e33fb707fc07d9602825351fc1ccff232d129e Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Tue, 4 Jun 2024 02:30:22 +0200 Subject: [PATCH 025/100] Fix missing-prototype errors in tests/suites Signed-off-by: Michael Schuster --- tests/src/test_helpers/ssl_helpers.c | 4 ++-- tests/suites/host_test.function | 8 +++---- tests/suites/main_test.function | 8 +++---- tests/suites/test_suite_alignment.function | 2 +- tests/suites/test_suite_asn1parse.function | 2 +- tests/suites/test_suite_asn1write.function | 4 ++-- tests/suites/test_suite_bignum.function | 2 +- tests/suites/test_suite_cipher.function | 2 +- tests/suites/test_suite_common.function | 2 +- tests/suites/test_suite_ctr_drbg.function | 1 + tests/suites/test_suite_debug.function | 2 +- tests/suites/test_suite_dhm.function | 2 +- tests/suites/test_suite_entropy.function | 6 ++--- tests/suites/test_suite_lmots.function | 2 +- tests/suites/test_suite_pk.function | 12 +++++----- tests/suites/test_suite_pkcs7.function | 2 +- tests/suites/test_suite_platform.function | 2 +- tests/suites/test_suite_psa_crypto.function | 10 ++++---- .../test_suite_psa_crypto_metadata.function | 10 ++++---- ...st_suite_psa_crypto_se_driver_hal.function | 2 +- ...te_psa_crypto_se_driver_hal_mocks.function | 12 +++++----- tests/suites/test_suite_x509parse.function | 24 +++++++++---------- tests/suites/test_suite_x509write.function | 6 ++--- 23 files changed, 64 insertions(+), 63 deletions(-) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 16fa38a172..21dcdec45d 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -950,7 +950,7 @@ int mbedtls_test_move_handshake_to_state(mbedtls_ssl_context *ssl, /* * Write application data. Increase write counter if necessary. */ -int mbedtls_ssl_write_fragment(mbedtls_ssl_context *ssl, +static int mbedtls_ssl_write_fragment(mbedtls_ssl_context *ssl, unsigned char *buf, int buf_len, int *written, const int expected_fragments) @@ -997,7 +997,7 @@ exit: * Read application data and increase read counter and fragments counter * if necessary. */ -int mbedtls_ssl_read_fragment(mbedtls_ssl_context *ssl, +static int mbedtls_ssl_read_fragment(mbedtls_ssl_context *ssl, unsigned char *buf, int buf_len, int *read, int *fragments, const int expected_fragments) diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function index eb42a07eba..d28a75e077 100644 --- a/tests/suites/host_test.function +++ b/tests/suites/host_test.function @@ -8,7 +8,7 @@ * * \return 0 if success else 1 */ -int verify_string(char **str) +static int verify_string(char **str) { if ((*str)[0] != '"' || (*str)[strlen(*str) - 1] != '"') { @@ -32,7 +32,7 @@ int verify_string(char **str) * * \return 0 if success else 1 */ -int verify_int(char *str, intmax_t *p_value) +static int verify_int(char *str, intmax_t *p_value) { char *end = NULL; errno = 0; @@ -80,7 +80,7 @@ int verify_int(char *str, intmax_t *p_value) * * \return 0 if success else -1 */ -int get_line(FILE *f, char *buf, size_t len) +static int get_line(FILE *f, char *buf, size_t len) { char *ret; int i = 0, str_len = 0, has_string = 0; @@ -485,7 +485,7 @@ static void try_chdir_if_supported(const char *argv0) * * \return Program exit status. */ -int execute_tests(int argc, const char **argv) +static int execute_tests(int argc, const char **argv) { /* Local Configurations and options */ const char *default_filename = "DATA_FILE"; diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function index f327a03783..c0cc2ac50b 100644 --- a/tests/suites/main_test.function +++ b/tests/suites/main_test.function @@ -69,7 +69,7 @@ __MBEDTLS_TEST_TEMPLATE__FUNCTIONS_CODE * * \return 0 if exp_id is found. 1 otherwise. */ -int get_expression(int32_t exp_id, intmax_t *out_value) +static int get_expression(int32_t exp_id, intmax_t *out_value) { int ret = KEY_VALUE_MAPPING_FOUND; @@ -100,7 +100,7 @@ int get_expression(int32_t exp_id, intmax_t *out_value) * * \return DEPENDENCY_SUPPORTED if set else DEPENDENCY_NOT_SUPPORTED */ -int dep_check(int dep_id) +static int dep_check(int dep_id) { int ret = DEPENDENCY_NOT_SUPPORTED; @@ -155,7 +155,7 @@ TestWrapper_t test_funcs[] = * DISPATCH_TEST_FN_NOT_FOUND if not found * DISPATCH_UNSUPPORTED_SUITE if not compile time enabled. */ -int dispatch_test(size_t func_idx, void **params) +static int dispatch_test(size_t func_idx, void **params) { int ret = DISPATCH_TEST_SUCCESS; TestWrapper_t fp = NULL; @@ -193,7 +193,7 @@ int dispatch_test(size_t func_idx, void **params) * DISPATCH_TEST_FN_NOT_FOUND if not found * DISPATCH_UNSUPPORTED_SUITE if not compile time enabled. */ -int check_test(size_t func_idx) +static int check_test(size_t func_idx) { int ret = DISPATCH_TEST_SUCCESS; TestWrapper_t fp = NULL; diff --git a/tests/suites/test_suite_alignment.function b/tests/suites/test_suite_alignment.function index 842101fc92..240f55211e 100644 --- a/tests/suites/test_suite_alignment.function +++ b/tests/suites/test_suite_alignment.function @@ -10,7 +10,7 @@ /* * Convert a string of the form "abcd" (case-insensitive) to a uint64_t. */ -int parse_hex_string(char *hex_string, uint64_t *result) +static int parse_hex_string(char *hex_string, uint64_t *result) { uint8_t raw[8] = { 0 }; size_t olen; diff --git a/tests/suites/test_suite_asn1parse.function b/tests/suites/test_suite_asn1parse.function index 01a091b06c..394d08a27b 100644 --- a/tests/suites/test_suite_asn1parse.function +++ b/tests/suites/test_suite_asn1parse.function @@ -122,7 +122,7 @@ exit: return ERR_PARSE_INCONSISTENCY; } -int get_len_step(const data_t *input, size_t buffer_size, +static int get_len_step(const data_t *input, size_t buffer_size, size_t actual_length) { unsigned char *buf = NULL; diff --git a/tests/suites/test_suite_asn1write.function b/tests/suites/test_suite_asn1write.function index 469b971c7d..d332485910 100644 --- a/tests/suites/test_suite_asn1write.function +++ b/tests/suites/test_suite_asn1write.function @@ -12,7 +12,7 @@ typedef struct { size_t size; } generic_write_data_t; -int generic_write_start_step(generic_write_data_t *data) +static int generic_write_start_step(generic_write_data_t *data) { mbedtls_test_set_step(data->size); mbedtls_free(data->output); @@ -26,7 +26,7 @@ exit: return 0; } -int generic_write_finish_step(generic_write_data_t *data, +static int generic_write_finish_step(generic_write_data_t *data, const data_t *expected, int ret) { int ok = 0; diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function index f3a64e1837..22a637a504 100644 --- a/tests/suites/test_suite_bignum.function +++ b/tests/suites/test_suite_bignum.function @@ -44,7 +44,7 @@ typedef struct mbedtls_test_mpi_random { * test) are stored in the data member of the state structure. Each number is in * the format that mbedtls_mpi_read_string understands and is chunk_len long. */ -int mbedtls_test_mpi_miller_rabin_determinizer(void *state, +static int mbedtls_test_mpi_miller_rabin_determinizer(void *state, unsigned char *buf, size_t len) { diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function index 8e49d2d3b5..040c35ca58 100644 --- a/tests/suites/test_suite_cipher.function +++ b/tests/suites/test_suite_cipher.function @@ -129,7 +129,7 @@ exit: * return 1 if it is, * 0 if it isn't. */ -int buffer_is_all_zero(const uint8_t *buf, size_t size) +static int buffer_is_all_zero(const uint8_t *buf, size_t size) { for (size_t i = 0; i < size; i++) { if (buf[i] != 0) { diff --git a/tests/suites/test_suite_common.function b/tests/suites/test_suite_common.function index 5c5700c25b..c508b11998 100644 --- a/tests/suites/test_suite_common.function +++ b/tests/suites/test_suite_common.function @@ -1,7 +1,7 @@ /* BEGIN_HEADER */ #include "common.h" -void fill_arrays(unsigned char *a, unsigned char *b, unsigned char *r1, unsigned char *r2, size_t n) +static void fill_arrays(unsigned char *a, unsigned char *b, unsigned char *r1, unsigned char *r2, size_t n) { for (size_t i = 0; i < n; i++) { a[i] = (unsigned char) i * 3; diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index 720eb3e08d..9fa55a754b 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -96,6 +96,7 @@ exit: } static const int thread_random_reps = 10; +void *thread_random_function(void *ctx); /* only used conditionally in ctr_drbg_threads */ void *thread_random_function(void *ctx) { unsigned char out[16]; diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function index 70e7badca5..878ceed574 100644 --- a/tests/suites/test_suite_debug.function +++ b/tests/suites/test_suite_debug.function @@ -9,7 +9,7 @@ struct buffer_data { char *ptr; }; -void string_debug(void *data, int level, const char *file, int line, const char *str) +static void string_debug(void *data, int level, const char *file, int line, const char *str) { struct buffer_data *buffer = (struct buffer_data *) data; char *p = buffer->ptr; diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function index 20905940ba..a7b4b407b0 100644 --- a/tests/suites/test_suite_dhm.function +++ b/tests/suites/test_suite_dhm.function @@ -1,7 +1,7 @@ /* BEGIN_HEADER */ #include "mbedtls/dhm.h" -int check_get_value(const mbedtls_dhm_context *ctx, +static int check_get_value(const mbedtls_dhm_context *ctx, mbedtls_dhm_parameter param, const mbedtls_mpi *expected) { diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function index 5ac65fcf5e..c89c26c637 100644 --- a/tests/suites/test_suite_entropy.function +++ b/tests/suites/test_suite_entropy.function @@ -65,7 +65,7 @@ static void entropy_clear_sources(mbedtls_entropy_context *ctx) */ static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE]; -int buffer_nv_seed_read(unsigned char *buf, size_t buf_len) +static int buffer_nv_seed_read(unsigned char *buf, size_t buf_len) { if (buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE) { return -1; @@ -75,7 +75,7 @@ int buffer_nv_seed_read(unsigned char *buf, size_t buf_len) return 0; } -int buffer_nv_seed_write(unsigned char *buf, size_t buf_len) +static int buffer_nv_seed_write(unsigned char *buf, size_t buf_len) { if (buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE) { return -1; @@ -111,7 +111,7 @@ static int write_nv_seed(unsigned char *buf, size_t buf_len) return 0; } -int read_nv_seed(unsigned char *buf, size_t buf_len) +static int read_nv_seed(unsigned char *buf, size_t buf_len) { FILE *f; diff --git a/tests/suites/test_suite_lmots.function b/tests/suites/test_suite_lmots.function index 293287aab9..61f2e28617 100644 --- a/tests/suites/test_suite_lmots.function +++ b/tests/suites/test_suite_lmots.function @@ -3,7 +3,7 @@ #include "mbedtls/lms.h" #if defined(MBEDTLS_TEST_HOOKS) -int check_lmots_private_key_for_leak(unsigned char *sig) +static int check_lmots_private_key_for_leak(unsigned char *sig) { size_t idx; diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 38c27e399e..c102f93b19 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -221,7 +221,7 @@ exit: } #if defined(MBEDTLS_PSA_CRYPTO_C) -psa_status_t pk_psa_import_key(const unsigned char *key_data, size_t key_len, +static psa_status_t pk_psa_import_key(const unsigned char *key_data, size_t key_len, psa_key_type_t type, psa_key_usage_t usage, psa_algorithm_t alg, mbedtls_svc_key_id_t *key) { @@ -320,7 +320,7 @@ exit: * for volatile keys. * \param[out] key Identifier of the "generated" (actually imported) PSA key. */ -psa_status_t pk_psa_setup(psa_key_type_t type, size_t bits, +static psa_status_t pk_psa_setup(psa_key_type_t type, size_t bits, psa_key_usage_t usage, psa_algorithm_t alg, psa_algorithm_t enrollment_alg, mbedtls_svc_key_id_t persistent_key_id, @@ -468,7 +468,7 @@ exit: #endif /* MBEDTLS_PSA_CRYPTO_C */ #if defined(MBEDTLS_RSA_C) -int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen, +static int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len) { @@ -476,7 +476,7 @@ int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen, mbedtls_test_rnd_std_rand, NULL, olen, input, output, output_max_len); } -int mbedtls_rsa_sign_func(void *ctx, +static int mbedtls_rsa_sign_func(void *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig) @@ -487,7 +487,7 @@ int mbedtls_rsa_sign_func(void *ctx, mbedtls_test_rnd_std_rand, NULL, md_alg, hashlen, hash, sig); } -size_t mbedtls_rsa_key_len_func(void *ctx) +static size_t mbedtls_rsa_key_len_func(void *ctx) { return ((const mbedtls_rsa_context *) ctx)->len; } @@ -618,7 +618,7 @@ exit: /* Create a copy of a PSA key with same usage and algorithm policy and destroy * the original one. */ -mbedtls_svc_key_id_t psa_copy_and_destroy(mbedtls_svc_key_id_t orig_key_id) +static mbedtls_svc_key_id_t psa_copy_and_destroy(mbedtls_svc_key_id_t orig_key_id) { psa_key_attributes_t orig_attr = PSA_KEY_ATTRIBUTES_INIT; psa_key_attributes_t new_attr = PSA_KEY_ATTRIBUTES_INIT; diff --git a/tests/suites/test_suite_pkcs7.function b/tests/suites/test_suite_pkcs7.function index 4c8bf233ef..e5dc4bd192 100644 --- a/tests/suites/test_suite_pkcs7.function +++ b/tests/suites/test_suite_pkcs7.function @@ -17,7 +17,7 @@ * END_DEPENDENCIES */ /* BEGIN_SUITE_HELPERS */ -int pkcs7_parse_buffer(unsigned char *pkcs7_buf, int buflen) +static int pkcs7_parse_buffer(unsigned char *pkcs7_buf, int buflen) { int res; mbedtls_pkcs7 pkcs7; diff --git a/tests/suites/test_suite_platform.function b/tests/suites/test_suite_platform.function index c65d011f0f..5d49e52e45 100644 --- a/tests/suites/test_suite_platform.function +++ b/tests/suites/test_suite_platform.function @@ -18,7 +18,7 @@ #else #include #endif -void sleep_ms(int milliseconds) +static void sleep_ms(int milliseconds) { #if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ defined(__MINGW32__) || defined(_WIN64) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 85b2fd7567..144c2e54c0 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -153,7 +153,7 @@ static int construct_fake_rsa_key(unsigned char *buffer, } #endif /* MBEDTLS_ASN1_WRITE_C */ -int exercise_mac_setup(psa_key_type_t key_type, +static int exercise_mac_setup(psa_key_type_t key_type, const unsigned char *key_bytes, size_t key_length, psa_algorithm_t alg, @@ -185,7 +185,7 @@ exit: return 0; } -int exercise_cipher_setup(psa_key_type_t key_type, +static int exercise_cipher_setup(psa_key_type_t key_type, const unsigned char *key_bytes, size_t key_length, psa_algorithm_t alg, @@ -1332,7 +1332,7 @@ same_key_context; /* Attempt to import the key in ctx. This handles any valid error codes * and reports an error for any invalid codes. This function also insures * that once imported by some thread, all threads can use the key. */ -void *thread_import_key(void *ctx) +static void *thread_import_key(void *ctx) { mbedtls_svc_key_id_t returned_key_id; same_key_context *skc = (struct same_key_context *) ctx; @@ -1406,7 +1406,7 @@ exit: return NULL; } -void *thread_use_and_destroy_key(void *ctx) +static void *thread_use_and_destroy_key(void *ctx) { same_key_context *skc = (struct same_key_context *) ctx; @@ -1446,7 +1446,7 @@ typedef struct generate_key_context { int reps; } generate_key_context; -void *thread_generate_key(void *ctx) +static void *thread_generate_key(void *ctx) { mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT; diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function index b51f2a28b7..d299794323 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.function +++ b/tests/suites/test_suite_psa_crypto_metadata.function @@ -106,7 +106,7 @@ * The expected parity is even so that 0 is considered a valid encoding. * * Return a nonzero value if value has even parity and 0 otherwise. */ -int has_even_parity(uint32_t value) +static int has_even_parity(uint32_t value) { value ^= value >> 16; value ^= value >> 8; @@ -116,7 +116,7 @@ int has_even_parity(uint32_t value) #define TEST_PARITY(value) \ TEST_ASSERT(has_even_parity(value)) -void algorithm_classification(psa_algorithm_t alg, unsigned flags) +static void algorithm_classification(psa_algorithm_t alg, unsigned flags) { unsigned classification_flags_tested = 0; TEST_CLASSIFICATION_MACRO(1, ALG_IS_VENDOR_DEFINED, alg, flags); @@ -155,7 +155,7 @@ void algorithm_classification(psa_algorithm_t alg, unsigned flags) exit:; } -void key_type_classification(psa_key_type_t type, unsigned flags) +static void key_type_classification(psa_key_type_t type, unsigned flags) { unsigned classification_flags_tested = 0; @@ -192,7 +192,7 @@ void key_type_classification(psa_key_type_t type, unsigned flags) exit:; } -void mac_algorithm_core(psa_algorithm_t alg, int classification_flags, +static void mac_algorithm_core(psa_algorithm_t alg, int classification_flags, psa_key_type_t key_type, size_t key_bits, size_t length) { @@ -218,7 +218,7 @@ void mac_algorithm_core(psa_algorithm_t alg, int classification_flags, exit:; } -void aead_algorithm_core(psa_algorithm_t alg, int classification_flags, +static void aead_algorithm_core(psa_algorithm_t alg, int classification_flags, psa_key_type_t key_type, size_t key_bits, size_t tag_length) { diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function index 37a72d9d75..96be55bcda 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function @@ -599,7 +599,7 @@ exit: * If this changes, the storage format version must change. * See psa_get_se_driver_its_file_uid() in psa_crypto_se.c. */ -psa_storage_uid_t file_uid_for_location(psa_key_location_t location) +static psa_storage_uid_t file_uid_for_location(psa_key_location_t location) { if (location > PSA_MAX_SE_LOCATION) { return 0; diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function index b6d3a3487d..9480bd4296 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function @@ -162,7 +162,7 @@ static psa_status_t mock_import(psa_drv_se_context_t *drv_context, return mock_import_data.return_value; } -psa_status_t mock_export(psa_drv_se_context_t *context, +static psa_status_t mock_export(psa_drv_se_context_t *context, psa_key_slot_number_t slot_number, uint8_t *p_data, size_t data_size, @@ -179,7 +179,7 @@ psa_status_t mock_export(psa_drv_se_context_t *context, return mock_export_data.return_value; } -psa_status_t mock_export_public(psa_drv_se_context_t *context, +static psa_status_t mock_export_public(psa_drv_se_context_t *context, psa_key_slot_number_t slot_number, uint8_t *p_data, size_t data_size, @@ -196,7 +196,7 @@ psa_status_t mock_export_public(psa_drv_se_context_t *context, return mock_export_public_data.return_value; } -psa_status_t mock_sign(psa_drv_se_context_t *context, +static psa_status_t mock_sign(psa_drv_se_context_t *context, psa_key_slot_number_t key_slot, psa_algorithm_t alg, const uint8_t *p_hash, @@ -219,7 +219,7 @@ psa_status_t mock_sign(psa_drv_se_context_t *context, return mock_sign_data.return_value; } -psa_status_t mock_verify(psa_drv_se_context_t *context, +static psa_status_t mock_verify(psa_drv_se_context_t *context, psa_key_slot_number_t key_slot, psa_algorithm_t alg, const uint8_t *p_hash, @@ -240,7 +240,7 @@ psa_status_t mock_verify(psa_drv_se_context_t *context, return mock_verify_data.return_value; } -psa_status_t mock_allocate(psa_drv_se_context_t *drv_context, +static psa_status_t mock_allocate(psa_drv_se_context_t *drv_context, void *persistent_data, const psa_key_attributes_t *attributes, psa_key_creation_method_t method, @@ -258,7 +258,7 @@ psa_status_t mock_allocate(psa_drv_se_context_t *drv_context, return mock_allocate_data.return_value; } -psa_status_t mock_destroy(psa_drv_se_context_t *context, +static psa_status_t mock_destroy(psa_drv_se_context_t *context, void *persistent_data, psa_key_slot_number_t slot_number) { diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index ba71c8f80c..e72a6e377e 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -60,7 +60,7 @@ const mbedtls_x509_crt_profile profile_sha512 = 1024, }; -int verify_none(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) +static int verify_none(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) { ((void) data); ((void) crt); @@ -70,7 +70,7 @@ int verify_none(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32 return 0; } -int verify_all(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) +static int verify_all(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) { ((void) data); ((void) crt); @@ -81,7 +81,7 @@ int verify_all(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_ } #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -int ca_callback_fail(void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates) +static int ca_callback_fail(void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates) { ((void) data); ((void) child); @@ -90,7 +90,7 @@ int ca_callback_fail(void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt return -1; } #if defined(MBEDTLS_X509_CRT_PARSE_C) -int ca_callback(void *data, mbedtls_x509_crt const *child, +static int ca_callback(void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates) { int ret = 0; @@ -141,7 +141,7 @@ exit: #endif /* MBEDTLS_X509_CRT_PARSE_C */ #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -int verify_fatal(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) +static int verify_fatal(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) { int *levels = (int *) data; @@ -158,7 +158,7 @@ int verify_fatal(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint3 } /* strsep() not available on Windows */ -char *mystrsep(char **stringp, const char *delim) +static char *mystrsep(char **stringp, const char *delim) { const char *p; char *ret = *stringp; @@ -192,13 +192,13 @@ typedef struct { char *p; } verify_print_context; -void verify_print_init(verify_print_context *ctx) +static void verify_print_init(verify_print_context *ctx) { memset(ctx, 0, sizeof(verify_print_context)); ctx->p = ctx->buf; } -int verify_print(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) +static int verify_print(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) { int ret; verify_print_context *ctx = (verify_print_context *) data; @@ -226,7 +226,7 @@ int verify_print(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint3 return 0; } -int verify_parse_san(mbedtls_x509_subject_alternative_name *san, +static int verify_parse_san(mbedtls_x509_subject_alternative_name *san, char **buf, size_t *size) { int ret; @@ -317,7 +317,7 @@ int verify_parse_san(mbedtls_x509_subject_alternative_name *san, return 0; } -int parse_crt_ext_cb(void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x509_buf const *oid, +static int parse_crt_ext_cb(void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x509_buf const *oid, int critical, const unsigned char *cp, const unsigned char *end) { (void) crt; @@ -417,7 +417,7 @@ int parse_crt_ext_cb(void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x509_buf #endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_X509_CSR_PARSE_C) -int parse_csr_ext_accept_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbedtls_x509_buf const *oid, +static int parse_csr_ext_accept_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbedtls_x509_buf const *oid, int critical, const unsigned char *cp, const unsigned char *end) { (void) p_ctx; @@ -430,7 +430,7 @@ int parse_csr_ext_accept_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbedtls_x5 return 0; } -int parse_csr_ext_reject_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbedtls_x509_buf const *oid, +static int parse_csr_ext_reject_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbedtls_x509_buf const *oid, int critical, const unsigned char *cp, const unsigned char *end) { (void) p_ctx; diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index 1db7e1cff2..820b48dfe8 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -11,14 +11,14 @@ #include "mbedtls/psa_util.h" #if defined(MBEDTLS_RSA_C) -int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen, +static int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len) { return mbedtls_rsa_pkcs1_decrypt((mbedtls_rsa_context *) ctx, NULL, NULL, olen, input, output, output_max_len); } -int mbedtls_rsa_sign_func(void *ctx, +static int mbedtls_rsa_sign_func(void *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig) @@ -26,7 +26,7 @@ int mbedtls_rsa_sign_func(void *ctx, return mbedtls_rsa_pkcs1_sign((mbedtls_rsa_context *) ctx, f_rng, p_rng, md_alg, hashlen, hash, sig); } -size_t mbedtls_rsa_key_len_func(void *ctx) +static size_t mbedtls_rsa_key_len_func(void *ctx) { return ((const mbedtls_rsa_context *) ctx)->len; } From 31b1cb860141a6bbd8f4e217aaaf490253b87f8c Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Tue, 4 Jun 2024 02:41:10 +0200 Subject: [PATCH 026/100] Adjust spacing in tests/suites function sources Signed-off-by: Michael Schuster --- tests/src/test_helpers/ssl_helpers.c | 12 ++-- tests/suites/helpers.function | 4 +- tests/suites/test_suite_asn1parse.function | 2 +- tests/suites/test_suite_asn1write.function | 2 +- tests/suites/test_suite_bignum.function | 4 +- tests/suites/test_suite_dhm.function | 4 +- tests/suites/test_suite_pk.function | 22 ++++---- tests/suites/test_suite_psa_crypto.function | 32 +++++------ .../test_suite_psa_crypto_metadata.function | 20 +++---- .../test_suite_psa_crypto_op_fail.function | 8 +-- .../test_suite_psa_crypto_pake.function | 34 +++++------ ...st_suite_psa_crypto_se_driver_hal.function | 52 ++++++++--------- ...te_psa_crypto_se_driver_hal_mocks.function | 56 +++++++++---------- tests/suites/test_suite_psa_its.function | 10 ++-- tests/suites/test_suite_ssl.function | 16 +++--- tests/suites/test_suite_x509parse.function | 10 ++-- tests/suites/test_suite_x509write.function | 10 ++-- 17 files changed, 149 insertions(+), 149 deletions(-) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 21dcdec45d..f546e76021 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -951,9 +951,9 @@ int mbedtls_test_move_handshake_to_state(mbedtls_ssl_context *ssl, * Write application data. Increase write counter if necessary. */ static int mbedtls_ssl_write_fragment(mbedtls_ssl_context *ssl, - unsigned char *buf, int buf_len, - int *written, - const int expected_fragments) + unsigned char *buf, int buf_len, + int *written, + const int expected_fragments) { int ret; /* Verify that calling mbedtls_ssl_write with a NULL buffer and zero length is @@ -998,9 +998,9 @@ exit: * if necessary. */ static int mbedtls_ssl_read_fragment(mbedtls_ssl_context *ssl, - unsigned char *buf, int buf_len, - int *read, int *fragments, - const int expected_fragments) + unsigned char *buf, int buf_len, + int *read, int *fragments, + const int expected_fragments) { int ret; /* Verify that calling mbedtls_ssl_write with a NULL buffer and zero length is diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function index b5f5796e42..b561f4766a 100644 --- a/tests/suites/helpers.function +++ b/tests/suites/helpers.function @@ -55,8 +55,8 @@ /* Indicates whether we expect mbedtls_entropy_init * to initialize some strong entropy source. */ #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) && \ - (!defined(MBEDTLS_NO_PLATFORM_ENTROPY) || \ - defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ + (!defined(MBEDTLS_NO_PLATFORM_ENTROPY) || \ + defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ defined(ENTROPY_NV_SEED)) #define ENTROPY_HAVE_STRONG #endif diff --git a/tests/suites/test_suite_asn1parse.function b/tests/suites/test_suite_asn1parse.function index 394d08a27b..123da5a784 100644 --- a/tests/suites/test_suite_asn1parse.function +++ b/tests/suites/test_suite_asn1parse.function @@ -123,7 +123,7 @@ exit: } static int get_len_step(const data_t *input, size_t buffer_size, - size_t actual_length) + size_t actual_length) { unsigned char *buf = NULL; unsigned char *p = NULL; diff --git a/tests/suites/test_suite_asn1write.function b/tests/suites/test_suite_asn1write.function index d332485910..f5fc025f7d 100644 --- a/tests/suites/test_suite_asn1write.function +++ b/tests/suites/test_suite_asn1write.function @@ -27,7 +27,7 @@ exit: } static int generic_write_finish_step(generic_write_data_t *data, - const data_t *expected, int ret) + const data_t *expected, int ret) { int ok = 0; diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function index 22a637a504..7cbbbe87f7 100644 --- a/tests/suites/test_suite_bignum.function +++ b/tests/suites/test_suite_bignum.function @@ -45,8 +45,8 @@ typedef struct mbedtls_test_mpi_random { * the format that mbedtls_mpi_read_string understands and is chunk_len long. */ static int mbedtls_test_mpi_miller_rabin_determinizer(void *state, - unsigned char *buf, - size_t len) + unsigned char *buf, + size_t len) { mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random *) state; diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function index a7b4b407b0..bb64ef320f 100644 --- a/tests/suites/test_suite_dhm.function +++ b/tests/suites/test_suite_dhm.function @@ -2,8 +2,8 @@ #include "mbedtls/dhm.h" static int check_get_value(const mbedtls_dhm_context *ctx, - mbedtls_dhm_parameter param, - const mbedtls_mpi *expected) + mbedtls_dhm_parameter param, + const mbedtls_mpi *expected) { mbedtls_mpi actual; int ok = 0; diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index c102f93b19..0cff121fbe 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -222,8 +222,8 @@ exit: #if defined(MBEDTLS_PSA_CRYPTO_C) static psa_status_t pk_psa_import_key(const unsigned char *key_data, size_t key_len, - psa_key_type_t type, psa_key_usage_t usage, - psa_algorithm_t alg, mbedtls_svc_key_id_t *key) + psa_key_type_t type, psa_key_usage_t usage, + psa_algorithm_t alg, mbedtls_svc_key_id_t *key) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_status_t status; @@ -321,10 +321,10 @@ exit: * \param[out] key Identifier of the "generated" (actually imported) PSA key. */ static psa_status_t pk_psa_setup(psa_key_type_t type, size_t bits, - psa_key_usage_t usage, psa_algorithm_t alg, - psa_algorithm_t enrollment_alg, - mbedtls_svc_key_id_t persistent_key_id, - mbedtls_svc_key_id_t *key) + psa_key_usage_t usage, psa_algorithm_t alg, + psa_algorithm_t enrollment_alg, + mbedtls_svc_key_id_t persistent_key_id, + mbedtls_svc_key_id_t *key) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_status_t status = PSA_ERROR_GENERIC_ERROR; @@ -469,17 +469,17 @@ exit: #if defined(MBEDTLS_RSA_C) static int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen, - const unsigned char *input, unsigned char *output, - size_t output_max_len) + const unsigned char *input, unsigned char *output, + size_t output_max_len) { return mbedtls_rsa_pkcs1_decrypt((mbedtls_rsa_context *) ctx, mbedtls_test_rnd_std_rand, NULL, olen, input, output, output_max_len); } static int mbedtls_rsa_sign_func(void *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_md_type_t md_alg, unsigned int hashlen, - const unsigned char *hash, unsigned char *sig) + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_md_type_t md_alg, unsigned int hashlen, + const unsigned char *hash, unsigned char *sig) { ((void) f_rng); ((void) p_rng); diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 144c2e54c0..3841ac6c23 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -154,11 +154,11 @@ static int construct_fake_rsa_key(unsigned char *buffer, #endif /* MBEDTLS_ASN1_WRITE_C */ static int exercise_mac_setup(psa_key_type_t key_type, - const unsigned char *key_bytes, - size_t key_length, - psa_algorithm_t alg, - psa_mac_operation_t *operation, - psa_status_t *status) + const unsigned char *key_bytes, + size_t key_length, + psa_algorithm_t alg, + psa_mac_operation_t *operation, + psa_status_t *status) { mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -186,11 +186,11 @@ exit: } static int exercise_cipher_setup(psa_key_type_t key_type, - const unsigned char *key_bytes, - size_t key_length, - psa_algorithm_t alg, - psa_cipher_operation_t *operation, - psa_status_t *status) + const unsigned char *key_bytes, + size_t key_length, + psa_algorithm_t alg, + psa_cipher_operation_t *operation, + psa_status_t *status) { mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -263,14 +263,14 @@ exit: /* Assert that a key isn't reported as having a slot number. */ #if defined(MBEDTLS_PSA_CRYPTO_SE_C) #define ASSERT_NO_SLOT_NUMBER(attributes) \ - do \ - { \ - psa_key_slot_number_t ASSERT_NO_SLOT_NUMBER_slot_number; \ - TEST_EQUAL(psa_get_key_slot_number( \ - attributes, \ + do \ + { \ + psa_key_slot_number_t ASSERT_NO_SLOT_NUMBER_slot_number; \ + TEST_EQUAL(psa_get_key_slot_number( \ + attributes, \ &ASSERT_NO_SLOT_NUMBER_slot_number), \ PSA_ERROR_INVALID_ARGUMENT); \ - } \ + } \ while (0) #else /* MBEDTLS_PSA_CRYPTO_SE_C */ #define ASSERT_NO_SLOT_NUMBER(attributes) \ diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function index d299794323..3b5bf66cdb 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.function +++ b/tests/suites/test_suite_psa_crypto_metadata.function @@ -80,17 +80,17 @@ * Unconditionally mask flag into the ambient variable * classification_flags_tested. */ -#define TEST_CLASSIFICATION_MACRO(cond, flag, alg, flags) \ +#define TEST_CLASSIFICATION_MACRO(cond, flag, alg, flags) \ do \ { \ - if (cond) \ + if (cond) \ { \ - if ((flags) & (flag)) \ - TEST_ASSERT(PSA_##flag(alg)); \ + if ((flags) & (flag)) \ + TEST_ASSERT(PSA_##flag(alg)); \ else \ - TEST_ASSERT(!PSA_##flag(alg)); \ + TEST_ASSERT(!PSA_##flag(alg)); \ } \ - classification_flags_tested |= (flag); \ + classification_flags_tested |= (flag); \ } \ while (0) @@ -193,8 +193,8 @@ exit:; } static void mac_algorithm_core(psa_algorithm_t alg, int classification_flags, - psa_key_type_t key_type, size_t key_bits, - size_t length) + psa_key_type_t key_type, size_t key_bits, + size_t length) { /* Algorithm classification */ TEST_ASSERT(!PSA_ALG_IS_HASH(alg)); @@ -219,8 +219,8 @@ exit:; } static void aead_algorithm_core(psa_algorithm_t alg, int classification_flags, - psa_key_type_t key_type, size_t key_bits, - size_t tag_length) + psa_key_type_t key_type, size_t key_bits, + size_t tag_length) { /* Algorithm classification */ TEST_ASSERT(!PSA_ALG_IS_HASH(alg)); diff --git a/tests/suites/test_suite_psa_crypto_op_fail.function b/tests/suites/test_suite_psa_crypto_op_fail.function index 9878237211..928986933a 100644 --- a/tests/suites/test_suite_psa_crypto_op_fail.function +++ b/tests/suites/test_suite_psa_crypto_op_fail.function @@ -27,11 +27,11 @@ static int test_equal_status(const char *test, * run, it would be better to clarify the expectations and reconcile the * library and the test case generator. */ -#define TEST_STATUS(expr1, expr2) \ - do { \ +#define TEST_STATUS(expr1, expr2) \ + do { \ if (!test_equal_status( #expr1 " == " #expr2, __LINE__, __FILE__, \ - expr1, expr2)) \ - goto exit; \ + expr1, expr2)) \ + goto exit; \ } while (0) /* END_HEADER */ diff --git a/tests/suites/test_suite_psa_crypto_pake.function b/tests/suites/test_suite_psa_crypto_pake.function index 1cc69a73aa..08c88a1d6e 100644 --- a/tests/suites/test_suite_psa_crypto_pake.function +++ b/tests/suites/test_suite_psa_crypto_pake.function @@ -71,9 +71,9 @@ static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' }; * we're corrupting. */ #define DO_ROUND_CONDITIONAL_INJECT(this_stage, buf) \ - if (this_stage == err_stage) \ - { \ - *(buf + 7) ^= 1; \ + if (this_stage == err_stage) \ + { \ + *(buf + 7) ^= 1; \ } #define DO_ROUND_CONDITIONAL_CHECK_FAILURE(this_stage, function) \ @@ -84,20 +84,20 @@ static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' }; } #define DO_ROUND_UPDATE_OFFSETS(main_buf_offset, step_offset, step_size) \ - { \ - step_offset = main_buf_offset; \ - main_buf_offset += step_size; \ + { \ + step_offset = main_buf_offset; \ + main_buf_offset += step_size; \ } -#define DO_ROUND_CHECK_FAILURE() \ - if (err_stage != ERR_NONE && status != PSA_SUCCESS) \ +#define DO_ROUND_CHECK_FAILURE() \ + if (err_stage != ERR_NONE && status != PSA_SUCCESS) \ { \ - TEST_EQUAL(status, expected_error_arg); \ + TEST_EQUAL(status, expected_error_arg); \ break; \ } \ else \ { \ - TEST_EQUAL(status, PSA_SUCCESS); \ + TEST_EQUAL(status, PSA_SUCCESS); \ } #if defined(PSA_WANT_ALG_JPAKE) @@ -550,15 +550,15 @@ exit: * - terminated with failure otherwise (either no error was expected at this * stage or a different error code was expected) */ -#define SETUP_ALWAYS_CHECK_STEP(test_function, this_check_err_stage) \ +#define SETUP_ALWAYS_CHECK_STEP(test_function, this_check_err_stage) \ status = test_function; \ - if (err_stage != this_check_err_stage) \ + if (err_stage != this_check_err_stage) \ { \ - PSA_ASSERT(status); \ + PSA_ASSERT(status); \ } \ else \ { \ - TEST_EQUAL(status, expected_error); \ + TEST_EQUAL(status, expected_error); \ goto exit; \ } @@ -572,10 +572,10 @@ exit: * The test succeeds if the returned error is exactly the expected one, * otherwise it fails. */ -#define SETUP_CONDITIONAL_CHECK_STEP(test_function, this_check_err_stage) \ - if (err_stage == this_check_err_stage) \ +#define SETUP_CONDITIONAL_CHECK_STEP(test_function, this_check_err_stage) \ + if (err_stage == this_check_err_stage) \ { \ - TEST_EQUAL(test_function, expected_error); \ + TEST_EQUAL(test_function, expected_error); \ goto exit; \ } /* END_HEADER */ diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function index 96be55bcda..66d2a4eb99 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function @@ -14,8 +14,8 @@ #endif /* Same in library/psa_crypto.c */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) #define BUILTIN_ALG_ANY_HKDF 1 #endif @@ -36,11 +36,11 @@ /** The location and lifetime used for tests that use a single driver. */ #define TEST_DRIVER_LOCATION 1 -#define TEST_SE_PERSISTENT_LIFETIME \ +#define TEST_SE_PERSISTENT_LIFETIME \ (PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \ PSA_KEY_PERSISTENCE_DEFAULT, TEST_DRIVER_LOCATION)) -#define TEST_SE_VOLATILE_LIFETIME \ +#define TEST_SE_VOLATILE_LIFETIME \ (PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \ PSA_KEY_PERSISTENCE_VOLATILE, TEST_DRIVER_LOCATION)) @@ -54,13 +54,13 @@ * * Use this macro to assert on guarantees provided by the core. */ -#define DRIVER_ASSERT_RETURN(TEST) \ - do { \ - if (!(TEST)) \ - { \ - mbedtls_test_fail( #TEST, __LINE__, __FILE__); \ - return PSA_ERROR_DETECTED_BY_DRIVER; \ - } \ +#define DRIVER_ASSERT_RETURN(TEST) \ + do { \ + if (!(TEST)) \ + { \ + mbedtls_test_fail( #TEST, __LINE__, __FILE__); \ + return PSA_ERROR_DETECTED_BY_DRIVER; \ + } \ } while (0) /** Like #TEST_ASSERT for use in a driver method, with cleanup. @@ -70,14 +70,14 @@ * * Use this macro to assert on guarantees provided by the core. */ -#define DRIVER_ASSERT(TEST) \ - do { \ - if (!(TEST)) \ - { \ - mbedtls_test_fail( #TEST, __LINE__, __FILE__); \ +#define DRIVER_ASSERT(TEST) \ + do { \ + if (!(TEST)) \ + { \ + mbedtls_test_fail( #TEST, __LINE__, __FILE__); \ status = PSA_ERROR_DETECTED_BY_DRIVER; \ goto exit; \ - } \ + } \ } while (0) /** Like #PSA_ASSERT for a PSA API call that calls a driver underneath. @@ -91,16 +91,16 @@ * case, the test driver code is expected to have called mbedtls_test_fail() * already, so we make sure not to overwrite the failure information. */ -#define PSA_ASSERT_VIA_DRIVER(expr, expected_status) \ - do { \ - psa_status_t PSA_ASSERT_VIA_DRIVER_status = (expr); \ - if (PSA_ASSERT_VIA_DRIVER_status == PSA_ERROR_DETECTED_BY_DRIVER) \ - goto exit; \ - if (PSA_ASSERT_VIA_DRIVER_status != (expected_status)) \ - { \ +#define PSA_ASSERT_VIA_DRIVER(expr, expected_status) \ + do { \ + psa_status_t PSA_ASSERT_VIA_DRIVER_status = (expr); \ + if (PSA_ASSERT_VIA_DRIVER_status == PSA_ERROR_DETECTED_BY_DRIVER) \ + goto exit; \ + if (PSA_ASSERT_VIA_DRIVER_status != (expected_status)) \ + { \ mbedtls_test_fail( #expr, __LINE__, __FILE__); \ - goto exit; \ - } \ + goto exit; \ + } \ } while (0) diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function index 9480bd4296..efd24e9f29 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function @@ -6,7 +6,7 @@ /** The location and lifetime used for tests that use a single driver. */ #define TEST_DRIVER_LOCATION 1 -#define TEST_SE_PERSISTENT_LIFETIME \ +#define TEST_SE_PERSISTENT_LIFETIME \ (PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( \ PSA_KEY_PERSISTENCE_DEFAULT, TEST_DRIVER_LOCATION)) @@ -163,10 +163,10 @@ static psa_status_t mock_import(psa_drv_se_context_t *drv_context, } static psa_status_t mock_export(psa_drv_se_context_t *context, - psa_key_slot_number_t slot_number, - uint8_t *p_data, - size_t data_size, - size_t *p_data_length) + psa_key_slot_number_t slot_number, + uint8_t *p_data, + size_t data_size, + size_t *p_data_length) { (void) context; (void) p_data; @@ -180,10 +180,10 @@ static psa_status_t mock_export(psa_drv_se_context_t *context, } static psa_status_t mock_export_public(psa_drv_se_context_t *context, - psa_key_slot_number_t slot_number, - uint8_t *p_data, - size_t data_size, - size_t *p_data_length) + psa_key_slot_number_t slot_number, + uint8_t *p_data, + size_t data_size, + size_t *p_data_length) { (void) context; (void) p_data; @@ -197,13 +197,13 @@ static psa_status_t mock_export_public(psa_drv_se_context_t *context, } static psa_status_t mock_sign(psa_drv_se_context_t *context, - psa_key_slot_number_t key_slot, - psa_algorithm_t alg, - const uint8_t *p_hash, - size_t hash_length, - uint8_t *p_signature, - size_t signature_size, - size_t *p_signature_length) + psa_key_slot_number_t key_slot, + psa_algorithm_t alg, + const uint8_t *p_hash, + size_t hash_length, + uint8_t *p_signature, + size_t signature_size, + size_t *p_signature_length) { (void) context; (void) p_hash; @@ -220,12 +220,12 @@ static psa_status_t mock_sign(psa_drv_se_context_t *context, } static psa_status_t mock_verify(psa_drv_se_context_t *context, - psa_key_slot_number_t key_slot, - psa_algorithm_t alg, - const uint8_t *p_hash, - size_t hash_length, - const uint8_t *p_signature, - size_t signature_length) + psa_key_slot_number_t key_slot, + psa_algorithm_t alg, + const uint8_t *p_hash, + size_t hash_length, + const uint8_t *p_signature, + size_t signature_length) { (void) context; (void) p_hash; @@ -241,10 +241,10 @@ static psa_status_t mock_verify(psa_drv_se_context_t *context, } static psa_status_t mock_allocate(psa_drv_se_context_t *drv_context, - void *persistent_data, - const psa_key_attributes_t *attributes, - psa_key_creation_method_t method, - psa_key_slot_number_t *key_slot) + void *persistent_data, + const psa_key_attributes_t *attributes, + psa_key_creation_method_t method, + psa_key_slot_number_t *key_slot) { (void) drv_context; (void) persistent_data; @@ -259,8 +259,8 @@ static psa_status_t mock_allocate(psa_drv_se_context_t *drv_context, } static psa_status_t mock_destroy(psa_drv_se_context_t *context, - void *persistent_data, - psa_key_slot_number_t slot_number) + void *persistent_data, + psa_key_slot_number_t slot_number) { (void) context; (void) persistent_data; diff --git a/tests/suites/test_suite_psa_its.function b/tests/suites/test_suite_psa_its.function index 0f66c79517..ce3433f2e5 100644 --- a/tests/suites/test_suite_psa_its.function +++ b/tests/suites/test_suite_psa_its.function @@ -19,11 +19,11 @@ #define PSA_ITS_STORAGE_PREFIX "" #define PSA_ITS_STORAGE_FILENAME_PATTERN "%08lx%08lx" #define PSA_ITS_STORAGE_SUFFIX ".psa_its" -#define PSA_ITS_STORAGE_FILENAME_LENGTH \ - (sizeof(PSA_ITS_STORAGE_PREFIX) - 1 + /*prefix without terminating 0*/ \ - 16 + /*UID (64-bit number in hex)*/ \ - 16 + /*UID (64-bit number in hex)*/ \ - sizeof(PSA_ITS_STORAGE_SUFFIX) - 1 + /*suffix without terminating 0*/ \ +#define PSA_ITS_STORAGE_FILENAME_LENGTH \ + (sizeof(PSA_ITS_STORAGE_PREFIX) - 1 + /*prefix without terminating 0*/ \ + 16 + /*UID (64-bit number in hex)*/ \ + 16 + /*UID (64-bit number in hex)*/ \ + sizeof(PSA_ITS_STORAGE_SUFFIX) - 1 + /*suffix without terminating 0*/ \ 1 /*terminating null byte*/) #define PSA_ITS_STORAGE_TEMP \ PSA_ITS_STORAGE_PREFIX "tempfile" PSA_ITS_STORAGE_SUFFIX diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 840af7d2d9..343e58a12d 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -1623,11 +1623,11 @@ void ssl_tls13_derive_secret(int hash_alg, unsigned char const *lbl = NULL; size_t lbl_len; -#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ - if (label_idx == (int) tls13_label_ ## name) \ +#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ + if (label_idx == (int) tls13_label_ ## name) \ { \ lbl = mbedtls_ssl_tls13_labels.name; \ - lbl_len = sizeof(mbedtls_ssl_tls13_labels.name); \ + lbl_len = sizeof(mbedtls_ssl_tls13_labels.name); \ } MBEDTLS_SSL_TLS1_3_LABEL_LIST #undef MBEDTLS_SSL_TLS1_3_LABEL @@ -1667,7 +1667,7 @@ void ssl_tls13_derive_early_secrets(int hash_alg, /* Double-check that we've passed sane parameters. */ psa_algorithm_t alg = (psa_algorithm_t) hash_alg; size_t const hash_len = PSA_HASH_LENGTH(alg); - TEST_ASSERT(PSA_ALG_IS_HASH(alg) && + TEST_ASSERT(PSA_ALG_IS_HASH(alg) && secret->len == hash_len && transcript->len == hash_len && traffic_expected->len == hash_len && @@ -1701,7 +1701,7 @@ void ssl_tls13_derive_handshake_secrets(int hash_alg, /* Double-check that we've passed sane parameters. */ psa_algorithm_t alg = (psa_algorithm_t) hash_alg; size_t const hash_len = PSA_HASH_LENGTH(alg); - TEST_ASSERT(PSA_ALG_IS_HASH(alg) && + TEST_ASSERT(PSA_ALG_IS_HASH(alg) && secret->len == hash_len && transcript->len == hash_len && client_expected->len == hash_len && @@ -1736,7 +1736,7 @@ void ssl_tls13_derive_application_secrets(int hash_alg, /* Double-check that we've passed sane parameters. */ psa_algorithm_t alg = (psa_algorithm_t) hash_alg; size_t const hash_len = PSA_HASH_LENGTH(alg); - TEST_ASSERT(PSA_ALG_IS_HASH(alg) && + TEST_ASSERT(PSA_ALG_IS_HASH(alg) && secret->len == hash_len && transcript->len == hash_len && client_expected->len == hash_len && @@ -1772,7 +1772,7 @@ void ssl_tls13_derive_resumption_secrets(int hash_alg, /* Double-check that we've passed sane parameters. */ psa_algorithm_t alg = (psa_algorithm_t) hash_alg; size_t const hash_len = PSA_HASH_LENGTH(alg); - TEST_ASSERT(PSA_ALG_IS_HASH(alg) && + TEST_ASSERT(PSA_ALG_IS_HASH(alg) && secret->len == hash_len && transcript->len == hash_len && resumption_expected->len == hash_len); @@ -1803,7 +1803,7 @@ void ssl_tls13_create_psk_binder(int hash_alg, /* Double-check that we've passed sane parameters. */ psa_algorithm_t alg = (psa_algorithm_t) hash_alg; size_t const hash_len = PSA_HASH_LENGTH(alg); - TEST_ASSERT(PSA_ALG_IS_HASH(alg) && + TEST_ASSERT(PSA_ALG_IS_HASH(alg) && transcript->len == hash_len && binder_expected->len == hash_len); diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index e72a6e377e..fbc4fbcd0b 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -91,7 +91,7 @@ static int ca_callback_fail(void *data, mbedtls_x509_crt const *child, mbedtls_x } #if defined(MBEDTLS_X509_CRT_PARSE_C) static int ca_callback(void *data, mbedtls_x509_crt const *child, - mbedtls_x509_crt **candidates) + mbedtls_x509_crt **candidates) { int ret = 0; mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data; @@ -227,7 +227,7 @@ static int verify_print(void *data, mbedtls_x509_crt *crt, int certificate_depth } static int verify_parse_san(mbedtls_x509_subject_alternative_name *san, - char **buf, size_t *size) + char **buf, size_t *size) { int ret; size_t i; @@ -318,7 +318,7 @@ static int verify_parse_san(mbedtls_x509_subject_alternative_name *san, } static int parse_crt_ext_cb(void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x509_buf const *oid, - int critical, const unsigned char *cp, const unsigned char *end) + int critical, const unsigned char *cp, const unsigned char *end) { (void) crt; (void) critical; @@ -418,7 +418,7 @@ static int parse_crt_ext_cb(void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x5 #if defined(MBEDTLS_X509_CSR_PARSE_C) static int parse_csr_ext_accept_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbedtls_x509_buf const *oid, - int critical, const unsigned char *cp, const unsigned char *end) + int critical, const unsigned char *cp, const unsigned char *end) { (void) p_ctx; (void) csr; @@ -431,7 +431,7 @@ static int parse_csr_ext_accept_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbe } static int parse_csr_ext_reject_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbedtls_x509_buf const *oid, - int critical, const unsigned char *cp, const unsigned char *end) + int critical, const unsigned char *cp, const unsigned char *end) { (void) p_ctx; (void) csr; diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index 820b48dfe8..901a88ad0a 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -12,16 +12,16 @@ #if defined(MBEDTLS_RSA_C) static int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen, - const unsigned char *input, unsigned char *output, - size_t output_max_len) + const unsigned char *input, unsigned char *output, + size_t output_max_len) { return mbedtls_rsa_pkcs1_decrypt((mbedtls_rsa_context *) ctx, NULL, NULL, olen, input, output, output_max_len); } static int mbedtls_rsa_sign_func(void *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_md_type_t md_alg, unsigned int hashlen, - const unsigned char *hash, unsigned char *sig) + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_md_type_t md_alg, unsigned int hashlen, + const unsigned char *hash, unsigned char *sig) { return mbedtls_rsa_pkcs1_sign((mbedtls_rsa_context *) ctx, f_rng, p_rng, md_alg, hashlen, hash, sig); From 4d0d0ec028be594d83c752303ee3c3ff5bed37d2 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Wed, 5 Jun 2024 01:45:54 +0200 Subject: [PATCH 027/100] Move the -Wmissing-prototypes option from library/CMakeLists.txt to the top-level CMakeLists.txt for GCC & Clang Signed-off-by: Michael Schuster --- CMakeLists.txt | 4 ++-- library/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10f4f53803..71b1383651 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,7 +204,7 @@ if(CMAKE_COMPILER_IS_GNU) # note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings -Wmissing-prototypes") if (GCC_VERSION VERSION_GREATER 3.0 OR GCC_VERSION VERSION_EQUAL 3.0) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat=2 -Wno-format-nonliteral") endif() @@ -238,7 +238,7 @@ if(CMAKE_COMPILER_IS_GNU) endif(CMAKE_COMPILER_IS_GNU) if(CMAKE_COMPILER_IS_CLANG) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings -Wmissing-prototypes -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral") set(CMAKE_C_FLAGS_RELEASE "-O2") set(CMAKE_C_FLAGS_DEBUG "-O0 -g3") set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage") diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 37a9724559..3f59c3c1bb 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -197,11 +197,11 @@ else() endif() if(CMAKE_COMPILER_IS_GNUCC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-declarations -Wmissing-prototypes") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-declarations") endif(CMAKE_COMPILER_IS_GNUCC) if(CMAKE_COMPILER_IS_CLANG) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-declarations -Wmissing-prototypes -Wdocumentation -Wno-documentation-deprecated-sync -Wunreachable-code") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-declarations -Wdocumentation -Wno-documentation-deprecated-sync -Wunreachable-code") endif(CMAKE_COMPILER_IS_CLANG) if(CMAKE_COMPILER_IS_MSVC) From 6d6cae53ad4ffbe8db4f25c1255f2937462e3c70 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Wed, 5 Jun 2024 14:45:45 +0200 Subject: [PATCH 028/100] Fix tests build with MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS enabled In that case mbedtls_psa_platform_get_builtin_key is already declared. Signed-off-by: Michael Schuster --- tests/src/drivers/platform_builtin_keys.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/src/drivers/platform_builtin_keys.c b/tests/src/drivers/platform_builtin_keys.c index 01fc050bbb..4561b6fdc2 100644 --- a/tests/src/drivers/platform_builtin_keys.c +++ b/tests/src/drivers/platform_builtin_keys.c @@ -10,6 +10,8 @@ #include +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) + #include #include @@ -76,3 +78,5 @@ psa_status_t mbedtls_psa_platform_get_builtin_key( return PSA_ERROR_DOES_NOT_EXIST; } + +#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ From 275b698ee766b6c4615c15908cca279ee7ade7c6 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Fri, 7 Jun 2024 01:51:54 +0200 Subject: [PATCH 029/100] Use correct test case conditionals for helper functions in tests/suites Fix unused-function errors. Signed-off-by: Michael Schuster --- tests/suites/test_suite_bignum.function | 2 ++ tests/suites/test_suite_entropy.function | 7 +++++++ tests/suites/test_suite_lmots.function | 4 ++-- tests/suites/test_suite_pk.function | 4 ++-- tests/suites/test_suite_psa_crypto.function | 2 ++ tests/suites/test_suite_x509parse.function | 18 +++++++++++------- tests/suites/test_suite_x509write.function | 8 ++++++-- 7 files changed, 32 insertions(+), 13 deletions(-) diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function index 7cbbbe87f7..1830e5aa1c 100644 --- a/tests/suites/test_suite_bignum.function +++ b/tests/suites/test_suite_bignum.function @@ -32,6 +32,7 @@ static int sign_is_valid(const mbedtls_mpi *X) return 1; } +#if defined(MBEDTLS_GENPRIME) typedef struct mbedtls_test_mpi_random { data_t *data; size_t pos; @@ -73,6 +74,7 @@ static int mbedtls_test_mpi_miller_rabin_determinizer(void *state, return 0; } +#endif /* MBEDTLS_GENPRIME */ /* Random generator that is told how many bytes to return. */ static int f_rng_bytes_left(void *state, unsigned char *buf, size_t len) diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function index c89c26c637..a4f3b1bd7c 100644 --- a/tests/suites/test_suite_entropy.function +++ b/tests/suites/test_suite_entropy.function @@ -60,6 +60,8 @@ static void entropy_clear_sources(mbedtls_entropy_context *ctx) } #if defined(MBEDTLS_ENTROPY_NV_SEED) + +#if defined(MBEDTLS_MD_LIGHT) && defined(MBEDTLS_PLATFORM_NV_SEED_ALT) /* * NV seed read/write functions that use a buffer instead of a file */ @@ -84,7 +86,9 @@ static int buffer_nv_seed_write(unsigned char *buf, size_t buf_len) memcpy(buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE); return 0; } +#endif /* MBEDTLS_MD_LIGHT && MBEDTLS_PLATFORM_NV_SEED_ALT */ +#if defined(MBEDTLS_FS_IO) /* * NV seed read/write helpers that fill the base seedfile */ @@ -111,6 +115,7 @@ static int write_nv_seed(unsigned char *buf, size_t buf_len) return 0; } +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) static int read_nv_seed(unsigned char *buf, size_t buf_len) { FILE *f; @@ -133,6 +138,8 @@ static int read_nv_seed(unsigned char *buf, size_t buf_len) return 0; } +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_ENTROPY_NV_SEED */ /* END_HEADER */ diff --git a/tests/suites/test_suite_lmots.function b/tests/suites/test_suite_lmots.function index 61f2e28617..bcc72d1822 100644 --- a/tests/suites/test_suite_lmots.function +++ b/tests/suites/test_suite_lmots.function @@ -2,7 +2,7 @@ #include "lmots.h" #include "mbedtls/lms.h" -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_LMS_PRIVATE) static int check_lmots_private_key_for_leak(unsigned char *sig) { size_t idx; @@ -18,7 +18,7 @@ static int check_lmots_private_key_for_leak(unsigned char *sig) exit: return -1; } -#endif /* defined(MBEDTLS_TEST_HOOKS) */ +#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_LMS_PRIVATE */ /* END_HEADER */ diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 0cff121fbe..f197d040bf 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -467,7 +467,7 @@ exit: } #endif /* MBEDTLS_PSA_CRYPTO_C */ -#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_RSA_ALT_SUPPORT) static int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len) @@ -491,7 +491,7 @@ static size_t mbedtls_rsa_key_len_func(void *ctx) { return ((const mbedtls_rsa_context *) ctx)->len; } -#endif /* MBEDTLS_RSA_C */ +#endif /* MBEDTLS_RSA_C && MBEDTLS_PK_RSA_ALT_SUPPORT */ typedef enum { /* The values are compatible with thinking of "from pair" as a boolean. */ diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 3841ac6c23..b8052481c6 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1316,6 +1316,7 @@ exit: #if defined(MBEDTLS_THREADING_PTHREAD) +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) typedef struct same_key_context { data_t *data; mbedtls_svc_key_id_t key; @@ -1434,6 +1435,7 @@ static void *thread_use_and_destroy_key(void *ctx) exit: return NULL; } +#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ typedef struct generate_key_context { psa_key_type_t type; diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index fbc4fbcd0b..b017e6854e 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -60,6 +60,9 @@ const mbedtls_x509_crt_profile profile_sha512 = 1024, }; +#if defined(MBEDTLS_X509_CRT_PARSE_C) + +#if defined(MBEDTLS_FS_IO) static int verify_none(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) { ((void) data); @@ -80,7 +83,8 @@ static int verify_all(void *data, mbedtls_x509_crt *crt, int certificate_depth, return 0; } -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) +#if defined(MBEDTLS_X509_CRL_PARSE_C) && \ + defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) static int ca_callback_fail(void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates) { ((void) data); @@ -89,7 +93,7 @@ static int ca_callback_fail(void *data, mbedtls_x509_crt const *child, mbedtls_x return -1; } -#if defined(MBEDTLS_X509_CRT_PARSE_C) + static int ca_callback(void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates) { @@ -138,8 +142,7 @@ exit: *candidates = first; return ret; } -#endif /* MBEDTLS_X509_CRT_PARSE_C */ -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ +#endif /* MBEDTLS_X509_CRL_PARSE_C && MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ static int verify_fatal(void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) { @@ -186,7 +189,6 @@ done: return ret; } -#if defined(MBEDTLS_X509_CRT_PARSE_C) typedef struct { char buf[512]; char *p; @@ -316,6 +318,7 @@ static int verify_parse_san(mbedtls_x509_subject_alternative_name *san, return 0; } +#endif /* MBEDTLS_FS_IO */ static int parse_crt_ext_cb(void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x509_buf const *oid, int critical, const unsigned char *cp, const unsigned char *end) @@ -416,7 +419,8 @@ static int parse_crt_ext_cb(void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x5 } #endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_X509_CSR_PARSE_C) +#if defined(MBEDTLS_X509_CSR_PARSE_C) && \ + !defined(MBEDTLS_X509_REMOVE_INFO) static int parse_csr_ext_accept_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbedtls_x509_buf const *oid, int critical, const unsigned char *cp, const unsigned char *end) { @@ -443,7 +447,7 @@ static int parse_csr_ext_reject_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbe return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); } -#endif /* MBEDTLS_X509_CSR_PARSE_C */ +#endif /* MBEDTLS_X509_CSR_PARSE_C && !MBEDTLS_X509_REMOVE_INFO */ /* END_HEADER */ /* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */ diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index 901a88ad0a..2762b0f84e 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -10,7 +10,11 @@ #include "mbedtls/pk.h" #include "mbedtls/psa_util.h" -#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_PEM_WRITE_C) && \ + defined(MBEDTLS_X509_CRT_WRITE_C) && \ + defined(MBEDTLS_X509_CRT_PARSE_C) && \ + defined(MBEDTLS_MD_CAN_SHA1) && \ + defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_RSA_ALT_SUPPORT) static int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len) @@ -30,7 +34,7 @@ static size_t mbedtls_rsa_key_len_func(void *ctx) { return ((const mbedtls_rsa_context *) ctx)->len; } -#endif /* MBEDTLS_RSA_C */ +#endif #if defined(MBEDTLS_USE_PSA_CRYPTO) && \ defined(MBEDTLS_PEM_WRITE_C) && defined(MBEDTLS_X509_CSR_WRITE_C) From 6a3573a1dd16418b4e613e20c48767c70a444c9d Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Fri, 7 Jun 2024 06:47:31 +0200 Subject: [PATCH 030/100] Fix Uncrustify errors in modified tests/suites to satisfy check_code_style test Signed-off-by: Michael Schuster --- tests/suites/test_suite_common.function | 6 +++++- tests/suites/test_suite_x509parse.function | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/tests/suites/test_suite_common.function b/tests/suites/test_suite_common.function index c508b11998..8626a0ba4c 100644 --- a/tests/suites/test_suite_common.function +++ b/tests/suites/test_suite_common.function @@ -1,7 +1,11 @@ /* BEGIN_HEADER */ #include "common.h" -static void fill_arrays(unsigned char *a, unsigned char *b, unsigned char *r1, unsigned char *r2, size_t n) +static void fill_arrays(unsigned char *a, + unsigned char *b, + unsigned char *r1, + unsigned char *r2, + size_t n) { for (size_t i = 0; i < n; i++) { a[i] = (unsigned char) i * 3; diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index b017e6854e..9fc0e55dff 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -85,7 +85,8 @@ static int verify_all(void *data, mbedtls_x509_crt *crt, int certificate_depth, #if defined(MBEDTLS_X509_CRL_PARSE_C) && \ defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -static int ca_callback_fail(void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates) +static int ca_callback_fail(void *data, mbedtls_x509_crt const *child, + mbedtls_x509_crt **candidates) { ((void) data); ((void) child); @@ -421,8 +422,12 @@ static int parse_crt_ext_cb(void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x5 #if defined(MBEDTLS_X509_CSR_PARSE_C) && \ !defined(MBEDTLS_X509_REMOVE_INFO) -static int parse_csr_ext_accept_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbedtls_x509_buf const *oid, - int critical, const unsigned char *cp, const unsigned char *end) +static int parse_csr_ext_accept_cb(void *p_ctx, + mbedtls_x509_csr const *csr, + mbedtls_x509_buf const *oid, + int critical, + const unsigned char *cp, + const unsigned char *end) { (void) p_ctx; (void) csr; @@ -434,8 +439,12 @@ static int parse_csr_ext_accept_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbe return 0; } -static int parse_csr_ext_reject_cb(void *p_ctx, mbedtls_x509_csr const *csr, mbedtls_x509_buf const *oid, - int critical, const unsigned char *cp, const unsigned char *end) +static int parse_csr_ext_reject_cb(void *p_ctx, + mbedtls_x509_csr const *csr, + mbedtls_x509_buf const *oid, + int critical, + const unsigned char *cp, + const unsigned char *end) { (void) p_ctx; (void) csr; From ab4951fbeff81a3fcd37e5fea808c1e371408e30 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Fri, 7 Jun 2024 06:57:06 +0200 Subject: [PATCH 031/100] Add missing include in tests/src/psa_memory_poisoning_wrappers.c to fix missing-prototype error Signed-off-by: Michael Schuster --- tests/src/psa_memory_poisoning_wrappers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/src/psa_memory_poisoning_wrappers.c b/tests/src/psa_memory_poisoning_wrappers.c index 05cba18ee7..7b48c7c95e 100644 --- a/tests/src/psa_memory_poisoning_wrappers.c +++ b/tests/src/psa_memory_poisoning_wrappers.c @@ -4,7 +4,8 @@ * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ -#include "test/memory.h" +#include +#include #include "psa_crypto_invasive.h" From ff4d6aea04661bccef2920e7caa179166e9b4747 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Fri, 7 Jun 2024 07:02:45 +0200 Subject: [PATCH 032/100] Use correct conditionals in programs/ssl (fix unused-function errors) Signed-off-by: Michael Schuster --- programs/ssl/ssl_server2.c | 5 +++-- programs/ssl/ssl_test_common_source.c | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 32fcc0b62d..480b262446 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1376,7 +1376,8 @@ static int report_cid_usage(mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_HAVE_TIME) +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C) && \ + defined(MBEDTLS_HAVE_TIME) static inline void put_unaligned_uint32(void *p, uint32_t x) { memcpy(p, &x, sizeof(x)); @@ -1467,7 +1468,7 @@ static int dummy_ticket_parse(void *p_ticket, mbedtls_ssl_session *session, return ret; } -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_HAVE_TIME */ +#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_TICKET_C && MBEDTLS_HAVE_TIME */ static int parse_cipher(char *buf) { diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c index ab41a0bf6d..6d333e803a 100644 --- a/programs/ssl/ssl_test_common_source.c +++ b/programs/ssl/ssl_test_common_source.c @@ -352,6 +352,7 @@ static int x509_crt_verify_info(char *buf, size_t size, const char *prefix, } #endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) static void mbedtls_print_supported_sig_algs(void) { mbedtls_printf("supported signature algorithms:\n"); @@ -373,3 +374,4 @@ static void mbedtls_print_supported_sig_algs(void) mbedtls_printf("ecdsa_sha1\n"); mbedtls_printf("\n"); } +#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ From 46a6e73285ecf77e0cab8ce0484c83cbdc67bb98 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Fri, 7 Jun 2024 20:58:06 +0200 Subject: [PATCH 033/100] Fix format-pedantic error in programs/test/metatest.c Signed-off-by: Michael Schuster --- programs/test/metatest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/test/metatest.c b/programs/test/metatest.c index 9d90d8cb72..d876e9a87d 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -128,7 +128,7 @@ static void null_pointer_dereference(const char *name) volatile char *volatile p; set_to_zero_but_the_compiler_does_not_know(&p, sizeof(p)); /* Undefined behavior (read from null data pointer) */ - mbedtls_printf("%p -> %u\n", p, (unsigned) *p); + mbedtls_printf("%p -> %u\n", (void *) p, (unsigned) *p); } static void null_pointer_call(const char *name) From 9bf18751463ba78c2b449927ed6a896196491021 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Sun, 21 Jul 2024 00:44:33 +0200 Subject: [PATCH 034/100] Revert commit 33af72df in order to not depend on test code Signed-off-by: Michael Schuster --- programs/cipher/cipher_aead_demo.c | 14 +++++++++++--- programs/hash/md_hmac_demo.c | 16 ++++++++++++---- programs/psa/aead_demo.c | 14 +++++++++++--- programs/psa/hmac_demo.c | 16 ++++++++++++---- tests/include/test/helpers.h | 3 --- tests/src/helpers.c | 9 --------- 6 files changed, 46 insertions(+), 26 deletions(-) diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c index 60a5ea280e..853ec202c6 100644 --- a/programs/cipher/cipher_aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -35,8 +35,6 @@ #include "mbedtls/cipher.h" -#include - #include #include #include @@ -80,6 +78,16 @@ const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; * 32-byte is enough to all the key size supported by this program. */ const unsigned char key_bytes[32] = { 0x2a }; +/* Print the contents of a buffer in hex */ +void print_buf(const char *title, unsigned char *buf, size_t len) +{ + printf("%s:", title); + for (size_t i = 0; i < len; i++) { + printf(" %02x", buf[i]); + } + printf("\n"); +} + /* Run an Mbed TLS function and bail out if it fails. * A string description of the error code can be recovered with: * programs/util/strerror */ @@ -190,7 +198,7 @@ static int aead_encrypt(mbedtls_cipher_context_t *ctx, size_t tag_len, p += tag_len; olen = p - out; - mbedtls_test_print_buf("out", out, olen); + print_buf("out", out, olen); exit: return ret; diff --git a/programs/hash/md_hmac_demo.c b/programs/hash/md_hmac_demo.c index ba51bfda26..4b5aa3ba78 100644 --- a/programs/hash/md_hmac_demo.c +++ b/programs/hash/md_hmac_demo.c @@ -32,8 +32,6 @@ #include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize -#include - #include #include @@ -58,6 +56,16 @@ const unsigned char msg2_part2[] = { 0x06, 0x06 }; * This example program uses SHA-256, so a 32-byte key makes sense. */ const unsigned char key_bytes[32] = { 0 }; +/* Print the contents of a buffer in hex */ +void print_buf(const char *title, unsigned char *buf, size_t len) +{ + printf("%s:", title); + for (size_t i = 0; i < len; i++) { + printf(" %02x", buf[i]); + } + printf("\n"); +} + /* Run an Mbed TLS function and bail out if it fails. * A string description of the error code can be recovered with: * programs/util/strerror */ @@ -99,14 +107,14 @@ static int hmac_demo(void) CHK(mbedtls_md_hmac_update(&ctx, msg1_part1, sizeof(msg1_part1))); CHK(mbedtls_md_hmac_update(&ctx, msg1_part2, sizeof(msg1_part2))); CHK(mbedtls_md_hmac_finish(&ctx, out)); - mbedtls_test_print_buf("msg1", out, mbedtls_md_get_size(info)); + print_buf("msg1", out, mbedtls_md_get_size(info)); /* compute HMAC(key, msg2_part1 | msg2_part2) */ CHK(mbedtls_md_hmac_reset(&ctx)); // prepare for new operation CHK(mbedtls_md_hmac_update(&ctx, msg2_part1, sizeof(msg2_part1))); CHK(mbedtls_md_hmac_update(&ctx, msg2_part2, sizeof(msg2_part2))); CHK(mbedtls_md_hmac_finish(&ctx, out)); - mbedtls_test_print_buf("msg2", out, mbedtls_md_get_size(info)); + print_buf("msg2", out, mbedtls_md_get_size(info)); exit: mbedtls_md_free(&ctx); diff --git a/programs/psa/aead_demo.c b/programs/psa/aead_demo.c index b300e3619c..619166dba4 100644 --- a/programs/psa/aead_demo.c +++ b/programs/psa/aead_demo.c @@ -36,8 +36,6 @@ #include "psa/crypto.h" -#include - #include #include #include @@ -83,6 +81,16 @@ const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; * 32-byte is enough to all the key size supported by this program. */ const unsigned char key_bytes[32] = { 0x2a }; +/* Print the contents of a buffer in hex */ +void print_buf(const char *title, uint8_t *buf, size_t len) +{ + printf("%s:", title); + for (size_t i = 0; i < len; i++) { + printf(" %02x", buf[i]); + } + printf("\n"); +} + /* Run a PSA function and bail out if it fails. * The symbolic name of the error code can be recovered using: * programs/psa/psa_constant_name status */ @@ -208,7 +216,7 @@ static int aead_encrypt(psa_key_id_t key, psa_algorithm_t alg, p += olen_tag; olen = p - out; - mbedtls_test_print_buf("out", out, olen); + print_buf("out", out, olen); exit: psa_aead_abort(&op); // required on errors, harmless on success diff --git a/programs/psa/hmac_demo.c b/programs/psa/hmac_demo.c index a85de008a7..f44f9a742f 100644 --- a/programs/psa/hmac_demo.c +++ b/programs/psa/hmac_demo.c @@ -32,8 +32,6 @@ #include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize -#include - #include #include @@ -60,6 +58,16 @@ const unsigned char msg2_part2[] = { 0x06, 0x06 }; * This example program uses SHA-256, so a 32-byte key makes sense. */ const unsigned char key_bytes[32] = { 0 }; +/* Print the contents of a buffer in hex */ +void print_buf(const char *title, uint8_t *buf, size_t len) +{ + printf("%s:", title); + for (size_t i = 0; i < len; i++) { + printf(" %02x", buf[i]); + } + printf("\n"); +} + /* Run a PSA function and bail out if it fails. * The symbolic name of the error code can be recovered using: * programs/psa/psa_constant_name status */ @@ -114,14 +122,14 @@ static psa_status_t hmac_demo(void) PSA_CHECK(psa_mac_update(&op, msg1_part1, sizeof(msg1_part1))); PSA_CHECK(psa_mac_update(&op, msg1_part2, sizeof(msg1_part2))); PSA_CHECK(psa_mac_sign_finish(&op, out, sizeof(out), &out_len)); - mbedtls_test_print_buf("msg1", out, out_len); + print_buf("msg1", out, out_len); /* compute HMAC(key, msg2_part1 | msg2_part2) */ PSA_CHECK(psa_mac_sign_setup(&op, key, alg)); PSA_CHECK(psa_mac_update(&op, msg2_part1, sizeof(msg2_part1))); PSA_CHECK(psa_mac_update(&op, msg2_part2, sizeof(msg2_part2))); PSA_CHECK(psa_mac_sign_finish(&op, out, sizeof(out), &out_len)); - mbedtls_test_print_buf("msg2", out, out_len); + print_buf("msg2", out, out_len); exit: psa_mac_abort(&op); // needed on error, harmless on success diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h index 10b321d781..d08100f158 100644 --- a/tests/include/test/helpers.h +++ b/tests/include/test/helpers.h @@ -381,9 +381,6 @@ unsigned char *mbedtls_test_unhexify_alloc(const char *ibuf, size_t *olen); int mbedtls_test_hexcmp(uint8_t *a, uint8_t *b, uint32_t a_len, uint32_t b_len); -/* Print the contents of a buffer in hex */ -void mbedtls_test_print_buf(const char *title, unsigned char *buf, size_t len); - #if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) #include "test/fake_external_rng_for_test.h" #endif diff --git a/tests/src/helpers.c b/tests/src/helpers.c index 29b2df515d..065d17d3e0 100644 --- a/tests/src/helpers.c +++ b/tests/src/helpers.c @@ -660,15 +660,6 @@ int mbedtls_test_hexcmp(uint8_t *a, uint8_t *b, return ret; } -void mbedtls_test_print_buf(const char *title, unsigned char *buf, size_t len) -{ - printf("%s:", title); - for (size_t i = 0; i < len; i++) { - printf(" %02x", buf[i]); - } - printf("\n"); -} - #if defined(MBEDTLS_TEST_HOOKS) void mbedtls_test_err_add_check(int high, int low, const char *file, int line) From 5830505b3d80e473354dd6653b0cf177c936654a Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Sun, 21 Jul 2024 00:46:10 +0200 Subject: [PATCH 035/100] Fix missing-prototype error for the print_buf functions in sample programs Signed-off-by: Michael Schuster --- programs/cipher/cipher_aead_demo.c | 2 +- programs/hash/md_hmac_demo.c | 2 +- programs/psa/aead_demo.c | 2 +- programs/psa/hmac_demo.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c index 853ec202c6..83fcce5878 100644 --- a/programs/cipher/cipher_aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -79,7 +79,7 @@ const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; const unsigned char key_bytes[32] = { 0x2a }; /* Print the contents of a buffer in hex */ -void print_buf(const char *title, unsigned char *buf, size_t len) +static void print_buf(const char *title, unsigned char *buf, size_t len) { printf("%s:", title); for (size_t i = 0; i < len; i++) { diff --git a/programs/hash/md_hmac_demo.c b/programs/hash/md_hmac_demo.c index 4b5aa3ba78..494e9efaa4 100644 --- a/programs/hash/md_hmac_demo.c +++ b/programs/hash/md_hmac_demo.c @@ -57,7 +57,7 @@ const unsigned char msg2_part2[] = { 0x06, 0x06 }; const unsigned char key_bytes[32] = { 0 }; /* Print the contents of a buffer in hex */ -void print_buf(const char *title, unsigned char *buf, size_t len) +static void print_buf(const char *title, unsigned char *buf, size_t len) { printf("%s:", title); for (size_t i = 0; i < len; i++) { diff --git a/programs/psa/aead_demo.c b/programs/psa/aead_demo.c index 619166dba4..2d99e3cbec 100644 --- a/programs/psa/aead_demo.c +++ b/programs/psa/aead_demo.c @@ -82,7 +82,7 @@ const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; const unsigned char key_bytes[32] = { 0x2a }; /* Print the contents of a buffer in hex */ -void print_buf(const char *title, uint8_t *buf, size_t len) +static void print_buf(const char *title, uint8_t *buf, size_t len) { printf("%s:", title); for (size_t i = 0; i < len; i++) { diff --git a/programs/psa/hmac_demo.c b/programs/psa/hmac_demo.c index f44f9a742f..683f3e59c9 100644 --- a/programs/psa/hmac_demo.c +++ b/programs/psa/hmac_demo.c @@ -59,7 +59,7 @@ const unsigned char msg2_part2[] = { 0x06, 0x06 }; const unsigned char key_bytes[32] = { 0 }; /* Print the contents of a buffer in hex */ -void print_buf(const char *title, uint8_t *buf, size_t len) +static void print_buf(const char *title, uint8_t *buf, size_t len) { printf("%s:", title); for (size_t i = 0; i < len; i++) { From 5eca4029c2ef0026354e0be13e4af44f502ed782 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 7 Aug 2024 20:08:23 +0200 Subject: [PATCH 036/100] Fix inverted assertion message Signed-off-by: Gilles Peskine --- library/psa_crypto_slot_management.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index c2949a61e7..9b297c9c08 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -67,7 +67,7 @@ static psa_global_data_t global_data; MBEDTLS_STATIC_ASSERT(ARRAY_LENGTH(global_data.key_slots) <= PSA_KEY_ID_VOLATILE_MAX - PSA_KEY_ID_VOLATILE_MIN + 1, - "The volatile key range is larger than the key slot array"); + "The key slot array is larger than the volatile key ID range"); static uint8_t psa_get_key_slots_initialized(void) { From a9083b752c76af901012e7ddad41fdfdaa21a618 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 7 Aug 2024 20:09:08 +0200 Subject: [PATCH 037/100] PSA_DONE: account for MBEDTLS_TEST_PSA_INTERNAL_KEYS Replace the hard-coded 1 by the proper constant now that the proper constant exists. Signed-off-by: Gilles Peskine --- tests/src/psa_crypto_helpers.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c index 1069eddfa1..197fd41980 100644 --- a/tests/src/psa_crypto_helpers.c +++ b/tests/src/psa_crypto_helpers.c @@ -74,7 +74,12 @@ const char *mbedtls_test_helper_is_psa_leaking(void) mbedtls_psa_get_stats(&stats); - if (stats.volatile_slots > 1) { + /* Some volatile slots may be used for internal purposes. Generally + * we'll have exactly MBEDTLS_TEST_PSA_INTERNAL_KEYS at this point, + * but in some cases we might have less, e.g. if a code path calls + * PSA_DONE more than once, or if there has only been a partial or + * failed initialization. */ + if (stats.volatile_slots > MBEDTLS_TEST_PSA_INTERNAL_KEYS) { return "A volatile slot has not been closed properly."; } if (stats.persistent_slots != 0) { From 1b240c7ec1fb8507c94ea5074d97d9dde51bc622 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 7 Aug 2024 22:38:52 +0200 Subject: [PATCH 038/100] Announce the main removals planned for 4.0 Signed-off-by: Gilles Peskine --- ChangeLog.d/announce-4.0-removals.txt | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 ChangeLog.d/announce-4.0-removals.txt diff --git a/ChangeLog.d/announce-4.0-removals.txt b/ChangeLog.d/announce-4.0-removals.txt new file mode 100644 index 0000000000..9ae61c1219 --- /dev/null +++ b/ChangeLog.d/announce-4.0-removals.txt @@ -0,0 +1,29 @@ +New deprecations + * The following cryptographic mechanisms are planned to be removed + in Mbed TLS 4.0: + - DES (including 3DES). + - PKCS#1v1.5 encryption (RSA-PKCS1-v1_5). (OAEP, PSS, and PKCS#1v1.5 + signature are staying.) + - Finite-field Diffie-Hellman with custom groups. (RFC 7919 remain + supported.) + - Elliptic curves of size 225 bits or less. + * The following mechanisms are planned to be removed from (D)TLS 1.2 + in Mbed TLS 4.0: + - RSA decryption (i.e. cipher suites using RSA without a key exchange: + cipher suites using an RSA signature and ECDHE are staying). + - Static ECDH (ephemeral ECDH, i.e. cipher suites using ECDHE, is staying). + - Finite-field Diffie-Hellman (i.e. DHE; ECDHE is staying) + - All cipher suites using CBC. + * The following low-level interfaces are planned to be removed from the + public API in Mbed TLS 4.0: + - Hashes: md5.h, ripemd160.h, sha1.h, sha3.h, sha256.h, sha512.h; + - Pseudorandom generation: ctr_drbg.h, hmac_drbg.h. + - Cipher primitives: aes.h, aria.h, camellia.h, chacha20.h, + chachapoly.h, poly1305.h; + - Cipher modes: ccm.h, cipher.h, cmac.h, gcm.h, hkdf.h; + - Private key encryption mechanisms: pkcs5.h, pkcs12.h. + - Asymmetric cryptography: bignum.h, dhm.h, ecdh.h, ecdsa.h, ecjpake.h, + ecp.h, rsa.h. + The cryptographic mechanisms remain present, but they will only be + accessible via the PSA API (psa_xxx functions introduced in + Mbed TLS 2.17.0) and, where relevant, PK. From aada0c869f8b710fb64d8a4d9df00e9b829d85b0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 7 Aug 2024 23:05:45 +0200 Subject: [PATCH 039/100] Mention the PSA transition guide Signed-off-by: Gilles Peskine --- ChangeLog.d/announce-4.0-removals.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog.d/announce-4.0-removals.txt b/ChangeLog.d/announce-4.0-removals.txt index 9ae61c1219..65f48468f1 100644 --- a/ChangeLog.d/announce-4.0-removals.txt +++ b/ChangeLog.d/announce-4.0-removals.txt @@ -27,3 +27,5 @@ New deprecations The cryptographic mechanisms remain present, but they will only be accessible via the PSA API (psa_xxx functions introduced in Mbed TLS 2.17.0) and, where relevant, PK. + For guidance on migrating application code to the PSA API, please consult + the PSA transition guide (docs/psa-transition.md). From 5e64de034e072a6d563610bdfb4d47448d2cdde8 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 8 Aug 2024 14:41:12 +0200 Subject: [PATCH 040/100] Fix missing bits in crypto mechanisms Signed-off-by: Gilles Peskine --- ChangeLog.d/announce-4.0-removals.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ChangeLog.d/announce-4.0-removals.txt b/ChangeLog.d/announce-4.0-removals.txt index 65f48468f1..02de358dfd 100644 --- a/ChangeLog.d/announce-4.0-removals.txt +++ b/ChangeLog.d/announce-4.0-removals.txt @@ -2,10 +2,10 @@ New deprecations * The following cryptographic mechanisms are planned to be removed in Mbed TLS 4.0: - DES (including 3DES). - - PKCS#1v1.5 encryption (RSA-PKCS1-v1_5). (OAEP, PSS, and PKCS#1v1.5 - signature are staying.) - - Finite-field Diffie-Hellman with custom groups. (RFC 7919 remain - supported.) + - PKCS#1v1.5 encryption/decryption (RSAES-PKCS1-v1_5). + (OAEP, PSS, and PKCS#1v1.5 signature are staying.) + - Finite-field Diffie-Hellman with custom groups. + (RFC 7919 groups remain supported.) - Elliptic curves of size 225 bits or less. * The following mechanisms are planned to be removed from (D)TLS 1.2 in Mbed TLS 4.0: From 086bc911792aedc4b243bf09ffeeccc7cd6e5cc9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 8 Aug 2024 14:45:35 +0200 Subject: [PATCH 041/100] Improve mechanism grouping Signed-off-by: Gilles Peskine --- ChangeLog.d/announce-4.0-removals.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ChangeLog.d/announce-4.0-removals.txt b/ChangeLog.d/announce-4.0-removals.txt index 02de358dfd..d9bbd16338 100644 --- a/ChangeLog.d/announce-4.0-removals.txt +++ b/ChangeLog.d/announce-4.0-removals.txt @@ -16,11 +16,10 @@ New deprecations - All cipher suites using CBC. * The following low-level interfaces are planned to be removed from the public API in Mbed TLS 4.0: - - Hashes: md5.h, ripemd160.h, sha1.h, sha3.h, sha256.h, sha512.h; - - Pseudorandom generation: ctr_drbg.h, hmac_drbg.h. - - Cipher primitives: aes.h, aria.h, camellia.h, chacha20.h, - chachapoly.h, poly1305.h; - - Cipher modes: ccm.h, cipher.h, cmac.h, gcm.h, hkdf.h; + - Hashes: hkdf.h, md5.h, ripemd160.h, sha1.h, sha3.h, sha256.h, sha512.h; + - Pseudorandom generation: ctr_drbg.h, hmac_drbg.h; + - Ciphers and modes: aes.h, aria.h, camellia.h, chacha20.h, chachapoly.h, + cipher.h, cmac.h, gcm.h, poly1305.h; - Private key encryption mechanisms: pkcs5.h, pkcs12.h. - Asymmetric cryptography: bignum.h, dhm.h, ecdh.h, ecdsa.h, ecjpake.h, ecp.h, rsa.h. From 6df289a56fd2c6c65423d585c30a218cd70d4a1b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 8 Aug 2024 14:45:57 +0200 Subject: [PATCH 042/100] More relevant characterisation of PSA being from before 3.0 Signed-off-by: Gilles Peskine --- ChangeLog.d/announce-4.0-removals.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog.d/announce-4.0-removals.txt b/ChangeLog.d/announce-4.0-removals.txt index d9bbd16338..aac1f7d217 100644 --- a/ChangeLog.d/announce-4.0-removals.txt +++ b/ChangeLog.d/announce-4.0-removals.txt @@ -24,7 +24,7 @@ New deprecations - Asymmetric cryptography: bignum.h, dhm.h, ecdh.h, ecdsa.h, ecjpake.h, ecp.h, rsa.h. The cryptographic mechanisms remain present, but they will only be - accessible via the PSA API (psa_xxx functions introduced in - Mbed TLS 2.17.0) and, where relevant, PK. + accessible via the PSA API (psa_xxx functions introduced before + Mbed TLS 2.28.0) and, where relevant, PK. For guidance on migrating application code to the PSA API, please consult the PSA transition guide (docs/psa-transition.md). From a11687e543e47e9984e0de4593d0bc462125a8bd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 8 Aug 2024 14:58:35 +0200 Subject: [PATCH 043/100] Revised presentation of cipher suites Include patterns on the official names. Signed-off-by: Gilles Peskine --- ChangeLog.d/announce-4.0-removals.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/ChangeLog.d/announce-4.0-removals.txt b/ChangeLog.d/announce-4.0-removals.txt index aac1f7d217..5942e3adb5 100644 --- a/ChangeLog.d/announce-4.0-removals.txt +++ b/ChangeLog.d/announce-4.0-removals.txt @@ -7,13 +7,16 @@ New deprecations - Finite-field Diffie-Hellman with custom groups. (RFC 7919 groups remain supported.) - Elliptic curves of size 225 bits or less. - * The following mechanisms are planned to be removed from (D)TLS 1.2 + * The following cipher suites are planned to be removed from (D)TLS 1.2 in Mbed TLS 4.0: - - RSA decryption (i.e. cipher suites using RSA without a key exchange: - cipher suites using an RSA signature and ECDHE are staying). - - Static ECDH (ephemeral ECDH, i.e. cipher suites using ECDHE, is staying). - - Finite-field Diffie-Hellman (i.e. DHE; ECDHE is staying) - - All cipher suites using CBC. + - TLS_RSA_* (including TLS_RSA_PSK_*), i.e. cipher suites using + RSA decryption. + (RSA signatures, i.e. TLS_ECDHE_RSA_*, are staying.) + - TLS_ECDH_*, i.e. cipher suites using static ECDH. + (Ephemeral ECDH, i.e. TLS_ECDHE_*, is staying.) + - TLS_DHE_*, i.e. cipher suites using finite-field Diffie-Hellman. + (Ephemeral ECDH, i.e. TLS_ECDHE_*, is staying.) + - TLS_*CBC*, i.e. all cipher suites using CBC. * The following low-level interfaces are planned to be removed from the public API in Mbed TLS 4.0: - Hashes: hkdf.h, md5.h, ripemd160.h, sha1.h, sha3.h, sha256.h, sha512.h; From aaa96721d11510633299c569a88812feed5bb3bd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 7 Aug 2024 20:09:49 +0200 Subject: [PATCH 044/100] Improve documentation in some tests Signed-off-by: Gilles Peskine --- tests/suites/test_suite_psa_crypto_init.function | 2 ++ ...test_suite_psa_crypto_slot_management.function | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function index 2fd282ec61..954560a24e 100644 --- a/tests/suites/test_suite_psa_crypto_init.function +++ b/tests/suites/test_suite_psa_crypto_init.function @@ -219,6 +219,8 @@ void init_deinit(int count) } PSA_DONE(); } +exit: + PSA_DONE(); } /* END_CASE */ diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function index 013945e759..f679f2e889 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.function +++ b/tests/suites/test_suite_psa_crypto_slot_management.function @@ -847,6 +847,16 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MAX_VOLATILE_KEYS */ +/* + * 1. Fill the key store with volatile keys. + * 2. Check that attempting to create another volatile key fails without + * corrupting the key store. + * 3. Destroy the key specified by key_to_destroy. This is the number of the + * key in creation order (e.g. 0 means the first key that was created). + * It can also be a negative value to count in reverse order (e.g. + * -1 means to destroy the last key that was created). + * 4. Check that creating another volatile key succeeds. + */ void fill_key_store(int key_to_destroy_arg) { mbedtls_svc_key_id_t *keys = NULL; @@ -912,6 +922,11 @@ void fill_key_store(int key_to_destroy_arg) replacement_value, sizeof(replacement_value), &keys[key_to_destroy]); PSA_ASSERT(status); + /* Since the key store was full except for one key, the new key must be + * in the same slot in the key store as the destroyed key. + * Since volatile keys IDs are assigned based on which slot contains + * the key, the new key should have the same ID as the destroyed key. + */ TEST_ASSERT(mbedtls_svc_key_id_equal(reused_id, keys[key_to_destroy])); /* Check that the keys are not corrupted and destroy them. */ From 2bfd749e862a7a437722bb338693c79a20aaea02 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 31 May 2024 18:38:36 +0200 Subject: [PATCH 045/100] Dynamic key store: new compilation option Create a new compilation option for a dynamically resized key store. The implementation will follow in subsequent commits. This option is off by default with custom configuration files, which is best for typical deployments on highly constrained platforms. This option is on by default with the provided configuration file, which is best for typical deployments on relatively high-end platforms. Signed-off-by: Gilles Peskine --- include/mbedtls/mbedtls_config.h | 23 ++++++++++++++++++- ...test_suite_psa_crypto_slot_management.data | 4 ++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index b7515f3a8c..7ed1a433ba 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -1414,6 +1414,23 @@ */ //#define MBEDTLS_PSA_CRYPTO_SPM +/** + * \def MBEDTLS_PSA_KEY_STORE_DYNAMIC + * + * Dynamically resize the PSA key store to accommodate any number of + * volatile keys (until the heap memory is exhausted). + * + * If this option is disabled, the key store has a fixed size + * #MBEDTLS_PSA_KEY_SLOT_COUNT for volatile keys and loaded persistent keys + * together. + * + * This option has no effect when #MBEDTLS_PSA_CRYPTO_C is disabled. + * + * Module: library/psa_crypto.c + * Requires: MBEDTLS_PSA_CRYPTO_C + */ +#define MBEDTLS_PSA_KEY_STORE_DYNAMIC + /** * Uncomment to enable p256-m. This is an alternative implementation of * key generation, ECDH and (randomized) ECDSA on the curve SECP256R1. @@ -4026,9 +4043,13 @@ /** \def MBEDTLS_PSA_KEY_SLOT_COUNT * - * The maximum amount of PSA keys simultaneously in memory. This counts all + * When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled, + * the maximum amount of PSA keys simultaneously in memory. This counts all * volatile keys, plus loaded persistent keys. * + * When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, + * the maximum number of loaded persistent keys. + * * Currently, persistent keys do not need to be loaded all the time while * a multipart operation is in progress, only while the operation is being * set up. This may change in future versions of the library. diff --git a/tests/suites/test_suite_psa_crypto_slot_management.data b/tests/suites/test_suite_psa_crypto_slot_management.data index af3b946754..1bf300ade6 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.data +++ b/tests/suites/test_suite_psa_crypto_slot_management.data @@ -129,9 +129,9 @@ depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C # writing, this happens in builds where AES uses a PSA driver and the # PSA RNG uses AES-CTR_DRBG through the PSA AES. # Pick a key id that's in the middle of the volatile key ID range. -# That works out both when MBEDTLS_PSA_KEY_SLOT_DYNAMIC is enabled and +# That works out both when MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled and # volatile key IDs are assigned starting with the lowest value, and when -# MBEDTLS_PSA_KEY_SLOT_DYNAMIC is disabled and volatile key IDs are assigned +# MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled and volatile key IDs are assigned # starting with the highest values. open_fail:(PSA_KEY_ID_VOLATILE_MIN + PSA_KEY_ID_VOLATILE_MAX) / 2:PSA_ERROR_DOES_NOT_EXIST From 5064af62b6011e81c1da7f6f6339983a067c1497 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 7 Jun 2024 13:53:28 +0200 Subject: [PATCH 046/100] Dynamic key store: preparatory refactoring Add some abstractions around code that traverses the key store, in preparation for adding support for MBEDTLS_PSA_KEY_STORE_DYNAMIC. No intended behavior change. The generated machine code should be almost the same with an optimizing compiler (in principle, it could be the same with sufficient constant folding and inlining, but in practice it will likely be a few byes larger), Signed-off-by: Gilles Peskine --- library/psa_crypto_slot_management.c | 150 +++++++++++++++++++-------- 1 file changed, 109 insertions(+), 41 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 9b297c9c08..7e0a1c12c1 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -58,6 +58,11 @@ MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN | +#define PERSISTENT_KEY_CACHE_COUNT MBEDTLS_PSA_KEY_SLOT_COUNT +#define KEY_SLICE_COUNT 1u +#define KEY_SLOT_CACHE_SLICE_INDEX 0 + + typedef struct { psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT]; uint8_t key_slots_initialized; @@ -65,10 +70,6 @@ typedef struct { static psa_global_data_t global_data; -MBEDTLS_STATIC_ASSERT(ARRAY_LENGTH(global_data.key_slots) <= - PSA_KEY_ID_VOLATILE_MAX - PSA_KEY_ID_VOLATILE_MIN + 1, - "The key slot array is larger than the volatile key ID range"); - static uint8_t psa_get_key_slots_initialized(void) { uint8_t initialized; @@ -86,6 +87,73 @@ static uint8_t psa_get_key_slots_initialized(void) return initialized; } + + +/** The length of the given slice in the key slot table. + * + * \param slice_idx The slice number. It must satisfy + * 0 <= slice_idx < KEY_SLICE_COUNT. + * + * \return The number of elements in the given slice. + */ +static inline size_t key_slice_length(size_t slice_idx); + +/** Get a pointer to the slot where the given volatile key is located. + * + * \param key_id The key identifier. It must be a valid volatile key + * identifier. + * \return A pointer to the only slot that the given key + * can be in. Note that the slot may be empty or + * contain a different key. + */ +static inline psa_key_slot_t *get_volatile_key_slot(psa_key_id_t key_id); + +/** Get a pointer to an entry in the persistent key cache. + * + * \param slot_idx The index in the table. It must satisfy + * 0 <= slot_idx < PERSISTENT_KEY_CACHE_COUNT. + * \return A pointer to the slot containing the given + * persistent key cache entry. + */ +static inline psa_key_slot_t *get_persistent_key_slot(size_t slot_idx); + +/** Get a pointer to a slot given by slice and index. + * + * \param slice_idx The slice number. It must satisfy + * 0 <= slice_idx < KEY_SLICE_COUNT. + * \param slot_idx An index in the given slice. It must satisfy + * 0 <= slot_idx < key_slice_length(slice_idx). + * + * \return A pointer to the given slot. + */ +static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx); + +static inline size_t key_slice_length(size_t slice_idx) +{ + (void) slice_idx; + return ARRAY_LENGTH(global_data.key_slots); +} + +static inline psa_key_slot_t *get_volatile_key_slot(psa_key_id_t key_id) +{ + MBEDTLS_STATIC_ASSERT(ARRAY_LENGTH(global_data.key_slots) <= + PSA_KEY_ID_VOLATILE_MAX - PSA_KEY_ID_VOLATILE_MIN + 1, + "The key slot array is larger than the volatile key ID range"); + return &global_data.key_slots[key_id - PSA_KEY_ID_VOLATILE_MIN]; +} + +static inline psa_key_slot_t *get_persistent_key_slot(size_t slot_idx) +{ + return &global_data.key_slots[slot_idx]; +} + +static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx) +{ + (void) slice_idx; + return &global_data.key_slots[slot_idx]; +} + + int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok) { psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key); @@ -147,7 +215,7 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory( psa_key_slot_t *slot = NULL; if (psa_key_id_is_volatile(key_id)) { - slot = &global_data.key_slots[key_id - PSA_KEY_ID_VOLATILE_MIN]; + slot = get_volatile_key_slot(key_id); /* Check if both the PSA key identifier key_id and the owner * identifier of key match those of the key slot. */ @@ -162,8 +230,8 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory( return PSA_ERROR_INVALID_HANDLE; } - for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) { - slot = &global_data.key_slots[slot_idx]; + for (slot_idx = 0; slot_idx < PERSISTENT_KEY_CACHE_COUNT; slot_idx++) { + slot = get_persistent_key_slot(slot_idx); /* Only consider slots which are in a full state. */ if ((slot->state == PSA_SLOT_FULL) && (mbedtls_svc_key_id_equal(key, slot->attr.id))) { @@ -197,13 +265,13 @@ psa_status_t psa_initialize_key_slots(void) void psa_wipe_all_key_slots(void) { - size_t slot_idx; - - for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) { - psa_key_slot_t *slot = &global_data.key_slots[slot_idx]; - slot->registered_readers = 1; - slot->state = PSA_SLOT_PENDING_DELETION; - (void) psa_wipe_key_slot(slot); + for (size_t slice_idx = 0; slice_idx < KEY_SLICE_COUNT; slice_idx++) { + for (size_t slot_idx = 0; slot_idx < key_slice_length(slice_idx); slot_idx++) { + psa_key_slot_t *slot = get_key_slot(slice_idx, slot_idx); + slot->registered_readers = 1; + slot->state = PSA_SLOT_PENDING_DELETION; + (void) psa_wipe_key_slot(slot); + } } /* The global data mutex is already held when calling this function. */ global_data.key_slots_initialized = 0; @@ -222,8 +290,8 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, } selected_slot = unused_persistent_key_slot = NULL; - for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) { - psa_key_slot_t *slot = &global_data.key_slots[slot_idx]; + for (slot_idx = 0; slot_idx < PERSISTENT_KEY_CACHE_COUNT; slot_idx++) { + psa_key_slot_t *slot = get_key_slot(KEY_SLOT_CACHE_SLICE_INDEX, slot_idx); if (slot->state == PSA_SLOT_EMPTY) { selected_slot = slot; break; @@ -689,34 +757,34 @@ psa_status_t psa_purge_key(mbedtls_svc_key_id_t key) void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats) { - size_t slot_idx; - memset(stats, 0, sizeof(*stats)); - for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) { - const psa_key_slot_t *slot = &global_data.key_slots[slot_idx]; - if (psa_key_slot_has_readers(slot)) { - ++stats->locked_slots; - } - if (slot->state == PSA_SLOT_EMPTY) { - ++stats->empty_slots; - continue; - } - if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { - ++stats->volatile_slots; - } else { - psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id); - ++stats->persistent_slots; - if (id > stats->max_open_internal_key_id) { - stats->max_open_internal_key_id = id; + for (size_t slice_idx = 0; slice_idx < KEY_SLICE_COUNT; slice_idx++) { + for (size_t slot_idx = 0; slot_idx < key_slice_length(slice_idx); slot_idx++) { + const psa_key_slot_t *slot = get_key_slot(slice_idx, slot_idx); + if (psa_key_slot_has_readers(slot)) { + ++stats->locked_slots; } - } - if (PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime) != - PSA_KEY_LOCATION_LOCAL_STORAGE) { - psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id); - ++stats->external_slots; - if (id > stats->max_open_external_key_id) { - stats->max_open_external_key_id = id; + if (slot->state == PSA_SLOT_EMPTY) { + ++stats->empty_slots; + continue; + } + if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { + ++stats->volatile_slots; + } else { + psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id); + ++stats->persistent_slots; + if (id > stats->max_open_internal_key_id) { + stats->max_open_internal_key_id = id; + } + } + if (PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime) != + PSA_KEY_LOCATION_LOCAL_STORAGE) { + psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id); + ++stats->external_slots; + if (id > stats->max_open_external_key_id) { + stats->max_open_external_key_id = id; + } } } } From b5891cc2cd9b8e8a181f8624ce2d348a3067e379 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 16 Jul 2024 20:49:36 +0200 Subject: [PATCH 047/100] Dynamic key store: disable full-key-store tests It's impractical to fill the key store when it can grow to accommodate millions of keys. A later commit will restore those tests in test configurations with the dynamic key store. Signed-off-by: Gilles Peskine --- ...test_suite_psa_crypto_slot_management.function | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function index f679f2e889..b2d3f29735 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.function +++ b/tests/suites/test_suite_psa_crypto_slot_management.function @@ -101,7 +101,11 @@ exit: /* Currently, there is always a maximum number of volatile keys that can * realistically be reached in tests. When we add configurations where this * is not true, undefine the macro in such configurations. */ +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) +#undef MAX_VOLATILE_KEYS +#else /* Static key store */ #define MAX_VOLATILE_KEYS MBEDTLS_PSA_KEY_SLOT_COUNT +#endif /* END_HEADER */ @@ -1028,7 +1032,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */ +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C:!MBEDTLS_PSA_KEY_STORE_DYNAMIC */ void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation() { psa_status_t status; @@ -1068,7 +1072,14 @@ void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation() TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, persistent_key)); /* - * Create the maximum available number of volatile keys + * Create the maximum available number of keys that are locked in + * memory. This can be: + * - volatile keys, when MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled; + * - opened persistent keys (could work, but not currently implemented + * in this test function); + * - keys in use by another thread (we don't do this because it would + * be hard to arrange and we can't control how long the keys are + * locked anyway). */ psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); for (i = 0; i < available_key_slots; i++) { From 47ad2f748492fa220e9feebb8db011896372548a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 10 Jun 2024 11:42:41 +0200 Subject: [PATCH 048/100] psa_key_slot_t: different fields in free vs occupied slots Place some fields of psa_key_slot_t in a union, to prepare for a new field in free slots that should not require extra memory. For occupied slots, place only the registered_readers field in the union, not other fields, to minimize textual changes. All fields could move to the union except state (also needed in free slots) and attr (which must stay first to reduce the code size, because it is accessed at many call sites). Signed-off-by: Gilles Peskine --- library/psa_crypto.c | 8 ++-- library/psa_crypto_core.h | 62 ++++++++++++++++------------ library/psa_crypto_slot_management.c | 10 ++--- library/psa_crypto_slot_management.h | 4 +- 4 files changed, 46 insertions(+), 38 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 25014e66ed..a67304fef2 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1210,15 +1210,15 @@ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot) case PSA_SLOT_PENDING_DELETION: /* In this state psa_wipe_key_slot() must only be called if the * caller is the last reader. */ - if (slot->registered_readers != 1) { - MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 1); + if (slot->var.occupied.registered_readers != 1) { + MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->var.occupied.registered_readers == 1); status = PSA_ERROR_CORRUPTION_DETECTED; } break; case PSA_SLOT_FILLING: /* In this state registered_readers must be 0. */ - if (slot->registered_readers != 0) { - MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 0); + if (slot->var.occupied.registered_readers != 0) { + MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->var.occupied.registered_readers == 0); status = PSA_ERROR_CORRUPTION_DETECTED; } break; diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index e7ff151a8b..a893c149ab 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -59,6 +59,8 @@ typedef enum { * and metadata for one key. */ typedef struct { + /* This field is accessed in a lot of places. Putting it first + * reduces the code size. */ psa_key_attributes_t attr; /* @@ -81,32 +83,38 @@ typedef struct { * PSA_SLOT_FULL. */ psa_key_slot_state_t state; - /* - * Number of functions registered as reading the material in the key slot. - * - * Library functions must not write directly to registered_readers - * - * A function must call psa_register_read(slot) before reading the current - * contents of the slot for an operation. - * They then must call psa_unregister_read(slot) once they have finished - * reading the current contents of the slot. If the key slot mutex is not - * held (when mutexes are enabled), this call must be done via a call to - * psa_unregister_read_under_mutex(slot). - * A function must call psa_key_slot_has_readers(slot) to check if - * the slot is in use for reading. - * - * This counter is used to prevent resetting the key slot while the library - * may access it. For example, such control is needed in the following - * scenarios: - * . In case of key slot starvation, all key slots contain the description - * of a key, and the library asks for the description of a persistent - * key not present in the key slots, the key slots currently accessed by - * the library cannot be reclaimed to free a key slot to load the - * persistent key. - * . In case of a multi-threaded application where one thread asks to close - * or purge or destroy a key while it is in use by the library through - * another thread. */ - size_t registered_readers; + union { + struct { + /* + * Number of functions registered as reading the material in the key slot. + * + * Library functions must not write directly to registered_readers + * + * A function must call psa_register_read(slot) before reading + * the current contents of the slot for an operation. + * They then must call psa_unregister_read(slot) once they have + * finished reading the current contents of the slot. If the key + * slot mutex is not held (when mutexes are enabled), this call + * must be done via a call to + * psa_unregister_read_under_mutex(slot). + * A function must call psa_key_slot_has_readers(slot) to check if + * the slot is in use for reading. + * + * This counter is used to prevent resetting the key slot while + * the library may access it. For example, such control is needed + * in the following scenarios: + * . In case of key slot starvation, all key slots contain the + * description of a key, and the library asks for the + * description of a persistent key not present in the + * key slots, the key slots currently accessed by the + * library cannot be reclaimed to free a key slot to load + * the persistent key. + * . In case of a multi-threaded application where one thread + * asks to close or purge or destroy a key while it is in use + * by the library through another thread. */ + size_t registered_readers; + } occupied; + } var; /* Dynamically allocated key data buffer. * Format as specified in psa_export_key(). */ @@ -169,7 +177,7 @@ typedef struct { */ static inline int psa_key_slot_has_readers(const psa_key_slot_t *slot) { - return slot->registered_readers > 0; + return slot->var.occupied.registered_readers > 0; } #if defined(MBEDTLS_PSA_CRYPTO_SE_C) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 7e0a1c12c1..327be0a4f3 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -268,7 +268,7 @@ void psa_wipe_all_key_slots(void) for (size_t slice_idx = 0; slice_idx < KEY_SLICE_COUNT; slice_idx++) { for (size_t slot_idx = 0; slot_idx < key_slice_length(slice_idx); slot_idx++) { psa_key_slot_t *slot = get_key_slot(slice_idx, slot_idx); - slot->registered_readers = 1; + slot->var.occupied.registered_readers = 1; slot->state = PSA_SLOT_PENDING_DELETION; (void) psa_wipe_key_slot(slot); } @@ -568,12 +568,12 @@ psa_status_t psa_unregister_read(psa_key_slot_t *slot) /* If we are the last reader and the slot is marked for deletion, * we must wipe the slot here. */ if ((slot->state == PSA_SLOT_PENDING_DELETION) && - (slot->registered_readers == 1)) { + (slot->var.occupied.registered_readers == 1)) { return psa_wipe_key_slot(slot); } if (psa_key_slot_has_readers(slot)) { - slot->registered_readers--; + slot->var.occupied.registered_readers--; return PSA_SUCCESS; } @@ -707,7 +707,7 @@ psa_status_t psa_close_key(psa_key_handle_t handle) return status; } - if (slot->registered_readers == 1) { + if (slot->var.occupied.registered_readers == 1) { status = psa_wipe_key_slot(slot); } else { status = psa_unregister_read(slot); @@ -742,7 +742,7 @@ psa_status_t psa_purge_key(mbedtls_svc_key_id_t key) } if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) && - (slot->registered_readers == 1)) { + (slot->var.occupied.registered_readers == 1)) { status = psa_wipe_key_slot(slot); } else { status = psa_unregister_read(slot); diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 88b7c837cc..cccf8f2f19 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -174,10 +174,10 @@ static inline psa_status_t psa_key_slot_state_transition( static inline psa_status_t psa_register_read(psa_key_slot_t *slot) { if ((slot->state != PSA_SLOT_FULL) || - (slot->registered_readers >= SIZE_MAX)) { + (slot->var.occupied.registered_readers >= SIZE_MAX)) { return PSA_ERROR_CORRUPTION_DETECTED; } - slot->registered_readers++; + slot->var.occupied.registered_readers++; return PSA_SUCCESS; } From e8199f574c2a1360a11fa4d6c71d0f1b14a285df Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 10 Jun 2024 11:53:33 +0200 Subject: [PATCH 049/100] Dynamic key store: implementation When MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, key slots are now organized in multiple slices. The slices are allocated on demand, which allows the key store to grow. The size of slices grows exponentially, which allows reaching a large number of slots with a small (static) number of slices without too much overhead. Maintain a linked list of free slots in each slice. This way, allocating a slot takes O(1) time unless a slice needs to be allocated. In this commit, slices are only ever freed when deinitializing the key store. This should be improved in the future to free empty slices. To avoid growing the persistent key cache without control, the persistent key cache has a fixed size (reusing MBEDTLS_PSA_KEY_SLOT_COUNT to avoid creating yet another option). When MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled. no semantic change and minimal changes to the code. Signed-off-by: Gilles Peskine --- library/psa_crypto.c | 29 ++- library/psa_crypto_core.h | 30 ++- library/psa_crypto_slot_management.c | 315 ++++++++++++++++++++++++++- library/psa_crypto_slot_management.h | 44 +++- 4 files changed, 398 insertions(+), 20 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a67304fef2..c4f41db10b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1232,6 +1232,11 @@ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot) status = PSA_ERROR_CORRUPTION_DETECTED; } +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + size_t slice_index = slot->slice_index; +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + + /* Multipart operations may still be using the key. This is safe * because all multipart operation objects are independent from * the key slot: if they need to access the key after the setup @@ -1242,6 +1247,17 @@ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot) * zeroize because the metadata is not particularly sensitive. * This memset also sets the slot's state to PSA_SLOT_EMPTY. */ memset(slot, 0, sizeof(*slot)); + +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + /* If the slot is already corrupted, something went deeply wrong, + * like a thread still using the slot or a stray pointer leading + * to the slot's memory being used for another object. Let the slot + * leak rather than make the corruption worse. */ + if (status == PSA_SUCCESS) { + status = psa_free_key_slot(slice_index, slot); + } +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + return status; } @@ -1753,8 +1769,6 @@ static psa_status_t psa_start_key_creation( psa_se_drv_table_entry_t **p_drv) { psa_status_t status; - psa_key_id_t volatile_key_id; - psa_key_slot_t *slot; (void) method; *p_drv = NULL; @@ -1764,11 +1778,16 @@ static psa_status_t psa_start_key_creation( return status; } + int key_is_volatile = PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime); + psa_key_id_t volatile_key_id; + #if defined(MBEDTLS_THREADING_C) PSA_THREADING_CHK_RET(mbedtls_mutex_lock( &mbedtls_threading_key_slot_mutex)); #endif - status = psa_reserve_free_key_slot(&volatile_key_id, p_slot); + status = psa_reserve_free_key_slot( + key_is_volatile ? &volatile_key_id : NULL, + p_slot); #if defined(MBEDTLS_THREADING_C) PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( &mbedtls_threading_key_slot_mutex)); @@ -1776,7 +1795,7 @@ static psa_status_t psa_start_key_creation( if (status != PSA_SUCCESS) { return status; } - slot = *p_slot; + psa_key_slot_t *slot = *p_slot; /* We're storing the declared bit-size of the key. It's up to each * creation mechanism to verify that this information is correct. @@ -1787,7 +1806,7 @@ static psa_status_t psa_start_key_creation( * definition. */ slot->attr = *attributes; - if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { + if (key_is_volatile) { #if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) slot->attr.id = volatile_key_id; #else diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index a893c149ab..91ef0bfb78 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -80,10 +80,38 @@ typedef struct { * slots that are in a suitable state for the function. * For example, psa_get_and_lock_key_slot_in_memory, which finds a slot * containing a given key ID, will only check slots whose state variable is - * PSA_SLOT_FULL. */ + * PSA_SLOT_FULL. + */ psa_key_slot_state_t state; +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + /* The index of the slice containing this slot. + * This field must be filled if the slot contains a key + * (including keys being created or destroyed), and can be either + * filled or 0 when the slot is free. */ + uint8_t slice_index; +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + union { + struct { + /* The index of the next slot in the free list for this + * slice, relative * to the next array element. + * + * That is, 0 means the next slot, 1 means the next slot + * but one, etc. -1 would mean the slot itself. -2 means + * the previous slot, etc. + * + * If this is beyond the array length, the free list ends with the + * current element. + * + * The reason for this strange encoding is that 0 means the next + * element. This way, when we allocate a slice and initialize it + * to all-zero, the slice is ready for use, with a free list that + * consists of all the slots in order. + */ + int32_t next_free_relative_to_next; + } free; + struct { /* * Number of functions registered as reading the material in the key slot. diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 327be0a4f3..eef65dc142 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -58,13 +58,110 @@ MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN | +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + +/* Dynamic key store. + * + * The key store consists of multiple slices. + * + * The volatile keys are stored in variable-sized tables called slices. + * Slices are allocated on demand and deallocated when possible. + * The size of slices increases exponentially, so the average overhead + * (number of slots that are allocated but not used) is roughly + * proportional to the number of keys (with a factor that grows + * when the key store is fragmented). + * + * One slice is dedicated to the cache of persistent and built-in keys. + * For simplicity, they are separated from volatile keys. This cache + * slice has a fixed size and has the slice index KEY_SLOT_CACHE_SLICE_INDEX, + * located after the slices for volatile keys. + */ + +/* Size of slice 0 containing the cache of persistent and built-in keys. */ +#define PERSISTENT_KEY_CACHE_COUNT MBEDTLS_PSA_KEY_SLOT_COUNT + +/* Volatile keys are stored in slices 1 through KEY_SLICE_COUNT inclusive. + * Each slice is twice the size of the previous slice. + * Volatile key identifiers encode the slice number as follows: + * bits 30..31: 0b10 (mandated by the PSA Crypto specification). + * bits 25..29: slice index (0...KEY_SLOT_VOLATILE_SLICE_COUNT-1) + * bits 0..24: slot index in slice + */ +#define KEY_ID_SLOT_INDEX_WIDTH 25u +#define KEY_ID_SLICE_INDEX_WIDTH 5u + +#define KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH 16u +#define KEY_SLOT_VOLATILE_SLICE_COUNT 22u +#define KEY_SLICE_COUNT (KEY_SLOT_VOLATILE_SLICE_COUNT + 1u) +#define KEY_SLOT_CACHE_SLICE_INDEX KEY_SLOT_VOLATILE_SLICE_COUNT + +#if KEY_ID_SLICE_INDEX_WIDTH + KEY_ID_SLOT_INDEX_WIDTH > 30 +#error "Not enough room in volatile key IDs for slice index and slot index" +#endif +#if KEY_SLICE_COUNT >= (1 << KEY_ID_SLICE_INDEX_WIDTH) - 1 +#error "Too many slices to fit the slice index in a volatile key ID" +#endif +#define KEY_SLICE_LENGTH_MAX \ + (KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH << (KEY_SLOT_VOLATILE_SLICE_COUNT - 1)) +#if KEY_SLICE_LENGTH_MAX > 1 << KEY_ID_SLOT_INDEX_WIDTH +#error "Not enough room in volatile key IDs for a slot index in the largest slice" +#endif +#if KEY_ID_SLICE_INDEX_WIDTH > 8 +#error "Slice index does not fit in uint8_t for psa_key_slot_t::slice_index" +#endif + + +/* Calculate the volatile key id to use for a given slot. + * This function assumes valid parameter values. */ +static psa_key_id_t volatile_key_id_of_index(size_t slice_idx, + size_t slot_idx) +{ + return 0x40000000u | (slice_idx << KEY_ID_SLOT_INDEX_WIDTH) | slot_idx; +} + +/* Calculate the slice containing the given volatile key. + * This function assumes valid parameter values. */ +static size_t slice_index_of_volatile_key_id(psa_key_id_t key_id) +{ + size_t mask = (1LU << KEY_ID_SLICE_INDEX_WIDTH) - 1; + return (key_id >> KEY_ID_SLOT_INDEX_WIDTH) & mask; +} + +/* Calculate the index of the slot containing the given volatile key. + * This function assumes valid parameter values. */ +static size_t slot_index_of_volatile_key_id(psa_key_id_t key_id) +{ + return key_id & ((1LU << KEY_ID_SLOT_INDEX_WIDTH) - 1); +} + +/* In global_data.first_free_slot_index, use this special value to + * indicate that the slice is full. */ +#define FREE_SLOT_INDEX_NONE ((size_t) -1) + +#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + +/* Static key store. + * + * All the keys (volatile or persistent) are in a single slice. + * We only use slices as a concept to allow some differences between + * static and dynamic key store management to be buried in auxiliary + * functions. + */ + #define PERSISTENT_KEY_CACHE_COUNT MBEDTLS_PSA_KEY_SLOT_COUNT #define KEY_SLICE_COUNT 1u #define KEY_SLOT_CACHE_SLICE_INDEX 0 +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + typedef struct { +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + psa_key_slot_t *key_slices[KEY_SLICE_COUNT]; + size_t first_free_slot_index[KEY_SLOT_VOLATILE_SLICE_COUNT]; +#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT]; +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ uint8_t key_slots_initialized; } psa_global_data_t; @@ -128,6 +225,46 @@ static inline psa_key_slot_t *get_persistent_key_slot(size_t slot_idx); */ static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx); +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + +static inline size_t key_slice_length(size_t slice_idx) +{ + if (slice_idx == KEY_SLOT_CACHE_SLICE_INDEX) { + return PERSISTENT_KEY_CACHE_COUNT; + } else { + return KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH << slice_idx; + } +} + +static inline psa_key_slot_t *get_volatile_key_slot(psa_key_id_t key_id) +{ + size_t slice_idx = slice_index_of_volatile_key_id(key_id); + if (slice_idx >= KEY_SLOT_VOLATILE_SLICE_COUNT) { + return NULL; + } + size_t slot_idx = slot_index_of_volatile_key_id(key_id); + if (slot_idx >= key_slice_length(slice_idx)) { + return NULL; + } + psa_key_slot_t *slice = global_data.key_slices[slice_idx]; + if (slice == NULL) { + return NULL; + } + return &slice[slot_idx]; +} + +static inline psa_key_slot_t *get_persistent_key_slot(size_t slot_idx) +{ + return &global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX][slot_idx]; +} + +static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx) +{ + return &global_data.key_slices[slice_idx][slot_idx]; +} + +#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + static inline size_t key_slice_length(size_t slice_idx) { (void) slice_idx; @@ -153,6 +290,9 @@ static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx) return &global_data.key_slots[slot_idx]; } +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + + int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok) { @@ -219,8 +359,9 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory( /* Check if both the PSA key identifier key_id and the owner * identifier of key match those of the key slot. */ - if ((slot->state == PSA_SLOT_FULL) && - (mbedtls_svc_key_id_equal(key, slot->attr.id))) { + if (slot != NULL && + slot->state == PSA_SLOT_FULL && + mbedtls_svc_key_id_equal(key, slot->attr.id)) { status = PSA_SUCCESS; } else { status = PSA_ERROR_DOES_NOT_EXIST; @@ -254,11 +395,21 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory( psa_status_t psa_initialize_key_slots(void) { +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX] = + mbedtls_calloc(PERSISTENT_KEY_CACHE_COUNT, + sizeof(*global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX])); + if (global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX] == NULL) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } +#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ /* Nothing to do: program startup and psa_wipe_all_key_slots() both * guarantee that the key slots are initialized to all-zero, which * means that all the key slots are in a valid, empty state. The global * data mutex is already held when calling this function, so no need to * lock it here, to set the flag. */ +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + global_data.key_slots_initialized = 1; return PSA_SUCCESS; } @@ -266,17 +417,137 @@ psa_status_t psa_initialize_key_slots(void) void psa_wipe_all_key_slots(void) { for (size_t slice_idx = 0; slice_idx < KEY_SLICE_COUNT; slice_idx++) { +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + if (global_data.key_slices[slice_idx] == NULL) { + continue; + } +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ for (size_t slot_idx = 0; slot_idx < key_slice_length(slice_idx); slot_idx++) { psa_key_slot_t *slot = get_key_slot(slice_idx, slot_idx); + if (slot->state == PSA_SLOT_EMPTY) { + /* Don't call psa_wipe_key_slot() on an already-empty slot. + * It rejects that case anyway, though we bypass it by setting + * the slot state to PENDING_DELETION. + * Also, when MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, + * psa_wipe_key_slot() needs to have a valid slice_index + * field, but that value might not be correct in a + * free slot. */ + continue; + } slot->var.occupied.registered_readers = 1; slot->state = PSA_SLOT_PENDING_DELETION; (void) psa_wipe_key_slot(slot); } +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + mbedtls_free(global_data.key_slices[slice_idx]); + global_data.key_slices[slice_idx] = NULL; +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ } + +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + for (size_t slice_idx = 0; slice_idx < KEY_SLOT_VOLATILE_SLICE_COUNT; slice_idx++) { + global_data.first_free_slot_index[slice_idx] = 0; + } +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + /* The global data mutex is already held when calling this function. */ global_data.key_slots_initialized = 0; } +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + +static psa_status_t psa_allocate_volatile_key_slot(psa_key_id_t *key_id, + psa_key_slot_t **p_slot) +{ + size_t slice_idx; + for (slice_idx = 0; slice_idx < KEY_SLOT_VOLATILE_SLICE_COUNT; slice_idx++) { + if (global_data.first_free_slot_index[slice_idx] != FREE_SLOT_INDEX_NONE) { + break; + } + } + if (slice_idx == KEY_SLOT_VOLATILE_SLICE_COUNT) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + + if (global_data.key_slices[slice_idx] == NULL) { + global_data.key_slices[slice_idx] = + mbedtls_calloc(key_slice_length(slice_idx), + sizeof(psa_key_slot_t)); + if (global_data.key_slices[slice_idx] == NULL) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + } + psa_key_slot_t *slice = global_data.key_slices[slice_idx]; + + size_t slot_idx = global_data.first_free_slot_index[slice_idx]; + *key_id = volatile_key_id_of_index(slice_idx, slot_idx); + + psa_key_slot_t *slot = &slice[slot_idx]; + size_t next_free = slot_idx + 1 + slot->var.free.next_free_relative_to_next; + if (next_free >= key_slice_length(slice_idx)) { + next_free = FREE_SLOT_INDEX_NONE; + } + global_data.first_free_slot_index[slice_idx] = next_free; + /* The .next_free field is not meaningful when the slot is not free, + * so give it the same content as freshly initialized memory. */ + slot->var.free.next_free_relative_to_next = 0; + + psa_status_t status = psa_key_slot_state_transition(slot, + PSA_SLOT_EMPTY, + PSA_SLOT_FILLING); + if (status != PSA_SUCCESS) { + /* The only reason for failure is if the slot state was not empty. + * This indicates that something has gone horribly wrong. + * In this case, we leave the slot out of the free list, and stop + * modifying it. This minimizes any further corruption. The slot + * is a memory leak, but that's a lesser evil. */ + return status; + } + + *p_slot = slot; + slot->slice_index = slice_idx; + return PSA_SUCCESS; +} + +psa_status_t psa_free_key_slot(size_t slice_idx, + psa_key_slot_t *slot) +{ + + if (slice_idx == KEY_SLOT_CACHE_SLICE_INDEX) { + /* This is a cache entry. We don't maintain a free list, so + * there's nothing to do. */ + return PSA_SUCCESS; + } + if (slice_idx >= KEY_SLOT_VOLATILE_SLICE_COUNT) { + return PSA_ERROR_CORRUPTION_DETECTED; + } + + psa_key_slot_t *slice = global_data.key_slices[slice_idx]; + psa_key_slot_t *slice_end = slice + key_slice_length(slice_idx); + if (slot < slice || slot >= slice_end) { + /* The slot isn't actually in the slice! We can't detect that + * condition for sure, because the pointer comparison itself is + * undefined behavior in that case. That same condition makes the + * subtraction to calculate the slot index also UB. + * Give up now to avoid causing further corruption. + */ + return PSA_ERROR_CORRUPTION_DETECTED; + } + size_t slot_idx = slot - slice; + + size_t next_free = global_data.first_free_slot_index[slice_idx]; + if (next_free >= key_slice_length(slice_idx)) { + /* The slot was full. The newly freed slot thus becomes the + * end of the free list. */ + next_free = key_slice_length(slice_idx); + } + global_data.first_free_slot_index[slice_idx] = slot_idx; + slot->var.free.next_free_relative_to_next = next_free - slot_idx - 1; + + return PSA_SUCCESS; +} +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, psa_key_slot_t **p_slot) { @@ -289,6 +560,17 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, goto error; } + if (volatile_key_id != NULL) { + *volatile_key_id = 0; +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + return psa_allocate_volatile_key_slot(volatile_key_id, p_slot); +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + } + + /* With a dynamic key store, allocate an entry in the cache slice, + * applicable only to non-volatile keys that get cached in RAM. + * With a static key store, allocate an entry in the sole slice, + * applicable to all keys. */ selected_slot = unused_persistent_key_slot = NULL; for (slot_idx = 0; slot_idx < PERSISTENT_KEY_CACHE_COUNT; slot_idx++) { psa_key_slot_t *slot = get_key_slot(KEY_SLOT_CACHE_SLICE_INDEX, slot_idx); @@ -329,8 +611,18 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, goto error; } - *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + - ((psa_key_id_t) (selected_slot - global_data.key_slots)); +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + selected_slot->slice_index = KEY_SLOT_CACHE_SLICE_INDEX; +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + +#if !defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + if (volatile_key_id != NULL) { + /* Refresh slot_idx, for when the slot is not the original + * selected_slot but rather unused_persistent_key_slot. */ + slot_idx = selected_slot - global_data.key_slots; + *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + slot_idx; + } +#endif *p_slot = selected_slot; return PSA_SUCCESS; @@ -339,7 +631,6 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, error: *p_slot = NULL; - *volatile_key_id = 0; return status; } @@ -498,9 +789,8 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, /* Loading keys from storage requires support for such a mechanism */ #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \ defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) - psa_key_id_t volatile_key_id; - status = psa_reserve_free_key_slot(&volatile_key_id, p_slot); + status = psa_reserve_free_key_slot(NULL, p_slot); if (status != PSA_SUCCESS) { #if defined(MBEDTLS_THREADING_C) PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( @@ -760,15 +1050,20 @@ void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats) memset(stats, 0, sizeof(*stats)); for (size_t slice_idx = 0; slice_idx < KEY_SLICE_COUNT; slice_idx++) { +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + if (global_data.key_slices[slice_idx] == NULL) { + continue; + } +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ for (size_t slot_idx = 0; slot_idx < key_slice_length(slice_idx); slot_idx++) { const psa_key_slot_t *slot = get_key_slot(slice_idx, slot_idx); - if (psa_key_slot_has_readers(slot)) { - ++stats->locked_slots; - } if (slot->state == PSA_SLOT_EMPTY) { ++stats->empty_slots; continue; } + if (psa_key_slot_has_readers(slot)) { + ++stats->locked_slots; + } if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { ++stats->volatile_slots; } else { diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index cccf8f2f19..1e6e935b59 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -17,8 +17,10 @@ * * The first #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation * range of key identifiers are reserved for volatile key identifiers. - * A volatile key identifier is equal to #PSA_KEY_ID_VOLATILE_MIN plus the - * index of the key slot containing the volatile key definition. + * + * If \c id is a a volatile key identifier, #PSA_KEY_ID_VOLATILE_MIN - \c id + * indicates the key slot containing the volatile key definition. See + * psa_crypto_slot_management.c for details. */ /** The minimum value for a volatile key identifier. @@ -27,8 +29,12 @@ /** The maximum value for a volatile key identifier. */ +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) +#define PSA_KEY_ID_VOLATILE_MAX (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1) +#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ #define PSA_KEY_ID_VOLATILE_MAX \ (PSA_KEY_ID_VOLATILE_MIN + MBEDTLS_PSA_KEY_SLOT_COUNT - 1) +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ /** Test whether a key identifier is a volatile key identifier. * @@ -113,13 +119,20 @@ void psa_wipe_all_key_slots(void); * If multi-threading is enabled, the caller must hold the * global key slot mutex. * - * \param[out] volatile_key_id On success, volatile key identifier - * associated to the returned slot. + * \param[out] volatile_key_id If null, reserve a cache slot for + * a persistent or built-in key. + * If non-null, allocate a slot for + * a volatile key. + * If non-null, on success, the volatile key + * identifier corresponding with the + * returned slot. * \param[out] p_slot On success, a pointer to the slot. * * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * There were no free key slots. + * When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, there was not + * enough memory to allocate more slots. * \retval #PSA_ERROR_BAD_STATE \emptydescription * \retval #PSA_ERROR_CORRUPTION_DETECTED * This function attempted to operate on a key slot which was in an @@ -128,6 +141,29 @@ void psa_wipe_all_key_slots(void); psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, psa_key_slot_t **p_slot); +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) +/** Return a key slot to the free list. + * + * Call this function when a slot obtained from psa_reserve_free_key_slot() + * is no longer in use. + * + * If multi-threading is enabled, the caller must hold the + * global key slot mutex. + * + * \param slice_idx The slice containing the slot. + * This is `slot->slice_index` when the slot + * is obtained from psa_reserve_free_key_slot(). + * \param slot The key slot. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * This function attempted to operate on a key slot which was in an + * unexpected state. + */ +psa_status_t psa_free_key_slot(size_t slice_idx, + psa_key_slot_t *slot); +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ + /** Change the state of a key slot. * * This function changes the state of the key slot from expected_state to From a81282ce30bbbb6d64bd08383a9e54b5459c0250 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 10 Jun 2024 15:41:38 +0200 Subject: [PATCH 050/100] Microoptimizations when MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled Compensate some of the code size increase from implementing dynamic key slots. Signed-off-by: Gilles Peskine --- library/psa_crypto_slot_management.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index eef65dc142..5b4539ca7b 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -424,16 +424,24 @@ void psa_wipe_all_key_slots(void) #endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ for (size_t slot_idx = 0; slot_idx < key_slice_length(slice_idx); slot_idx++) { psa_key_slot_t *slot = get_key_slot(slice_idx, slot_idx); +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + /* When MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled, calling + * psa_wipe_key_slot() on an unused slot is useless, but it + * happens to work (because we flip the state to PENDING_DELETION). + * + * When MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, + * psa_wipe_key_slot() needs to have a valid slice_index + * field, but that value might not be correct in a + * free slot, so we must not call it. + * + * Bypass the call to psa_wipe_key_slot() if the slot is empty, + * but only if MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, to save + * a few bytes of code size otherwise. + */ if (slot->state == PSA_SLOT_EMPTY) { - /* Don't call psa_wipe_key_slot() on an already-empty slot. - * It rejects that case anyway, though we bypass it by setting - * the slot state to PENDING_DELETION. - * Also, when MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, - * psa_wipe_key_slot() needs to have a valid slice_index - * field, but that value might not be correct in a - * free slot. */ continue; } +#endif slot->var.occupied.registered_readers = 1; slot->state = PSA_SLOT_PENDING_DELETION; (void) psa_wipe_key_slot(slot); @@ -560,12 +568,11 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, goto error; } - if (volatile_key_id != NULL) { - *volatile_key_id = 0; #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) + if (volatile_key_id != NULL) { return psa_allocate_volatile_key_slot(volatile_key_id, p_slot); -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ } +#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ /* With a dynamic key store, allocate an entry in the cache slice, * applicable only to non-volatile keys that get cached in RAM. From 3bc9d2b5b9a393223be9103f12b6cf565d650a74 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 21 Jun 2024 00:09:07 +0200 Subject: [PATCH 051/100] Dynamic key store: make full-key-store tests work effectively Add a practical way to fill the dynamic key store by artificially limiting the slice length through a test hook. Signed-off-by: Gilles Peskine --- library/psa_crypto_slot_management.c | 16 ++++++++++ library/psa_crypto_slot_management.h | 18 ++++++++++++ ...test_suite_psa_crypto_slot_management.data | 5 ++++ ..._suite_psa_crypto_slot_management.function | 29 +++++++++++++++++-- 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 5b4539ca7b..d740960dd5 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -138,6 +138,13 @@ static size_t slot_index_of_volatile_key_id(psa_key_id_t key_id) * indicate that the slice is full. */ #define FREE_SLOT_INDEX_NONE ((size_t) -1) +#if defined(MBEDTLS_TEST_HOOKS) +size_t psa_key_slot_volatile_slice_count(void) +{ + return KEY_SLOT_VOLATILE_SLICE_COUNT; +} +#endif + #else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ /* Static key store. @@ -227,11 +234,20 @@ static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx); #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) +#if defined(MBEDTLS_TEST_HOOKS) +size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)(size_t slice_idx) = NULL; +#endif + static inline size_t key_slice_length(size_t slice_idx) { if (slice_idx == KEY_SLOT_CACHE_SLICE_INDEX) { return PERSISTENT_KEY_CACHE_COUNT; } else { +#if defined(MBEDTLS_TEST_HOOKS) + if (mbedtls_test_hook_psa_volatile_key_slice_length != NULL) { + return mbedtls_test_hook_psa_volatile_key_slice_length(slice_idx); + } +#endif return KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH << slice_idx; } } diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 1e6e935b59..26b73969b4 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -100,6 +100,24 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, */ psa_status_t psa_initialize_key_slots(void); +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) +/* Allow test code to customize the key slice length. We use this in tests + * that exhaust the key store to reach a full key store in reasonable time + * and memory. + * + * The length of each slice must be between 1 and + * (1 << KEY_ID_SLOT_INDEX_WIDTH) inclusive. + * + * The length for a given slice index must not change while + * the key store is initialized. + */ +extern size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)( + size_t slice_idx); + +/* The number of volatile key slices. */ +size_t psa_key_slot_volatile_slice_count(void); +#endif + /** Delete all data from key slots in memory. * This function is not thread safe, it wipes every key slot regardless of * state and reader count. It should only be called when no slot is in use. diff --git a/tests/suites/test_suite_psa_crypto_slot_management.data b/tests/suites/test_suite_psa_crypto_slot_management.data index 1bf300ade6..f379dba020 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.data +++ b/tests/suites/test_suite_psa_crypto_slot_management.data @@ -228,6 +228,11 @@ invalid_handle:INVALID_HANDLE_HUGE:PSA_ERROR_INVALID_HANDLE Key slot count: maximum many_transient_keys:MBEDTLS_PSA_KEY_SLOT_COUNT - MBEDTLS_TEST_PSA_INTERNAL_KEYS +Key slot count: dynamic: more than MBEDTLS_PSA_KEY_SLOT_COUNT +depends_on:MBEDTLS_PSA_KEY_STORE_DYNAMIC +# Check that MBEDTLS_PSA_KEY_SLOT_COUNT doesn't apply to volatile keys. +many_transient_keys:MBEDTLS_PSA_KEY_SLOT_COUNT + 1 + Key slot count: try to overfill, destroy first fill_key_store:0 diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function index b2d3f29735..604c4bd5de 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.function +++ b/tests/suites/test_suite_psa_crypto_slot_management.function @@ -98,11 +98,27 @@ exit: return 0; } -/* Currently, there is always a maximum number of volatile keys that can - * realistically be reached in tests. When we add configurations where this - * is not true, undefine the macro in such configurations. */ #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) +#if defined(MBEDTLS_TEST_HOOKS) +/* Artificially restrictable dynamic key store */ +#define KEY_SLICE_1_LENGTH 4 +#define KEY_SLICE_2_LENGTH 10 +static size_t tiny_key_slice_length(size_t slice_idx) +{ + switch (slice_idx) { + case 1: return KEY_SLICE_1_LENGTH; + case 2: return KEY_SLICE_2_LENGTH; + default: return 1; + } +} +#define MAX_VOLATILE_KEYS \ + (KEY_SLICE_1_LENGTH + KEY_SLICE_2_LENGTH + \ + psa_key_slot_volatile_slice_count() - 2) + +#else /* Effectively unbounded dynamic key store */ #undef MAX_VOLATILE_KEYS +#endif + #else /* Static key store */ #define MAX_VOLATILE_KEYS MBEDTLS_PSA_KEY_SLOT_COUNT #endif @@ -871,6 +887,10 @@ void fill_key_store(int key_to_destroy_arg) uint8_t exported[sizeof(size_t)]; size_t exported_length; +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && defined(MBEDTLS_TEST_HOOKS) + mbedtls_test_hook_psa_volatile_key_slice_length = &tiny_key_slice_length; +#endif + PSA_ASSERT(psa_crypto_init()); mbedtls_psa_stats_t stats; @@ -953,6 +973,9 @@ void fill_key_store(int key_to_destroy_arg) exit: PSA_DONE(); mbedtls_free(keys); +#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && defined(MBEDTLS_TEST_HOOKS) + mbedtls_test_hook_psa_volatile_key_slice_length = NULL; +#endif } /* END_CASE */ From 9dc903a316024d6e1c8605b917b002be30291fbc Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 21 Jun 2024 11:25:01 +0200 Subject: [PATCH 052/100] Add test components with the PSA static key store We were only testing the static key store (MBEDTLS_PSA_KEY_STORE_DYNAMIC disabled) with configs/*.h. Add a component with the static key store and everything else (including built-in keys), and a component with the static key store and CTR_DBRG using PSA for AES (which means PSA uses a volatile key internally). Signed-off-by: Gilles Peskine --- .../components-configuration-crypto.sh | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/scripts/components-configuration-crypto.sh b/tests/scripts/components-configuration-crypto.sh index 39b9d5d738..da0e180801 100644 --- a/tests/scripts/components-configuration-crypto.sh +++ b/tests/scripts/components-configuration-crypto.sh @@ -2504,6 +2504,40 @@ common_block_cipher_dispatch () { scripts/config.py set MBEDTLS_DEPRECATED_REMOVED } +component_test_full_block_cipher_psa_dispatch_static_keystore () { + msg "build: full + PSA dispatch in block_cipher with static keystore" + # Check that the static key store works well when CTR_DRBG uses a + # PSA key for AES. + scripts/config.py unset MBEDTLS_PSA_KEY_STORE_DYNAMIC + + loc_accel_list="ALG_ECB_NO_PADDING \ + KEY_TYPE_AES KEY_TYPE_ARIA KEY_TYPE_CAMELLIA" + + # Configure + # --------- + + common_block_cipher_dispatch 1 + + # Build + # ----- + + helper_libtestdriver1_make_drivers "$loc_accel_list" + + helper_libtestdriver1_make_main "$loc_accel_list" + + # Make sure disabled components were not re-enabled by accident (additive + # config) + not grep mbedtls_aes_ library/aes.o + not grep mbedtls_aria_ library/aria.o + not grep mbedtls_camellia_ library/camellia.o + + # Run the tests + # ------------- + + msg "test: full + PSA dispatch in block_cipher with static keystore" + make test +} + component_test_full_block_cipher_psa_dispatch () { msg "build: full + PSA dispatch in block_cipher" @@ -3038,6 +3072,16 @@ component_test_se_default () { make test } +component_test_full_static_keystore () { + msg "build: full config - MBEDTLS_PSA_KEY_STORE_DYNAMIC" + scripts/config.py full + scripts/config.py unset MBEDTLS_PSA_KEY_STORE_DYNAMIC + make CC=clang CFLAGS="$ASAN_CFLAGS -Os" LDFLAGS="$ASAN_CFLAGS" + + msg "test: full config - MBEDTLS_PSA_KEY_STORE_DYNAMIC" + make test +} + component_test_psa_crypto_drivers () { msg "build: full + test drivers dispatching to builtins" scripts/config.py full From 628ad389be62a80bfe2e575f4a0e70719bed1e1f Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 10 Jun 2024 18:50:00 +0200 Subject: [PATCH 053/100] Changelog entry for MBEDTLS_PSA_KEY_STORE_DYNAMIC Signed-off-by: Gilles Peskine --- ChangeLog.d/dynamic-keystore.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog.d/dynamic-keystore.txt b/ChangeLog.d/dynamic-keystore.txt index d576dcd86f..c6aac3c991 100644 --- a/ChangeLog.d/dynamic-keystore.txt +++ b/ChangeLog.d/dynamic-keystore.txt @@ -1,3 +1,9 @@ +Features + * When the new compilation option MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, + the number of volatile PSA keys is virtually unlimited, at the expense + of increased code size. This option is off by default, but enabled in + the default mbedtls_config.h. Fixes #9216. + Bugfix * Fix interference between PSA volatile keys and built-in keys when MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS is enabled and From ac43de0e52a9aa0052d6c20ef73471c9a5efc183 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 13 Jun 2024 20:36:50 +0200 Subject: [PATCH 054/100] Make integer downsizing explicit Reassure both humans and compilers that the places where we assign an integer to a smaller type are safe. Signed-off-by: Gilles Peskine --- library/psa_crypto_slot_management.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index d740960dd5..feedbb5ea4 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -116,7 +116,12 @@ MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN | static psa_key_id_t volatile_key_id_of_index(size_t slice_idx, size_t slot_idx) { - return 0x40000000u | (slice_idx << KEY_ID_SLOT_INDEX_WIDTH) | slot_idx; + /* We assert above that the slice and slot indexes fit in separate + * bit-fields inside psa_key_id_t, which is a 32-bit type per the + * PSA Cryptography specification. */ + return (psa_key_id_t) (0x40000000u | + (slice_idx << KEY_ID_SLOT_INDEX_WIDTH) | + slot_idx); } /* Calculate the slice containing the given volatile key. @@ -529,7 +534,8 @@ static psa_status_t psa_allocate_volatile_key_slot(psa_key_id_t *key_id, } *p_slot = slot; - slot->slice_index = slice_idx; + /* We assert at compile time that the slice index fits in uint8_t. */ + slot->slice_index = (uint8_t) slice_idx; return PSA_SUCCESS; } @@ -566,7 +572,8 @@ psa_status_t psa_free_key_slot(size_t slice_idx, next_free = key_slice_length(slice_idx); } global_data.first_free_slot_index[slice_idx] = slot_idx; - slot->var.free.next_free_relative_to_next = next_free - slot_idx - 1; + slot->var.free.next_free_relative_to_next = + (int32_t) next_free - (int32_t) slot_idx - 1; return PSA_SUCCESS; } From 1dfb6b595a8b00af7a811f64b970e827d9407c93 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 9 Aug 2024 14:04:46 +0200 Subject: [PATCH 055/100] Clarify some internal documentation Signed-off-by: Gilles Peskine --- library/psa_crypto_core.h | 10 +++++++++- library/psa_crypto_slot_management.h | 16 +++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 91ef0bfb78..21e7559f01 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -88,7 +88,15 @@ typedef struct { /* The index of the slice containing this slot. * This field must be filled if the slot contains a key * (including keys being created or destroyed), and can be either - * filled or 0 when the slot is free. */ + * filled or 0 when the slot is free. + * + * In most cases, the slice index can be deduced from the key identifer. + * We keep it in a separate field for robustness (it reduces the chance + * that a coding mistake in the key store will result in accessing the + * wrong slice), and also so that it's available even on code paths + * during creation or destruction where the key identifier might not be + * filled in. + * */ uint8_t slice_index; #endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 26b73969b4..af1208e3ae 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -137,13 +137,15 @@ void psa_wipe_all_key_slots(void); * If multi-threading is enabled, the caller must hold the * global key slot mutex. * - * \param[out] volatile_key_id If null, reserve a cache slot for - * a persistent or built-in key. - * If non-null, allocate a slot for - * a volatile key. - * If non-null, on success, the volatile key - * identifier corresponding with the - * returned slot. + * \param[out] volatile_key_id - If null, reserve a cache slot for + * a persistent or built-in key. + * - If non-null, allocate a slot for + * a volatile key. On success, + * \p *volatile_key_id is the + * identifier corresponding to the + * returned slot. It is the caller's + * responsibility to set this key identifier + * in the attributes. * \param[out] p_slot On success, a pointer to the slot. * * \retval #PSA_SUCCESS \emptydescription From 81a438b7d71555149b2901756d66815395953077 Mon Sep 17 00:00:00 2001 From: Sam Berry Date: Fri, 12 Jul 2024 14:42:08 +0100 Subject: [PATCH 056/100] Remove MBEDTLS_PSA_UTIL_HAVE_ECDSA so that functions are only enabled when PSA enabled Signed-off-by: Sam Berry --- include/mbedtls/config_adjust_legacy_crypto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/config_adjust_legacy_crypto.h b/include/mbedtls/config_adjust_legacy_crypto.h index 7a375d8646..3ba987ebb2 100644 --- a/include/mbedtls/config_adjust_legacy_crypto.h +++ b/include/mbedtls/config_adjust_legacy_crypto.h @@ -428,7 +428,7 @@ /* psa_util file features some ECDSA conversion functions, to convert between * legacy's ASN.1 DER format and PSA's raw one. */ -#if defined(MBEDTLS_ECDSA_C) || (defined(MBEDTLS_PSA_CRYPTO_C) && \ +#if (defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \ (defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA))) #define MBEDTLS_PSA_UTIL_HAVE_ECDSA #endif From 6474d906bbabcc36d760187ba754b0b1b40023e7 Mon Sep 17 00:00:00 2001 From: Sam Berry Date: Wed, 7 Aug 2024 13:56:21 +0100 Subject: [PATCH 057/100] Changelog entry Signed-off-by: Sam Berry --- ChangeLog.d/psa_util_in_builds_without_psa.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ChangeLog.d/psa_util_in_builds_without_psa.txt diff --git a/ChangeLog.d/psa_util_in_builds_without_psa.txt b/ChangeLog.d/psa_util_in_builds_without_psa.txt new file mode 100644 index 0000000000..7c0866dd30 --- /dev/null +++ b/ChangeLog.d/psa_util_in_builds_without_psa.txt @@ -0,0 +1,5 @@ +Bugfix + * When MBEDTLS_PSA_CRYPTO_C was disabled and MBEDTLS_ECDSA_C enabled, + some code was defining 0-size arrays, resulting in compilation errors. + Fixed by disabling the offending code in configurations without PSA + Crypto, where it never worked. Fixes #9311. From 3001e27f21a61d3d54d1e6a5628e7e3f2c8d9705 Mon Sep 17 00:00:00 2001 From: Michael Schuster Date: Wed, 24 Jul 2024 18:23:50 +0200 Subject: [PATCH 058/100] Update the submodule to the head of PR in the framework repository See Mbed-TLS/mbedtls-framework#23 Signed-off-by: Michael Schuster Signed-off-by: Gilles Peskine --- framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework b/framework index 331565b041..6a1dc7daa9 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit 331565b041f794df2da76394b3b0039abce30355 +Subproject commit 6a1dc7daa9e861fb873dd4b9f13ebfbd6f82f6dc From ee7332104d1a18121d3c39edb1a1b1b3b4674cf3 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sat, 10 Aug 2024 17:22:45 +0200 Subject: [PATCH 059/100] Mention interfaces replaced by PSA drivers Signed-off-by: Gilles Peskine --- ChangeLog.d/announce-4.0-removals.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog.d/announce-4.0-removals.txt b/ChangeLog.d/announce-4.0-removals.txt index 5942e3adb5..ba78386407 100644 --- a/ChangeLog.d/announce-4.0-removals.txt +++ b/ChangeLog.d/announce-4.0-removals.txt @@ -17,8 +17,8 @@ New deprecations - TLS_DHE_*, i.e. cipher suites using finite-field Diffie-Hellman. (Ephemeral ECDH, i.e. TLS_ECDHE_*, is staying.) - TLS_*CBC*, i.e. all cipher suites using CBC. - * The following low-level interfaces are planned to be removed from the - public API in Mbed TLS 4.0: + * The following low-level application interfaces are planned to be removed + from the public API in Mbed TLS 4.0: - Hashes: hkdf.h, md5.h, ripemd160.h, sha1.h, sha3.h, sha256.h, sha512.h; - Pseudorandom generation: ctr_drbg.h, hmac_drbg.h; - Ciphers and modes: aes.h, aria.h, camellia.h, chacha20.h, chachapoly.h, @@ -31,3 +31,9 @@ New deprecations Mbed TLS 2.28.0) and, where relevant, PK. For guidance on migrating application code to the PSA API, please consult the PSA transition guide (docs/psa-transition.md). + * The following integration interfaces are planned to be removed + in Mbed TLS 4.0: + - MBEDTLS_xxx_ALT replacement of cryptographic modules and functions. + Use PSA transparent drivers instead. + - MBEDTLS_PK_RSA_ALT and MBEDTLS_PSA_CRYPTO_SE_C. + Use PSA opaque drivers instead. From ce629a6ce7b1d0af15485d7fd7f5eb3800e01798 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 12 Aug 2024 11:21:10 +0200 Subject: [PATCH 060/100] entropy.h is also going away Signed-off-by: Gilles Peskine --- ChangeLog.d/announce-4.0-removals.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/announce-4.0-removals.txt b/ChangeLog.d/announce-4.0-removals.txt index ba78386407..49dbf802b0 100644 --- a/ChangeLog.d/announce-4.0-removals.txt +++ b/ChangeLog.d/announce-4.0-removals.txt @@ -20,7 +20,7 @@ New deprecations * The following low-level application interfaces are planned to be removed from the public API in Mbed TLS 4.0: - Hashes: hkdf.h, md5.h, ripemd160.h, sha1.h, sha3.h, sha256.h, sha512.h; - - Pseudorandom generation: ctr_drbg.h, hmac_drbg.h; + - Random generation: ctr_drbg.h, hmac_drbg.h, entropy.h; - Ciphers and modes: aes.h, aria.h, camellia.h, chacha20.h, chachapoly.h, cipher.h, cmac.h, gcm.h, poly1305.h; - Private key encryption mechanisms: pkcs5.h, pkcs12.h. From 47bf23f74887aca4384b023a6921444a52b03c4e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 12 Aug 2024 11:21:54 +0200 Subject: [PATCH 061/100] PSA PAKE wasn't in 2.28 Signed-off-by: Gilles Peskine --- ChangeLog.d/announce-4.0-removals.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog.d/announce-4.0-removals.txt b/ChangeLog.d/announce-4.0-removals.txt index 49dbf802b0..bf941e22a2 100644 --- a/ChangeLog.d/announce-4.0-removals.txt +++ b/ChangeLog.d/announce-4.0-removals.txt @@ -27,8 +27,8 @@ New deprecations - Asymmetric cryptography: bignum.h, dhm.h, ecdh.h, ecdsa.h, ecjpake.h, ecp.h, rsa.h. The cryptographic mechanisms remain present, but they will only be - accessible via the PSA API (psa_xxx functions introduced before - Mbed TLS 2.28.0) and, where relevant, PK. + accessible via the PSA API (psa_xxx functions introduced gradually + starting with Mbed TLS 2.17) and, where relevant, `pk.h`. For guidance on migrating application code to the PSA API, please consult the PSA transition guide (docs/psa-transition.md). * The following integration interfaces are planned to be removed From e084964068a2c79b1230670875b48a907e63c108 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 12 Aug 2024 17:26:24 +0100 Subject: [PATCH 062/100] Improve documentation of MBEDTLS_MPI_IS_PUBLIC Signed-off-by: Janos Follath --- include/mbedtls/bignum.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index bb96f4fb89..cd7e2f6c66 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -44,7 +44,12 @@ goto cleanup; \ } while (0) -/* Constants to identify whether a value is public or secret. +/* Constants to identify whether a value is public or secret. If a parameter is marked as secret by + * this constant, the function must be constant time with respect to the parameter. + * + * This is only needed for functions with the _optionally_safe postfix. All other functions have + * fixed behavior that can't be changed at runtime and are constant time with respect to their + * parameters as prescribed by their documentation or by conventions in their module's documentation. * * Parameters should be named X_public where X is the name of the * corresponding input parameter. From 38ff70e169e5b00bbe63038456638f357f01db3e Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 12 Aug 2024 18:20:59 +0100 Subject: [PATCH 063/100] Make _optionally_safe functions internal The complexity of having functions whose security properties depend on a runtime argument can be dangerous. Limit misuse by making any such functions local. Signed-off-by: Janos Follath --- include/mbedtls/bignum.h | 8 +++++--- library/bignum.c | 31 +++++++++++++++++++------------ library/bignum_core.c | 39 ++++++++++++++++++++++++++++++--------- library/bignum_core.h | 18 ++++++++---------- 4 files changed, 62 insertions(+), 34 deletions(-) diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index cd7e2f6c66..26c61f5db2 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -903,6 +903,8 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, /** * \brief Perform a modular exponentiation: X = A^E mod N * + * \warning This function is not constant time with respect to \p E (the exponent). + * * \param X The destination MPI. This must point to an initialized MPI. * This must not alias E or N. * \param A The base of the exponentiation. @@ -927,9 +929,9 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, * \return Another negative error code on different kinds of failures. * */ -int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *prec_RR, int E_public); +int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR); /** * \brief Perform a modular exponentiation: X = A^E mod N diff --git a/library/bignum.c b/library/bignum.c index 4db2b10544..6ac041eef9 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -1610,9 +1610,13 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s return 0; } -int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *prec_RR, int E_public) +/* + * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value, + * this function is not constant time with respect to the exponent (parameter E). + */ +static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR, int E_public) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -1695,15 +1699,11 @@ int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A, { mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p); mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T); - mbedtls_mpi_core_exp_mod_optionally_safe(X->p, - X->p, - N->p, - N->n, - E->p, - E->n, - RR.p, - T, - E_public); + if (E_public == MBEDTLS_MPI_IS_PUBLIC) { + mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T); + } else { + mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T); + } mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T); } @@ -1735,6 +1735,13 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, N, prec_RR, MBEDTLS_MPI_IS_SECRET); } +int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR) +{ + return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, N, prec_RR, MBEDTLS_MPI_IS_PUBLIC); +} + /* * Greatest common divisor: G = gcd(A, B) (HAC 14.54) */ diff --git a/library/bignum_core.c b/library/bignum_core.c index 518b1bd3f3..ab6cf8fcdc 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -747,6 +747,9 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A, } /* Exponentiation: X := A^E mod N. + * + * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value, + * this function is not constant time with respect to the exponent (parameter E). * * A must already be in Montgomery form. * @@ -758,15 +761,15 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A, * (The difference is that the body in our loop processes a single bit instead * of a full window.) */ -void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - const mbedtls_mpi_uint *E, - size_t E_limbs, - const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T, - int E_public) +static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, + size_t AN_limbs, + const mbedtls_mpi_uint *E, + size_t E_limbs, + const mbedtls_mpi_uint *RR, + mbedtls_mpi_uint *T, + int E_public) { const size_t wsize = exp_mod_get_window_size(E_limbs * biL); const size_t welem = ((size_t) 1) << wsize; @@ -872,6 +875,24 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, MBEDTLS_MPI_IS_SECRET); } +void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, size_t AN_limbs, + const mbedtls_mpi_uint *E, size_t E_limbs, + const mbedtls_mpi_uint *RR, + mbedtls_mpi_uint *T) +{ + mbedtls_mpi_core_exp_mod_optionally_safe(X, + A, + N, + AN_limbs, + E, + E_limbs, + RR, + T, + MBEDTLS_MPI_IS_PUBLIC); +} + mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X, const mbedtls_mpi_uint *A, mbedtls_mpi_uint c, /* doubles as carry */ diff --git a/library/bignum_core.h b/library/bignum_core.h index c63cdee465..d208daf7ba 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -608,6 +608,8 @@ size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs); * \brief Perform a modular exponentiation with public or secret exponent: * X = A^E mod N, where \p A is already in Montgomery form. * + * \warning This function is not constant time with respect to \p E (the exponent). + * * \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs == * \p AN_limbs. * @@ -630,17 +632,13 @@ size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs); * It is up to the caller to zeroize \p T when it is no * longer needed, and before freeing it if it was dynamically * allocated. - * \param[in] E_public Set to MBEDTLS_MPI_IS_PUBLIC to gain some performance - * when the value of E is public. - * Set to MBEDTLS_MPI_IS_SECRET when the value of E is secret. */ -void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, size_t AN_limbs, - const mbedtls_mpi_uint *E, size_t E_limbs, - const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T, - int E_public); +void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, size_t AN_limbs, + const mbedtls_mpi_uint *E, size_t E_limbs, + const mbedtls_mpi_uint *RR, + mbedtls_mpi_uint *T); /** * \brief Perform a modular exponentiation with secret exponent: From bb3f295e4007e7953a8f314febd6cdbde9c885b7 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 12 Aug 2024 19:05:47 +0100 Subject: [PATCH 064/100] Move mixed security code to small local functions The complexity of having functions whose security properties depend on a runtime argument can be dangerous. Limit risk by isolating such code in small functions with limited scope. Signed-off-by: Janos Follath --- library/bignum_core.c | 70 +++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/library/bignum_core.c b/library/bignum_core.c index ab6cf8fcdc..460a115d99 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -746,6 +746,56 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A, } } +/* + * This function calculates the indices of the exponent where the exponentiation algorithm should + * start processing. + * + * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value, + * this function is not constant time with respect to the exponent (parameter E). + */ +static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E, + size_t E_limbs, + int E_public, + size_t *E_limb_index, + size_t *E_bit_index) +{ + if (E_public == MBEDTLS_MPI_IS_PUBLIC) { + size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs); + if (E_bits != 0) { + *E_limb_index = E_bits / biL; + *E_bit_index = E_bits % biL; + } + } else { + /* + * Here we need to be constant time with respect to E and can't do anything better than + * start at the first allocated bit. + */ + *E_limb_index = E_limbs; + *E_bit_index = 0; + } +} + +/* + * Warning! If the parameter window_public has MBEDTLS_MPI_IS_PUBLIC as its value, this function is + * not constant time with respect to the window parameter and consequently the exponent of the + * exponentiation (parameter E of mbedtls_mpi_core_exp_mod_optionally_safe). + */ +static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselect, + mbedtls_mpi_uint *Wtable, + size_t AN_limbs, size_t welem, + mbedtls_mpi_uint window, + int window_public) +{ + if (window_public == MBEDTLS_MPI_IS_PUBLIC) { + memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL); + } else { + /* Select Wtable[window] without leaking window through + * memory access patterns. */ + mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable, + AN_limbs, welem, window); + } +} + /* Exponentiation: X := A^E mod N. * * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value, @@ -807,13 +857,8 @@ static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, * (limb_index=0, E_bit_index=0). */ size_t E_limb_index = E_limbs; size_t E_bit_index = 0; - if (E_public == MBEDTLS_MPI_IS_PUBLIC) { - size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs); - if (E_bits != 0) { - E_limb_index = E_bits / biL; - E_bit_index = E_bits % biL; - } - } + exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public, + &E_limb_index, &E_bit_index); /* At any given time, window contains window_bits bits from E. * window_bits can go up to wsize. */ @@ -840,14 +885,9 @@ static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, * when we've finished processing the exponent. */ if (window_bits == wsize || (E_bit_index == 0 && E_limb_index == 0)) { - if (E_public == MBEDTLS_MPI_IS_PUBLIC) { - memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL); - } else { - /* Select Wtable[window] without leaking window through - * memory access patterns. */ - mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable, - AN_limbs, welem, window); - } + + exp_mod_table_lookup_optionally_safe(Wselect, Wtable, AN_limbs, welem, + window, E_public); /* Multiply X by the selected element. */ mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm, temp); From 90b4271ff0e8bc541118b1dba49ad295c8239c19 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 12 Aug 2024 19:32:45 +0100 Subject: [PATCH 065/100] Move MBEDTLS_MPI_IS_* macros to bignum_core.h These macros are not part of any public or internal API, ideally they would be defined in the source files. The reason to put them in bignum_core.h to avoid duplication as macros for this purpose are needed in both bignum.c and bignum_core.c. Signed-off-by: Janos Follath --- include/mbedtls/bignum.h | 21 --------------------- library/bignum_core.h | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index 26c61f5db2..a945be3614 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -44,27 +44,6 @@ goto cleanup; \ } while (0) -/* Constants to identify whether a value is public or secret. If a parameter is marked as secret by - * this constant, the function must be constant time with respect to the parameter. - * - * This is only needed for functions with the _optionally_safe postfix. All other functions have - * fixed behavior that can't be changed at runtime and are constant time with respect to their - * parameters as prescribed by their documentation or by conventions in their module's documentation. - * - * Parameters should be named X_public where X is the name of the - * corresponding input parameter. - * - * Implementation should always check using - * if (X_public == MBEDTLS_MPI_IS_PUBLIC) { - * // unsafe path - * } 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.) */ -#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a -#define MBEDTLS_MPI_IS_SECRET 0 - /* * Maximum size MPIs are allowed to grow to in number of limbs. */ diff --git a/library/bignum_core.h b/library/bignum_core.h index d208daf7ba..ee69aa7317 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -90,6 +90,27 @@ #define GET_BYTE(X, i) \ (((X)[(i) / ciL] >> (((i) % ciL) * 8)) & 0xff) +/* Constants to identify whether a value is public or secret. If a parameter is marked as secret by + * this constant, the function must be constant time with respect to the parameter. + * + * This is only needed for functions with the _optionally_safe postfix. All other functions have + * fixed behavior that can't be changed at runtime and are constant time with respect to their + * parameters as prescribed by their documentation or by conventions in their module's documentation. + * + * Parameters should be named X_public where X is the name of the + * corresponding input parameter. + * + * Implementation should always check using + * if (X_public == MBEDTLS_MPI_IS_PUBLIC) { + * // unsafe path + * } 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.) */ +#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a +#define MBEDTLS_MPI_IS_SECRET 0 + /** Count leading zero bits in a given integer. * * \warning The result is undefined if \p a == 0 From 0c292b26a55cfaebfe90ee3b4c850f257e1d4146 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 12 Aug 2024 19:55:02 +0100 Subject: [PATCH 066/100] Make MBEDTLS_MPI_IS_PUBLIC thumb friendly In Thumb instructions, constant can be: - any constant that can be produced by shifting an 8-bit value left by any number of bits within a 32-bit word - any constant of the form 0x00XY00XY - any constant of the form 0xXY00XY00 - any constant of the form 0xXYXYXYXY. Signed-off-by: Janos Follath --- library/bignum_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/bignum_core.h b/library/bignum_core.h index ee69aa7317..6c214a530b 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -108,7 +108,7 @@ * } * 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.) */ -#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a +#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a2a2a #define MBEDTLS_MPI_IS_SECRET 0 /** Count leading zero bits in a given integer. From a5fc8f342a980e2f75229fb42fb92a5d4b0b2c6a Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 12 Aug 2024 20:11:06 +0100 Subject: [PATCH 067/100] Move _public parameters next to their target It is easier to read if the parameter controlling constant timeness with respect to a parameter is next to that parameter. Signed-off-by: Janos Follath --- library/bignum.c | 8 ++++---- library/bignum_core.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index 6ac041eef9..b1f9c1bf0f 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -1615,8 +1615,8 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s * this function is not constant time with respect to the exponent (parameter E). */ static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *prec_RR, int E_public) + const mbedtls_mpi *E, int E_public, + const mbedtls_mpi *N, mbedtls_mpi *prec_RR) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -1732,14 +1732,14 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *prec_RR) { - return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, N, prec_RR, MBEDTLS_MPI_IS_SECRET); + return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR); } int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *prec_RR) { - return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, N, prec_RR, MBEDTLS_MPI_IS_PUBLIC); + return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR); } /* diff --git a/library/bignum_core.c b/library/bignum_core.c index 460a115d99..33d66323f4 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -817,9 +817,9 @@ static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, size_t AN_limbs, const mbedtls_mpi_uint *E, size_t E_limbs, + int E_public, const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T, - int E_public) + mbedtls_mpi_uint *T) { const size_t wsize = exp_mod_get_window_size(E_limbs * biL); const size_t welem = ((size_t) 1) << wsize; @@ -910,9 +910,9 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, AN_limbs, E, E_limbs, + MBEDTLS_MPI_IS_SECRET, RR, - T, - MBEDTLS_MPI_IS_SECRET); + T); } void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X, @@ -928,9 +928,9 @@ void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X, AN_limbs, E, E_limbs, + MBEDTLS_MPI_IS_PUBLIC, RR, - T, - MBEDTLS_MPI_IS_PUBLIC); + T); } mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X, From 020b9ab004e81bea811b9a437e976121778c222e Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 13 Aug 2024 07:53:20 +0100 Subject: [PATCH 068/100] Use actual exponent size for window calculation The allocated size can be significantly larger than the actual size. In the unsafe case we can use the actual size and gain some performance. Signed-off-by: Janos Follath --- library/bignum_core.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/library/bignum_core.c b/library/bignum_core.c index 33d66323f4..260a1f2661 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -821,7 +821,15 @@ static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, const mbedtls_mpi_uint *RR, mbedtls_mpi_uint *T) { - const size_t wsize = exp_mod_get_window_size(E_limbs * biL); + /* 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 = 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); + + const size_t wsize = exp_mod_get_window_size(E_limb_index * biL); const size_t welem = ((size_t) 1) << wsize; /* This is how we will use the temporary storage T, which must have space @@ -852,14 +860,6 @@ static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, /* X = 1 (in Montgomery presentation) initially */ memcpy(X, Wtable, AN_limbs * ciL); - /* 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 = 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); - /* At any given time, window contains window_bits bits from E. * window_bits can go up to wsize. */ size_t window_bits = 0; From e0842aa7512438b9e749f4137b15ee810052ecaf Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 13 Aug 2024 08:40:31 +0100 Subject: [PATCH 069/100] Add tests for optionally safe codepaths The new test hooks allow to check whether there was an unsafe call of an optionally safe function in the codepath. For the sake of simplicity the MBEDTLS_MPI_IS_* macros are reused for signalling safe/unsafe codepaths here too. Signed-off-by: Janos Follath --- library/bignum_core.c | 18 ++++++++++++++++++ library/bignum_core.h | 10 ++++++++++ tests/suites/test_suite_bignum_core.function | 12 ++++++++++++ 3 files changed, 40 insertions(+) diff --git a/library/bignum_core.c b/library/bignum_core.c index 260a1f2661..f46df0c8c7 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -765,6 +765,9 @@ static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E_limb_index = E_bits / biL; *E_bit_index = E_bits % biL; } +#if defined(MBEDTLS_TEST_HOOKS) + mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC; +#endif } else { /* * Here we need to be constant time with respect to E and can't do anything better than @@ -772,6 +775,12 @@ 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) + // 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; + } +#endif } } @@ -788,11 +797,20 @@ 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) + mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC; +#endif } else { /* Select Wtable[window] without leaking window through * memory access patterns. */ mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable, AN_limbs, welem, window); +#if defined(MBEDTLS_TEST_HOOKS) + // 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; + } +#endif } } diff --git a/library/bignum_core.h b/library/bignum_core.h index 6c214a530b..50c53e6c39 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -817,4 +817,14 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X, mbedtls_mpi_uint mm, mbedtls_mpi_uint *T); +#if defined(MBEDTLS_TEST_HOOKS) +int mbedtls_mpi_optionally_safe_codepath; + +static inline void mbedtls_mpi_optionally_safe_codepath_reset() +{ + // 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 */ diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index db84d6238f..373bda4e8c 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -1229,13 +1229,25 @@ void mpi_core_exp_mod(char *input_N, char *input_A, TEST_CALLOC(T, working_limbs); +#if defined(MBEDTLS_TEST_HOOKS) + mbedtls_mpi_optionally_safe_codepath_reset(); +#endif mbedtls_mpi_core_exp_mod(Y, A, N, N_limbs, E, E_limbs, R2, T); +#if defined(MBEDTLS_TEST_HOOKS) + TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_SECRET); +#endif TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint))); /* Check when output aliased to input */ +#if defined(MBEDTLS_TEST_HOOKS) + mbedtls_mpi_optionally_safe_codepath_reset(); +#endif mbedtls_mpi_core_exp_mod(A, A, N, N_limbs, E, E_limbs, R2, T); +#if defined(MBEDTLS_TEST_HOOKS) + TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_SECRET); +#endif TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint))); From 4d9981ac5c0cfae04d11492aaae065348830318b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 13 Aug 2024 11:44:16 +0200 Subject: [PATCH 070/100] Update framework to the head of the main branch Signed-off-by: Gilles Peskine --- framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework b/framework index 6a1dc7daa9..94599c0e3b 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit 6a1dc7daa9e861fb873dd4b9f13ebfbd6f82f6dc +Subproject commit 94599c0e3b5036e086446a51a3f79640f70f22f6 From 73426560984108ad1b72bcc9611c58ff0ca7166c Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 13 Aug 2024 11:39:03 +0100 Subject: [PATCH 071/100] Add tests for optionally unsafe code paths Signed-off-by: Janos Follath --- tests/suites/test_suite_bignum_core.function | 30 ++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index 373bda4e8c..9c864ac870 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -1178,6 +1178,7 @@ void mpi_core_exp_mod(char *input_N, char *input_A, char *input_E, char *input_X) { mbedtls_mpi_uint *A = NULL; + mbedtls_mpi_uint *A_copy = NULL; mbedtls_mpi_uint *E = NULL; mbedtls_mpi_uint *N = NULL; mbedtls_mpi_uint *X = NULL; @@ -1229,6 +1230,8 @@ void mpi_core_exp_mod(char *input_N, char *input_A, TEST_CALLOC(T, working_limbs); + /* Test the safe variant */ + #if defined(MBEDTLS_TEST_HOOKS) mbedtls_mpi_optionally_safe_codepath_reset(); #endif @@ -1236,10 +1239,23 @@ void mpi_core_exp_mod(char *input_N, char *input_A, #if defined(MBEDTLS_TEST_HOOKS) TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_SECRET); #endif - TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint))); - /* Check when output aliased to input */ + /* Test the unsafe variant */ + +#if defined(MBEDTLS_TEST_HOOKS) + mbedtls_mpi_optionally_safe_codepath_reset(); +#endif + mbedtls_mpi_core_exp_mod_unsafe(Y, A, N, N_limbs, E, E_limbs, R2, T); +#if defined(MBEDTLS_TEST_HOOKS) + TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_PUBLIC); +#endif + TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint))); + + /* Check both with output aliased to input */ + + TEST_CALLOC(A_copy, A_limbs); + memcpy(A_copy, A, sizeof(A_copy) * A_limbs); #if defined(MBEDTLS_TEST_HOOKS) mbedtls_mpi_optionally_safe_codepath_reset(); @@ -1248,12 +1264,22 @@ void mpi_core_exp_mod(char *input_N, char *input_A, #if defined(MBEDTLS_TEST_HOOKS) TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_SECRET); #endif + TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint))); + memcpy(A, A_copy, sizeof(A) * A_limbs); +#if defined(MBEDTLS_TEST_HOOKS) + mbedtls_mpi_optionally_safe_codepath_reset(); +#endif + mbedtls_mpi_core_exp_mod_unsafe(A, A, N, N_limbs, E, E_limbs, R2, T); +#if defined(MBEDTLS_TEST_HOOKS) + TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_PUBLIC); +#endif TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint))); exit: mbedtls_free(T); mbedtls_free(A); + mbedtls_free(A_copy); mbedtls_free(E); mbedtls_free(N); mbedtls_free(X); From fc1b6f54a300a90bf98d8243e5d37a77f14ed3f9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 14 Aug 2024 11:40:20 +0200 Subject: [PATCH 072/100] Mention the option name for the dynamic key store Signed-off-by: Gilles Peskine --- docs/architecture/psa-keystore-design.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/architecture/psa-keystore-design.md b/docs/architecture/psa-keystore-design.md index 54ba8ac28b..42f08495a9 100644 --- a/docs/architecture/psa-keystore-design.md +++ b/docs/architecture/psa-keystore-design.md @@ -113,6 +113,8 @@ With a static key store, `psa_wipe_key_slot()` destroys or purges a key by freei The dynamic key store allows a large number of keys, at the expense of more complex memory management. +The dynamic key store was added in Mbed TLS 3.6.1. It is enabled by `MBEDTLS_PSA_KEY_STORE_DYNAMIC`, which is enabled by default since Mbed TLS 3.6.1. + #### Dynamic key slot performance characteristics Key management and key access have $O(1)$ amortized performance, and mostly $O(1)$ performance for actions involving keys. More precisely: From 39c227207ce6939a51c9e69226ceb070b37440fc Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 14 Aug 2024 11:40:38 +0200 Subject: [PATCH 073/100] The fully static key store will miss the 3.6.1 release Signed-off-by: Gilles Peskine --- docs/architecture/psa-keystore-design.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture/psa-keystore-design.md b/docs/architecture/psa-keystore-design.md index 42f08495a9..cdd2cac3ab 100644 --- a/docs/architecture/psa-keystore-design.md +++ b/docs/architecture/psa-keystore-design.md @@ -67,7 +67,7 @@ Note that a slot must not be moved in memory while it is being read or written. There are three variants of the key store implementation, responding to different needs. * Hybrid key store ([static key slots](#static-key-store) with dynamic key data): the key store is a statically allocated array of slots, of size `MBEDTLS_PSA_KEY_SLOT_COUNT`. Key material is allocated on the heap. This is the historical implementation. It remains the default in the Mbed TLS 3.6 long-time support (LTS) branch when using a handwritten `mbedtls_config.h`, as is common on resource-constrained platforms, because the alternatives have tradeoffs (key size limit and larger RAM usage at rest for the static key store, larger code size and more risk due to code complexity for the dynamic key store). -* Fully [static key store](#static-key-store) (since Mbed TLS 3.6.1): the key store is a statically allocated array of slots, of size `MBEDTLS_PSA_KEY_SLOT_COUNT`. Each key slot contains the key representation directly, and the key representation must be no more than `MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE` bytes. This is intended for very constrained devices that do not have a heap. +* Fully [static key store](#static-key-store) (since Mbed TLS 3.6.2): the key store is a statically allocated array of slots, of size `MBEDTLS_PSA_KEY_SLOT_COUNT`. Each key slot contains the key representation directly, and the key representation must be no more than `MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE` bytes. This is intended for very constrained devices that do not have a heap. * [Dynamic key store](#dynamic-key-store) (since Mbed TLS 3.6.1): the key store is dynamically allocated as multiple slices on the heap, with a size that adjusts to the application's usage. Key material is allocated on the heap. Compared to the hybrid key store, the code size and RAM consumption are larger. This is intended for higher-end devices where applications are not expected to have a highly predicatable resource usage. This is the default implementation when using the default `mbedtls_config.h` file, as is common on platforms such as Linux, starting with Mbed TLS 3.6.1. #### Future improvement: merging the key store variants @@ -95,7 +95,7 @@ When creating a volatile key, the slice containing the slot and index of the slo The static key store is the historical implementation. The key store is a statically allocated array of slots, of size `MBEDTLS_PSA_KEY_SLOT_COUNT`. This value is an upper bound for the total number of volatile keys plus loaded keys. -Since Mbed TLS 3.6.1, there are two variants for the static key store: a hybrid variant (default), and a fully-static variant enabled by the configuration option `MBEDTLS_PSA_STATIC_KEY_SLOTS`. The two variants have the same key store management: the only difference is in how the memory for key data is managed. With fully static key slots, the key data is directly inside the slot, and limited to `MBEDTLS_PSA_KEY_SLOT_BUFFER_SIZE` bytes. With the hybrid key store, the slot contains a pointer to the key data, which is allocated on the heap. +Since Mbed TLS 3.6.2, there are two variants for the static key store: a hybrid variant (default), and a fully-static variant enabled by the configuration option `MBEDTLS_PSA_STATIC_KEY_SLOTS`. The two variants have the same key store management: the only difference is in how the memory for key data is managed. With fully static key slots, the key data is directly inside the slot, and limited to `MBEDTLS_PSA_KEY_SLOT_BUFFER_SIZE` bytes. With the hybrid key store, the slot contains a pointer to the key data, which is allocated on the heap. #### Volatile key identifiers in the static key store From 68c0e3d3a6715e8654481b5c57f7c3fa029ca26d Mon Sep 17 00:00:00 2001 From: Sergey Markelov Date: Wed, 14 Aug 2024 15:06:03 -0700 Subject: [PATCH 074/100] Fix Mbed-TLS build when WIN32_LEAN_AND_MEAN macro is defined globally Signed-off-by: Sergey Markelov --- library/sha256.c | 2 ++ library/x509_crt.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/library/sha256.c b/library/sha256.c index 8b2c34526b..159acccaeb 100644 --- a/library/sha256.c +++ b/library/sha256.c @@ -152,7 +152,9 @@ static int mbedtls_a64_crypto_sha256_determine_support(void) return 1; } #elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif #include #include diff --git a/library/x509_crt.c b/library/x509_crt.c index 2fd56fbd79..53cdcf0266 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -48,7 +48,9 @@ #if defined(MBEDTLS_HAVE_TIME) #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif #include #else #include From 2c62441f965b1c10edd4e3d62da218fcb971cfa9 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 15 Aug 2024 15:53:07 +0100 Subject: [PATCH 075/100] Fix mpi_core_exp_mod documentation Signed-off-by: Janos Follath --- library/bignum_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/bignum_core.c b/library/bignum_core.c index f46df0c8c7..150bc766b2 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -866,7 +866,7 @@ static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N); - /* Set Wtable[i] = A^(2^i) (in Montgomery representation) */ + /* Set Wtable[i] = A^i (in Montgomery representation) */ exp_mod_precompute_window(A, N, AN_limbs, mm, RR, welem, Wtable, temp); From 9d72df8e6d7742741bc66f51e89d7ee65368ca33 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 15 Aug 2024 16:06:19 +0100 Subject: [PATCH 076/100] Optimise public RSA operations Signed-off-by: Janos Follath --- library/rsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/rsa.c b/library/rsa.c index 7eb4a259ea..d0a2695f17 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1259,7 +1259,7 @@ int mbedtls_rsa_public(mbedtls_rsa_context *ctx, } olen = ctx->len; - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &ctx->E, &ctx->N, &ctx->RN)); + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod_unsafe(&T, &T, &ctx->E, &ctx->N, &ctx->RN)); MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen)); cleanup: From a11269187ec25aded7de8c002e75c7fa231d7c09 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 20 Aug 2024 09:56:16 +0100 Subject: [PATCH 077/100] Fix optionally safe hooks declarations Signed-off-by: Janos Follath --- library/bignum_core.c | 5 +++++ library/bignum_core.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/library/bignum_core.c b/library/bignum_core.c index 150bc766b2..463f145148 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -746,6 +746,11 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A, } } +#if defined(MBEDTLS_TEST_HOOKS) +// 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; +#endif + /* * This function calculates the indices of the exponent where the exponentiation algorithm should * start processing. diff --git a/library/bignum_core.h b/library/bignum_core.h index 50c53e6c39..ff6360b3e7 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -818,9 +818,9 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X, mbedtls_mpi_uint *T); #if defined(MBEDTLS_TEST_HOOKS) -int mbedtls_mpi_optionally_safe_codepath; +extern int mbedtls_mpi_optionally_safe_codepath; -static inline void mbedtls_mpi_optionally_safe_codepath_reset() +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; From 8786dd79f715f52444088858ad1e2eb79dd9f25c Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 20 Aug 2024 10:21:54 +0100 Subject: [PATCH 078/100] Disable optionally safe test hook in threading builds Signed-off-by: Janos Follath --- library/bignum_core.c | 10 +++++----- library/bignum_core.h | 5 ++++- tests/suites/test_suite_bignum_core.function | 16 ++++++++-------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/library/bignum_core.c b/library/bignum_core.c index 463f145148..2e2df37bb4 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -746,7 +746,7 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A, } } -#if defined(MBEDTLS_TEST_HOOKS) +#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; #endif @@ -770,7 +770,7 @@ static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E_limb_index = E_bits / biL; *E_bit_index = E_bits % biL; } -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC; #endif } else { @@ -780,7 +780,7 @@ 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) +#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; @@ -802,7 +802,7 @@ 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) +#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC; #endif } else { @@ -810,7 +810,7 @@ static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselec * memory access patterns. */ mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable, AN_limbs, welem, window); -#if defined(MBEDTLS_TEST_HOOKS) +#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; diff --git a/library/bignum_core.h b/library/bignum_core.h index ff6360b3e7..cf6485a148 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -817,7 +817,10 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X, mbedtls_mpi_uint mm, mbedtls_mpi_uint *T); -#if defined(MBEDTLS_TEST_HOOKS) +/* + * 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) diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index 9c864ac870..ce663299d6 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -1232,22 +1232,22 @@ void mpi_core_exp_mod(char *input_N, char *input_A, /* Test the safe variant */ -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) mbedtls_mpi_optionally_safe_codepath_reset(); #endif mbedtls_mpi_core_exp_mod(Y, A, N, N_limbs, E, E_limbs, R2, T); -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_SECRET); #endif TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint))); /* Test the unsafe variant */ -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) mbedtls_mpi_optionally_safe_codepath_reset(); #endif mbedtls_mpi_core_exp_mod_unsafe(Y, A, N, N_limbs, E, E_limbs, R2, T); -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_PUBLIC); #endif TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint))); @@ -1257,21 +1257,21 @@ void mpi_core_exp_mod(char *input_N, char *input_A, TEST_CALLOC(A_copy, A_limbs); memcpy(A_copy, A, sizeof(A_copy) * A_limbs); -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) mbedtls_mpi_optionally_safe_codepath_reset(); #endif mbedtls_mpi_core_exp_mod(A, A, N, N_limbs, E, E_limbs, R2, T); -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_SECRET); #endif TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint))); memcpy(A, A_copy, sizeof(A) * A_limbs); -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) mbedtls_mpi_optionally_safe_codepath_reset(); #endif mbedtls_mpi_core_exp_mod_unsafe(A, A, N, N_limbs, E, E_limbs, R2, T); -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_PUBLIC); #endif TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint))); From afb20796524f5bb746f4e0ee7e4e92a1e90cd380 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 20 Aug 2024 10:41:55 +0100 Subject: [PATCH 079/100] Clean up initialization in _core_exp_mod() Signed-off-by: Janos Follath --- library/bignum_core.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/library/bignum_core.c b/library/bignum_core.c index 2e2df37bb4..4231554b84 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -765,11 +765,21 @@ static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint size_t *E_bit_index) { if (E_public == MBEDTLS_MPI_IS_PUBLIC) { + /* + * Skip leading zero bits. + */ size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs); - if (E_bits != 0) { - *E_limb_index = E_bits / biL; - *E_bit_index = E_bits % biL; + if (E_bits == 0) { + /* + * If E is 0 mbedtls_mpi_core_bitlen() returns 0. Even if that is the case, we will want + * to represent it as a single 0 bit and as such the bitlength will be 1. + */ + E_bits = 1; } + + *E_limb_index = E_bits / biL; + *E_bit_index = E_bits % biL; + #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC; #endif @@ -847,8 +857,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 = E_limbs; - size_t E_bit_index = 0; + size_t E_limb_index; + size_t E_bit_index; exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public, &E_limb_index, &E_bit_index); From 878af1280729c60c4fb965005fae929963b0c20d Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 20 Aug 2024 12:33:42 +0100 Subject: [PATCH 080/100] Fix memory corruption in exp_mod tests Signed-off-by: Janos Follath --- tests/suites/test_suite_bignum_core.function | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index ce663299d6..08dac2e279 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -1255,7 +1255,7 @@ void mpi_core_exp_mod(char *input_N, char *input_A, /* Check both with output aliased to input */ TEST_CALLOC(A_copy, A_limbs); - memcpy(A_copy, A, sizeof(A_copy) * A_limbs); + memcpy(A_copy, A, sizeof(*A_copy) * A_limbs); #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) mbedtls_mpi_optionally_safe_codepath_reset(); @@ -1266,7 +1266,7 @@ void mpi_core_exp_mod(char *input_N, char *input_A, #endif TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint))); - memcpy(A, A_copy, sizeof(A) * A_limbs); + memcpy(A, A_copy, sizeof(*A) * A_limbs); #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) mbedtls_mpi_optionally_safe_codepath_reset(); #endif From a8e13d7c2aa43bf36e9cf7ca342f94e5822e3579 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 21 Aug 2024 14:41:06 +0100 Subject: [PATCH 081/100] Fix incorrect comments on slice numbering The persistent key cache slice is the last slice (not the first as previously stated). Update the numbering-related comments accordingly. Signed-off-by: David Horstmann --- library/psa_crypto_slot_management.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index feedbb5ea4..101a976847 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -77,10 +77,11 @@ MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN | * located after the slices for volatile keys. */ -/* Size of slice 0 containing the cache of persistent and built-in keys. */ +/* Size of the last slice containing the cache of persistent and built-in keys. */ #define PERSISTENT_KEY_CACHE_COUNT MBEDTLS_PSA_KEY_SLOT_COUNT -/* Volatile keys are stored in slices 1 through KEY_SLICE_COUNT inclusive. +/* Volatile keys are stored in slices 0 through + * (KEY_SLOT_VOLATILE_SLICE_COUNT - 1) inclusive. * Each slice is twice the size of the previous slice. * Volatile key identifiers encode the slice number as follows: * bits 30..31: 0b10 (mandated by the PSA Crypto specification). From 43124912c52a037e7ab78cb126c71df7f4de6659 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 21 Aug 2024 14:48:32 +0100 Subject: [PATCH 082/100] Tweak macro check to allow 3 extra key slices We are technically allowed to use all possible values of key slice index that will fit into the bit width we have allocated, so allow all values. Signed-off-by: David Horstmann --- library/psa_crypto_slot_management.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 101a976847..7857aad77a 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -99,7 +99,7 @@ MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN | #if KEY_ID_SLICE_INDEX_WIDTH + KEY_ID_SLOT_INDEX_WIDTH > 30 #error "Not enough room in volatile key IDs for slice index and slot index" #endif -#if KEY_SLICE_COUNT >= (1 << KEY_ID_SLICE_INDEX_WIDTH) - 1 +#if KEY_SLOT_VOLATILE_SLICE_COUNT > (1 << KEY_ID_SLICE_INDEX_WIDTH) #error "Too many slices to fit the slice index in a volatile key ID" #endif #define KEY_SLICE_LENGTH_MAX \ From 9183ba1179ce3e2b11cfea3902ebc0fb45153384 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 21 Aug 2024 15:38:44 +0100 Subject: [PATCH 083/100] Add overflow check for maximum key slot length Signed-off-by: David Horstmann --- library/psa_crypto_slot_management.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 7857aad77a..216e0c27cf 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -111,6 +111,11 @@ MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN | #error "Slice index does not fit in uint8_t for psa_key_slot_t::slice_index" #endif +MBEDTLS_STATIC_ASSERT((KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH + & (SIZE_MAX >> (KEY_SLOT_VOLATILE_SLICE_COUNT - 1))) + == KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH, + "Maximum slice length overflows size_t"); + /* Calculate the volatile key id to use for a given slot. * This function assumes valid parameter values. */ From 11cac75449e5a81cbafc87519e72c3fcedd4ebdd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 21 Aug 2024 21:46:26 +0200 Subject: [PATCH 084/100] Simplify and explain the overflow check for maximum slice length Signed-off-by: Gilles Peskine --- library/psa_crypto_slot_management.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 216e0c27cf..9850d8c750 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -96,6 +96,18 @@ MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN | #define KEY_SLICE_COUNT (KEY_SLOT_VOLATILE_SLICE_COUNT + 1u) #define KEY_SLOT_CACHE_SLICE_INDEX KEY_SLOT_VOLATILE_SLICE_COUNT + +/* Check that the length of the largest slice (calculated as + * KEY_SLICE_LENGTH_MAX below) does not overflow size_t. We use + * an indirect method in case the calculation of KEY_SLICE_LENGTH_MAX + * itself overflows uintmax_t: if (BASE_LENGTH << c) + * overflows size_t then BASE_LENGTH > SIZE_MAX >> c. + */ +#if (KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH > \ + SIZE_MAX >> (KEY_SLOT_VOLATILE_SLICE_COUNT - 1)) +#error "Maximum slice length overflows size_t" +#endif + #if KEY_ID_SLICE_INDEX_WIDTH + KEY_ID_SLOT_INDEX_WIDTH > 30 #error "Not enough room in volatile key IDs for slice index and slot index" #endif @@ -111,11 +123,6 @@ MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN | #error "Slice index does not fit in uint8_t for psa_key_slot_t::slice_index" #endif -MBEDTLS_STATIC_ASSERT((KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH - & (SIZE_MAX >> (KEY_SLOT_VOLATILE_SLICE_COUNT - 1))) - == KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH, - "Maximum slice length overflows size_t"); - /* Calculate the volatile key id to use for a given slot. * This function assumes valid parameter values. */ From 6c2086931d558e92beffff58181626eaf709337c Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 22 Aug 2024 12:34:10 +0100 Subject: [PATCH 085/100] Add changelog Signed-off-by: Janos Follath --- ChangeLog.d/fix-rsa-performance-regression.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 ChangeLog.d/fix-rsa-performance-regression.txt diff --git a/ChangeLog.d/fix-rsa-performance-regression.txt b/ChangeLog.d/fix-rsa-performance-regression.txt new file mode 100644 index 0000000000..abcc7a5adc --- /dev/null +++ b/ChangeLog.d/fix-rsa-performance-regression.txt @@ -0,0 +1,2 @@ +Bugfix + * Fix unintended performance regression when using short RSA public keys. See #9232. From 82976f3548592e44a1328c696008bbf3af7063ad Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 22 Aug 2024 13:00:12 +0100 Subject: [PATCH 086/100] Make mbedtls_mpi_exp_mod_unsafe internal Signed-off-by: Janos Follath --- include/mbedtls/bignum.h | 33 --------------------------------- library/rsa.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 33 deletions(-) diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index a945be3614..8367cd34e6 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -879,39 +879,6 @@ int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b); -/** - * \brief Perform a modular exponentiation: X = A^E mod N - * - * \warning This function is not constant time with respect to \p E (the exponent). - * - * \param X The destination MPI. This must point to an initialized MPI. - * This must not alias E or N. - * \param A The base of the exponentiation. - * This must point to an initialized MPI. - * \param E The exponent MPI. This must point to an initialized MPI. - * \param N The base for the modular reduction. This must point to an - * initialized MPI. - * \param prec_RR A helper MPI depending solely on \p N which can be used to - * speed-up multiple modular exponentiations for the same value - * of \p N. This may be \c NULL. If it is not \c NULL, it must - * point to an initialized MPI. If it hasn't been used after - * the call to mbedtls_mpi_init(), this function will compute - * the helper value and store it in \p prec_RR for reuse on - * subsequent calls to this function. Otherwise, the function - * will assume that \p prec_RR holds the helper value set by a - * previous call to mbedtls_mpi_exp_mod(), and reuse it. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or - * even, or if \c E is negative. - * \return Another negative error code on different kinds of failures. - * - */ -int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *prec_RR); - /** * \brief Perform a modular exponentiation: X = A^E mod N * diff --git a/library/rsa.c b/library/rsa.c index d0a2695f17..b6fea49d89 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1228,6 +1228,16 @@ int mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context *pub, return 0; } +/* + * This function is identical to mbedtls_mpi_exp_mod() the only difference is that this function is + * not constant time. + * + * WARNING! This function is not constant time. + */ +int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR); + /* * Do an RSA public key operation */ From 5d16334e84c3206c380cfe9121847d23601f5e19 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 22 Aug 2024 14:49:58 +0100 Subject: [PATCH 087/100] Improve ChangeLog Co-authored-by: Gilles Peskine Signed-off-by: Janos Follath --- ChangeLog.d/fix-rsa-performance-regression.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/fix-rsa-performance-regression.txt b/ChangeLog.d/fix-rsa-performance-regression.txt index abcc7a5adc..1624ac2618 100644 --- a/ChangeLog.d/fix-rsa-performance-regression.txt +++ b/ChangeLog.d/fix-rsa-performance-regression.txt @@ -1,2 +1,2 @@ Bugfix - * Fix unintended performance regression when using short RSA public keys. See #9232. + * Fix unintended performance regression when using short RSA public keys. Fixes #9232. From 5f316972b2d0ee6ede71102a666df55b5f46e1e8 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 22 Aug 2024 14:53:13 +0100 Subject: [PATCH 088/100] Add header for mbedtls_mpi_exp_mod_unsafe() To silence no previous prototype warnings. And this is the proper way to do it anyway. Signed-off-by: Janos Follath --- library/bignum.c | 1 + library/bignum_internal.h | 50 +++++++++++++++++++++++++ library/rsa.c | 11 +----- tests/suites/test_suite_bignum.function | 1 + 4 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 library/bignum_internal.h diff --git a/library/bignum.c b/library/bignum.c index b1f9c1bf0f..424490951d 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -27,6 +27,7 @@ #include "mbedtls/bignum.h" #include "bignum_core.h" +#include "bignum_internal.h" #include "bn_mul.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" diff --git a/library/bignum_internal.h b/library/bignum_internal.h new file mode 100644 index 0000000000..aceaf55ea2 --- /dev/null +++ b/library/bignum_internal.h @@ -0,0 +1,50 @@ +/** + * \file bignum_internal.h + * + * \brief Internal-only bignum public-key cryptosystem API. + * + * This file declares bignum-related functions that are to be used + * only from within the Mbed TLS library itself. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_BIGNUM_INTERNAL_H +#define MBEDTLS_BIGNUM_INTERNAL_H + +/** + * \brief Perform a modular exponentiation: X = A^E mod N + * + * \warning This function is not constant time with respect to \p E (the exponent). + * + * \param X The destination MPI. This must point to an initialized MPI. + * This must not alias E or N. + * \param A The base of the exponentiation. + * This must point to an initialized MPI. + * \param E The exponent MPI. This must point to an initialized MPI. + * \param N The base for the modular reduction. This must point to an + * initialized MPI. + * \param prec_RR A helper MPI depending solely on \p N which can be used to + * speed-up multiple modular exponentiations for the same value + * of \p N. This may be \c NULL. If it is not \c NULL, it must + * point to an initialized MPI. If it hasn't been used after + * the call to mbedtls_mpi_init(), this function will compute + * the helper value and store it in \p prec_RR for reuse on + * subsequent calls to this function. Otherwise, the function + * will assume that \p prec_RR holds the helper value set by a + * previous call to mbedtls_mpi_exp_mod(), and reuse it. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or + * even, or if \c E is negative. + * \return Another negative error code on different kinds of failures. + * + */ +int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR); + +#endif /* bignum_internal.h */ diff --git a/library/rsa.c b/library/rsa.c index b6fea49d89..557faaf363 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -29,6 +29,7 @@ #include "mbedtls/rsa.h" #include "bignum_core.h" +#include "bignum_internal.h" #include "rsa_alt_helpers.h" #include "rsa_internal.h" #include "mbedtls/oid.h" @@ -1228,16 +1229,6 @@ int mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context *pub, return 0; } -/* - * This function is identical to mbedtls_mpi_exp_mod() the only difference is that this function is - * not constant time. - * - * WARNING! This function is not constant time. - */ -int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *prec_RR); - /* * Do an RSA public key operation */ diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function index f3a64e1837..afa97a4505 100644 --- a/tests/suites/test_suite_bignum.function +++ b/tests/suites/test_suite_bignum.function @@ -3,6 +3,7 @@ #include "mbedtls/entropy.h" #include "constant_time_internal.h" #include "bignum_core.h" +#include "bignum_internal.h" #include "test/constant_flow.h" #if MBEDTLS_MPI_MAX_BITS > 792 From 4c857c49b471d5e85a1148ab26eace3da4376eea Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 22 Aug 2024 15:45:18 +0100 Subject: [PATCH 089/100] Fix Changelog formatting Signed-off-by: Janos Follath --- ChangeLog.d/fix-rsa-performance-regression.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog.d/fix-rsa-performance-regression.txt b/ChangeLog.d/fix-rsa-performance-regression.txt index 1624ac2618..603612a314 100644 --- a/ChangeLog.d/fix-rsa-performance-regression.txt +++ b/ChangeLog.d/fix-rsa-performance-regression.txt @@ -1,2 +1,3 @@ Bugfix - * Fix unintended performance regression when using short RSA public keys. Fixes #9232. + * Fix unintended performance regression when using short RSA public keys. + Fixes #9232. From 41e0cdf8c16f255a8ecf7a49a6342598e580d5cf Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Tue, 11 Jun 2024 18:44:48 +0100 Subject: [PATCH 090/100] Fix issue in handling legacy_compression_methods in ssl_tls13_parse_client_hello() Signed-off-by: Waleed Elmelegy --- library/ssl_tls13_server.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index f5ef92032b..ca3ea53857 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1265,6 +1265,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, mbedtls_ssl_handshake_params *handshake = ssl->handshake; int hrr_required = 0; int no_usable_share_for_key_agreement = 0; + unsigned char legacy_compression_methods_len; + unsigned char legacy_compression_methods; #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) int got_psk = 0; @@ -1362,6 +1364,13 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, p += cipher_suites_len; cipher_suites_end = p; + legacy_compression_methods_len = *p; + legacy_compression_methods = *(p+1); + + if (legacy_compression_methods_len != 1 || legacy_compression_methods != 0) { + return SSL_CLIENT_HELLO_TLS1_2; + } + /* * Search for the supported versions extension and parse it to determine * if the client supports TLS 1.3. From 566ed54d6eed952e5be0b2368ee368963c524f22 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Wed, 19 Jun 2024 15:09:48 +0100 Subject: [PATCH 091/100] Improve handling of legacy_compression_methods in ssl_tls13_parse_client_hello() Signed-off-by: Waleed Elmelegy --- library/ssl_tls13_server.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index ca3ea53857..ae690e538e 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1265,8 +1265,6 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, mbedtls_ssl_handshake_params *handshake = ssl->handshake; int hrr_required = 0; int no_usable_share_for_key_agreement = 0; - unsigned char legacy_compression_methods_len; - unsigned char legacy_compression_methods; #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) int got_psk = 0; @@ -1364,19 +1362,17 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, p += cipher_suites_len; cipher_suites_end = p; - legacy_compression_methods_len = *p; - legacy_compression_methods = *(p+1); - - if (legacy_compression_methods_len != 1 || legacy_compression_methods != 0) { - return SSL_CLIENT_HELLO_TLS1_2; - } + /* Check if we have enough data to for legacy_compression_methods + * and a length byte. + */ + MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1 + p[0]); /* * Search for the supported versions extension and parse it to determine * if the client supports TLS 1.3. */ ret = mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts( - ssl, p + 2, end, + ssl, p + 1 + p[0], end, &supported_versions_data, &supported_versions_data_end); if (ret < 0) { MBEDTLS_SSL_DEBUG_RET(1, From 3918598e52484f4dcaf84b787f8448d1eb22e5b0 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Tue, 25 Jun 2024 10:22:49 +0100 Subject: [PATCH 092/100] Correct a small typo in ssl_tls13_parse_client_hello() Signed-off-by: Waleed Elmelegy --- library/ssl_tls13_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index ae690e538e..27235a7f18 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1362,7 +1362,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, p += cipher_suites_len; cipher_suites_end = p; - /* Check if we have enough data to for legacy_compression_methods + /* Check if we have enough data for legacy_compression_methods * and a length byte. */ MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1 + p[0]); From a1c4f4cab65c6a24de03570d794909e6a8753e5f Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Tue, 25 Jun 2024 18:16:16 +0100 Subject: [PATCH 093/100] Improve comments explaining legacy_methods_compression handling Signed-off-by: Waleed Elmelegy --- library/ssl_tls13_server.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 27235a7f18..9c949bd0b1 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1355,17 +1355,16 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, * compression methods and the length of the extensions. * * cipher_suites cipher_suites_len bytes - * legacy_compression_methods 2 bytes - * extensions_len 2 bytes + * legacy_compression_methods length 1 byte */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cipher_suites_len + 2 + 2); + MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cipher_suites_len + 1); p += cipher_suites_len; cipher_suites_end = p; /* Check if we have enough data for legacy_compression_methods - * and a length byte. + * and the length of the extensions (2 bytes). */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1 + p[0]); + MBEDTLS_SSL_CHK_BUF_READ_PTR(p + 1, end, p[0] + 2); /* * Search for the supported versions extension and parse it to determine From 790f3b16d42711d541589d729de2e26bbdcf7ec8 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 4 Jul 2024 16:38:04 +0000 Subject: [PATCH 094/100] Add regression testing to handling Legacy_compression_methods Signed-off-by: Waleed Elmelegy --- tests/ssl-opt.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 0b8f129048..fbf7f32b99 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -14142,6 +14142,17 @@ run_test "TLS 1.3: no HRR in case of PSK key exchange mode" \ -c "Selected key exchange mode: psk$" \ -c "HTTP/1.0 200 OK" +# Legacy_compression_methods testing + +requires_gnutls +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +run_test "ClientHello parse handle Legacy_compression_methods" \ + "$P_SRV debug_level=3" \ + "$G_CLI --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+COMP-DEFLATE localhost" \ + 0 \ + -c "Handshake was completed" + # Test heap memory usage after handshake requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_MEMORY_DEBUG From 38c8757b2c0de6bab622aaaf8b3dbc9676caf0d3 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Mon, 15 Jul 2024 17:25:04 +0000 Subject: [PATCH 095/100] Improve legacy compression regression testing Signed-off-by: Waleed Elmelegy --- tests/ssl-opt.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index fbf7f32b99..c3891edea2 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -14145,13 +14145,25 @@ run_test "TLS 1.3: no HRR in case of PSK key exchange mode" \ # Legacy_compression_methods testing requires_gnutls +requires_config_enabled MBEDTLS_SSL_SRV_C requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -run_test "ClientHello parse handle Legacy_compression_methods" \ +run_test "TLS 1.2 ClientHello indicating support for deflate compression method (fallback from TLS 1.3)" \ "$P_SRV debug_level=3" \ "$G_CLI --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+COMP-DEFLATE localhost" \ 0 \ - -c "Handshake was completed" + -c "Handshake was completed" \ + -s "dumping .client hello, compression. (2 bytes)" + +requires_gnutls +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +run_test "TLS 1.2 ClientHello indicating support for deflate compression method" \ + "$P_SRV debug_level=3" \ + "$G_CLI --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+COMP-DEFLATE localhost" \ + 0 \ + -c "Handshake was completed" \ + -s "dumping .client hello, compression. (2 bytes)" # Test heap memory usage after handshake requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 From 1297309fdb3bcac9ea1608b88fe5f12e82dfcd8a Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Tue, 16 Jul 2024 10:32:03 +0000 Subject: [PATCH 096/100] Remove redundant legacy compression test Signed-off-by: Waleed Elmelegy --- tests/ssl-opt.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index c3891edea2..216bbd061b 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -14144,17 +14144,6 @@ run_test "TLS 1.3: no HRR in case of PSK key exchange mode" \ # Legacy_compression_methods testing -requires_gnutls -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -run_test "TLS 1.2 ClientHello indicating support for deflate compression method (fallback from TLS 1.3)" \ - "$P_SRV debug_level=3" \ - "$G_CLI --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+COMP-DEFLATE localhost" \ - 0 \ - -c "Handshake was completed" \ - -s "dumping .client hello, compression. (2 bytes)" - requires_gnutls requires_config_enabled MBEDTLS_SSL_SRV_C requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 From f669fef85600989c0426dd69dea5a45a986d3084 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 22 Aug 2024 16:10:10 +0000 Subject: [PATCH 097/100] Add chanelog entry for fixing legacy comprssion methods issue Signed-off-by: Waleed Elmelegy --- ChangeLog.d/fix-legacy-compression-issue.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 ChangeLog.d/fix-legacy-compression-issue.txt diff --git a/ChangeLog.d/fix-legacy-compression-issue.txt b/ChangeLog.d/fix-legacy-compression-issue.txt new file mode 100644 index 0000000000..e51ee24a9b --- /dev/null +++ b/ChangeLog.d/fix-legacy-compression-issue.txt @@ -0,0 +1,7 @@ +Bugfix + * Fix an issue where ssl_tls13_parse_client_hello() assumed legacy_compression_methods + length would always be zero, which is true for TLS 1.3. However, with TLS 1.3 enabled + by default, all ClientHello requests (including TLS 1.2 requests) are initially + processed by ssl_tls13_parse_client_hello() before being passed to the TLS 1.2 + parsing function. This caused an issue where legacy_compression_methods + might not be zero for TLS 1.2 requests, as it is processed earlier. From 5183e1ab17eceb2c7a07c3ded11deab26f3a1423 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 22 Aug 2024 16:27:27 +0000 Subject: [PATCH 098/100] Improve the changelog entry for fixing legacy compression issue Signed-off-by: Waleed Elmelegy --- ChangeLog.d/fix-legacy-compression-issue.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ChangeLog.d/fix-legacy-compression-issue.txt b/ChangeLog.d/fix-legacy-compression-issue.txt index e51ee24a9b..8b2fe23369 100644 --- a/ChangeLog.d/fix-legacy-compression-issue.txt +++ b/ChangeLog.d/fix-legacy-compression-issue.txt @@ -1,7 +1,7 @@ Bugfix - * Fix an issue where ssl_tls13_parse_client_hello() assumed legacy_compression_methods - length would always be zero, which is true for TLS 1.3. However, with TLS 1.3 enabled - by default, all ClientHello requests (including TLS 1.2 requests) are initially - processed by ssl_tls13_parse_client_hello() before being passed to the TLS 1.2 - parsing function. This caused an issue where legacy_compression_methods - might not be zero for TLS 1.2 requests, as it is processed earlier. + * Fix an issue where TLS 1.2 clients who send a ClientHello message with + legacy_compression_methods get a failure in connection because TLS 1.3 + is enabled by default and the server rejects the ClientHello packet as + malformed for TLS 1.3 in a way that stops the fallback to TLS 1.2. + fixes #8995, #9243. + From d930a3e9506d7bb0a25437210647ada3bdd882d6 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 22 Aug 2024 16:33:17 +0000 Subject: [PATCH 099/100] Reduce the wording in changelog entry Signed-off-by: Waleed Elmelegy --- ChangeLog.d/fix-legacy-compression-issue.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ChangeLog.d/fix-legacy-compression-issue.txt b/ChangeLog.d/fix-legacy-compression-issue.txt index 8b2fe23369..2549af8733 100644 --- a/ChangeLog.d/fix-legacy-compression-issue.txt +++ b/ChangeLog.d/fix-legacy-compression-issue.txt @@ -1,7 +1,6 @@ Bugfix - * Fix an issue where TLS 1.2 clients who send a ClientHello message with - legacy_compression_methods get a failure in connection because TLS 1.3 - is enabled by default and the server rejects the ClientHello packet as - malformed for TLS 1.3 in a way that stops the fallback to TLS 1.2. + * Fixes an issue where some TLS 1.2 clients could not connect to an + Mbed TLS 3.6.0 server, due to incorrect handling of + legacy_compression_methods in the ClientHello. fixes #8995, #9243. From 8ac9caf89be14396a7bbe7133fb1d97096f71b1c Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 22 Aug 2024 16:42:18 +0000 Subject: [PATCH 100/100] Fix the capitalisation in the changelog entry Signed-off-by: Waleed Elmelegy --- ChangeLog.d/fix-legacy-compression-issue.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/fix-legacy-compression-issue.txt b/ChangeLog.d/fix-legacy-compression-issue.txt index 2549af8733..b77e7a44f0 100644 --- a/ChangeLog.d/fix-legacy-compression-issue.txt +++ b/ChangeLog.d/fix-legacy-compression-issue.txt @@ -2,5 +2,5 @@ Bugfix * Fixes an issue where some TLS 1.2 clients could not connect to an Mbed TLS 3.6.0 server, due to incorrect handling of legacy_compression_methods in the ClientHello. - fixes #8995, #9243. + Fixes #8995, #9243.