Merge pull request #1282 from gilles-peskine-arm/merge-3.6-restricted-20240823

Merge 3.6 into -restricted
This commit is contained in:
Manuel Pégourié-Gonnard 2024-08-26 12:07:24 +02:00 committed by GitHub
commit 8b8228ce2e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
102 changed files with 1978 additions and 636 deletions

View File

@ -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")

View File

@ -0,0 +1,39 @@
New deprecations
* The following cryptographic mechanisms are planned to be removed
in Mbed TLS 4.0:
- DES (including 3DES).
- 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 cipher suites are planned to be removed from (D)TLS 1.2
in Mbed TLS 4.0:
- 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 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;
- 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.
- 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 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
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.

View File

@ -0,0 +1,10 @@
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
MBEDTLS_PSA_KEY_SLOT_COUNT is more than 4096.

View File

@ -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.

View File

@ -0,0 +1,6 @@
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.

View File

@ -0,0 +1,3 @@
Bugfix
* Fix unintended performance regression when using short RSA public keys.
Fixes #9232.

View File

@ -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.

View File

@ -0,0 +1,3 @@
Bugfix
* Document and enforce the limitation of mbedtls_psa_register_se_key()
to persistent keys. Resolves #9253.

View File

@ -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.

View File

@ -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
@ -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:

@ -1 +1 @@
Subproject commit 331565b041f794df2da76394b3b0039abce30355
Subproject commit 94599c0e3b5036e086446a51a3f79640f70f22f6

View File

@ -880,7 +880,7 @@ 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.

View File

@ -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

View File

@ -32,12 +32,27 @@
#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)
#include "mbedtls/aes.h"
#else
/* 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 enabled, 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 "psa/crypto.h"
#else
#include "mbedtls/aes.h"
#endif
#include "entropy.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,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_AES_C)
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
/*

View File

@ -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.
@ -4032,13 +4049,22 @@
//#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.
* 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.
*
* 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

View File

@ -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);

View File

@ -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.
@ -479,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)

View File

@ -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)

View File

@ -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"
@ -1610,9 +1611,13 @@ 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)
/*
* 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, int E_public,
const mbedtls_mpi *N, mbedtls_mpi *prec_RR)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -1695,7 +1700,11 @@ 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);
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);
}
@ -1720,6 +1729,20 @@ 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, 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, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);
}
/*
* Greatest common divisor: G = gcd(A, B) (HAC 14.54)
*/

View File

@ -746,7 +746,93 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A,
}
}
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
// Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
int mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
#endif
/*
* 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) {
/*
* Skip leading zero bits.
*/
size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs);
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
} 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;
#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;
}
#endif
}
}
/*
* 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);
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
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) && !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;
}
#endif
}
}
/* 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,16 +844,25 @@ 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)
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,
int E_public,
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;
size_t E_bit_index;
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
@ -786,7 +881,7 @@ void mbedtls_mpi_core_exp_mod(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);
@ -798,11 +893,6 @@ void mbedtls_mpi_core_exp_mod(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;
/* 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 +918,9 @@ 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);
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);
@ -841,6 +930,42 @@ 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,
MBEDTLS_MPI_IS_SECRET,
RR,
T);
}
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,
MBEDTLS_MPI_IS_PUBLIC,
RR,
T);
}
mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
mbedtls_mpi_uint c, /* doubles as carry */

View File

@ -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 0x2a2a2a2a
#define MBEDTLS_MPI_IS_SECRET 0
/** Count leading zero bits in a given integer.
*
* \warning The result is undefined if \p a == 0
@ -604,6 +625,42 @@ 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.
*
* \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.
*
* \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.
*/
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:
* X = A^E mod N, where \p A is already in Montgomery form.
@ -760,4 +817,17 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X,
mbedtls_mpi_uint mm,
mbedtls_mpi_uint *T);
/*
* Can't define thread local variables with our abstraction layer: do nothing if threading is on.
*/
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
extern int mbedtls_mpi_optionally_safe_codepath;
static inline void mbedtls_mpi_optionally_safe_codepath_reset(void)
{
// Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
}
#endif
#endif /* MBEDTLS_BIGNUM_CORE_H */

50
library/bignum_internal.h Normal file
View File

@ -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 */

View File

@ -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)

View File

@ -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,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_AES_C)
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_AES_C)
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_AES_C)
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_AES_C)
#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_AES_C)
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_AES_C)
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_AES_C)
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_AES_C)
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
@ -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,18 +352,18 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
/*
* Crypt counter block
*/
#if defined(MBEDTLS_AES_C)
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_AES_C)
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_AES_C)
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_AES_C)
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)

View File

@ -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;
@ -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
@ -2149,6 +2168,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) {

View File

@ -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;
/*
@ -78,35 +80,77 @@ 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;
/*
* Number of functions registered as reading the material in the key slot.
#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.
*
* 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;
* 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 */
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.
*
* 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 +213,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)

View File

@ -27,8 +27,166 @@
#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");
#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 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 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).
* 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
/* 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
#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 \
(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)
{
/* 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.
* 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)
#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.
*
* 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;
@ -51,6 +209,125 @@ 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);
#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;
}
}
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;
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];
}
#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
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);
@ -112,12 +389,13 @@ 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. */
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;
@ -127,8 +405,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))) {
@ -151,29 +429,169 @@ 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;
}
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++) {
#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 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) {
continue;
}
#endif
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;
/* We assert at compile time that the slice index fits in uint8_t. */
slot->slice_index = (uint8_t) 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 =
(int32_t) next_free - (int32_t) 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)
{
@ -186,9 +604,19 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
goto error;
}
#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 */
/* 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 < 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;
@ -226,8 +654,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;
@ -236,7 +674,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;
}
@ -395,9 +832,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(
@ -465,12 +901,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;
}
@ -604,7 +1040,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);
@ -639,7 +1075,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);
@ -654,34 +1090,39 @@ 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;
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;
}
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;
#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 (slot->state == PSA_SLOT_EMPTY) {
++stats->empty_slots;
continue;
}
}
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 (psa_key_slot_has_readers(slot)) {
++stats->locked_slots;
}
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;
}
}
}
}

View File

@ -15,20 +15,26 @@
/** 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.
*
* 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.
*/
#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
#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.
*
@ -94,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.
@ -113,13 +137,22 @@ 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. 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
* \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 +161,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
@ -174,10 +230,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;
}

View File

@ -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"
@ -1259,7 +1260,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:

View File

@ -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 <Windows.h>
#include <processthreadsapi.h>

View File

@ -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

View File

@ -3923,7 +3923,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;

View File

@ -1355,19 +1355,23 @@ 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 the length of the extensions (2 bytes).
*/
MBEDTLS_SSL_CHK_BUF_READ_PTR(p + 1, end, p[0] + 2);
/*
* 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,

View File

@ -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 <windows.h>
#else
#include <time.h>

View File

@ -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++) {

View File

@ -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);

View File

@ -1,5 +1,6 @@
#include <stdint.h>
#include "mbedtls/pkcs7.h"
#include "common.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{

View File

@ -1,6 +1,7 @@
#include <stdint.h>
#include <stdlib.h>
#include "mbedtls/pk.h"
#include "common.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{

View File

@ -1,5 +1,6 @@
#include <stdint.h>
#include "mbedtls/x509_crl.h"
#include "common.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{

View File

@ -1,5 +1,6 @@
#include <stdint.h>
#include "mbedtls/x509_crt.h"
#include "common.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{

View File

@ -1,5 +1,6 @@
#include <stdint.h>
#include "mbedtls/x509_csr.h"
#include "common.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{

View File

@ -1,14 +1,13 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#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;

View File

@ -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++) {
@ -87,7 +87,7 @@ void print_buf(const char *title, unsigned char *buf, size_t len)
* 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;

View File

@ -39,8 +39,8 @@ int main(void)
#define DEV_RANDOM_THRESHOLD 32
int dev_random_entropy_poll(void *data, unsigned char *output,
size_t len, size_t *olen)
static int dev_random_entropy_poll(void *data, unsigned char *output,
size_t len, size_t *olen)
{
FILE *file;
size_t ret, left = len;

View File

@ -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++) {

View File

@ -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++) {
@ -90,7 +90,7 @@ void print_buf(const char *title, uint8_t *buf, size_t len)
* 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);

View File

@ -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];

View File

@ -597,8 +597,8 @@ 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,
const char *additional_description)
static int report_cid_usage(mbedtls_ssl_context *ssl,
const char *additional_description)
{
int ret;
unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX];

View File

@ -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,8 +247,8 @@ 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,
const size_t in_line, const char *prefix)
static void print_hex(const uint8_t *b, size_t len,
const size_t in_line, const char *prefix)
{
size_t i = 0;
const uint8_t *end = b + len;
@ -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,8 +509,8 @@ 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,
int session_cfg_flag)
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;
int ciphersuite_id;
@ -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;

View File

@ -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,8 +878,8 @@ error:
/*
* SNI callback.
*/
int sni_callback(void *p_info, mbedtls_ssl_context *ssl,
const unsigned char *name, size_t name_len)
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,8 +1027,8 @@ error:
/*
* PSK callback
*/
int psk_callback(void *p_info, mbedtls_ssl_context *ssl,
const unsigned char *name, size_t name_len)
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,11 +1105,11 @@ typedef struct {
void *p_rng;
} ssl_async_key_context_t;
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)
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)
{
if (ctx->slots_used >= sizeof(ctx->slots) / sizeof(*ctx->slots)) {
return -1;
@ -1332,8 +1332,8 @@ 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,
const char *additional_description)
static int report_cid_usage(mbedtls_ssl_context *ssl,
const char *additional_description)
{
int ret;
unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX];
@ -1376,16 +1376,17 @@ 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));
}
/* Functions for session ticket tests */
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)
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)
{
int ret;
unsigned char *p = start;
@ -1410,8 +1411,8 @@ 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,
unsigned char *buf, size_t len)
static int dummy_ticket_parse(void *p_ticket, mbedtls_ssl_session *session,
unsigned char *buf, size_t len)
{
int ret;
((void) p_ticket);
@ -1467,9 +1468,9 @@ 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 */
int parse_cipher(char *buf)
static int parse_cipher(char *buf)
{
if (strcmp(buf, "AES-128-CCM")) {
return MBEDTLS_CIPHER_AES_128_CCM;

View File

@ -12,13 +12,13 @@
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
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)
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)
{
eap_tls_keys *keys = (eap_tls_keys *) p_expkey;
@ -36,13 +36,13 @@ void eap_tls_key_derivation(void *p_expkey,
keys->tls_prf_type = tls_prf_type;
}
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)
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)
{
char nss_keylog_line[200];
size_t const client_random_len = 32;
@ -106,13 +106,13 @@ exit:
}
#if defined(MBEDTLS_SSL_DTLS_SRTP)
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)
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)
{
dtls_srtp_keys *keys = (dtls_srtp_keys *) p_expkey;
@ -131,8 +131,8 @@ void dtls_srtp_key_derivation(void *p_expkey,
}
#endif /* MBEDTLS_SSL_DTLS_SRTP */
int ssl_check_record(mbedtls_ssl_context const *ssl,
unsigned char const *buf, size_t len)
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;
unsigned char *tmp_buf;
@ -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,8 +223,8 @@ 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,
uint32_t timeout)
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;
int ret;
@ -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,8 +319,8 @@ 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,
uint32_t flags)
static int x509_crt_verify_info(char *buf, size_t size, const char *prefix,
uint32_t flags)
{
#if !defined(MBEDTLS_X509_REMOVE_INFO)
return mbedtls_x509_crt_verify_info(buf, size, prefix, flags);
@ -352,7 +352,8 @@ 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)
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
static void mbedtls_print_supported_sig_algs(void)
{
mbedtls_printf("supported signature algorithms:\n");
mbedtls_printf("\trsa_pkcs1_sha256 ");
@ -373,3 +374,4 @@ void mbedtls_print_supported_sig_algs(void)
mbedtls_printf("ecdsa_sha1\n");
mbedtls_printf("\n");
}
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */

View File

@ -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,16 +122,16 @@ exit:
/* Platform features */
/****************************************************************/
void null_pointer_dereference(const char *name)
static void null_pointer_dereference(const char *name)
{
(void) 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);
}
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)

View File

@ -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)

View File

@ -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,9 +663,9 @@ int send_delayed(void)
static unsigned char held[2048] = { 0 };
#define HOLD_MAX 2
int handle_message(const char *way,
mbedtls_net_context *dst,
mbedtls_net_context *src)
static int handle_message(const char *way,
mbedtls_net_context *dst,
mbedtls_net_context *src)
{
int ret;
packet cur;

View File

@ -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");

View File

@ -45,8 +45,8 @@ struct options {
const char *output_file; /* where to store the output */
} opt;
int convert_pem_to_der(const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen)
static int convert_pem_to_der(const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen)
{
int ret;
const unsigned char *s1, *s2, *end = input + ilen;

View File

@ -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;
int write_certificate_request(mbedtls_x509write_csr *req, const char *output_file,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
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 ret;
FILE *f;

View File

@ -204,9 +204,9 @@ struct options {
int format; /* format */
} opt;
int write_certificate(mbedtls_x509write_cert *crt, const char *output_file,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
static int write_certificate(mbedtls_x509write_cert *crt, const char *output_file,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
int ret;
FILE *f;
@ -249,8 +249,8 @@ int write_certificate(mbedtls_x509write_cert *crt, const char *output_file,
return 0;
}
int parse_serial_decimal_format(unsigned char *obuf, size_t obufmax,
const char *ibuf, size_t *len)
static int parse_serial_decimal_format(unsigned char *obuf, size_t obufmax,
const char *ibuf, size_t *len)
{
unsigned long long int dec;
unsigned int remaining_bytes = sizeof(dec);

View File

@ -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;

View File

@ -16,6 +16,8 @@
#include <psa/crypto.h>
#endif
#include <mbedtls/ctr_drbg.h>
#if defined(MBEDTLS_PSA_CRYPTO_C)
/** Initialize the PSA Crypto subsystem. */
#define PSA_INIT() PSA_ASSERT(psa_crypto_init())
@ -430,12 +432,32 @@ 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)
#define AES_PSA_INIT() ((void) 0)
#define AES_PSA_DONE() ((void) 0)
#else /* MBEDTLS_AES_C */
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
#define AES_PSA_INIT() PSA_INIT()
#define AES_PSA_DONE() PSA_DONE()
#endif /* MBEDTLS_AES_C */
#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 */
#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 */

View File

@ -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

View File

@ -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 () {

View File

@ -15,6 +15,8 @@
#include <mbedtls/asn1.h>
#include <test/asn1_helpers.h>
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)

View File

@ -10,6 +10,8 @@
#include <test/helpers.h>
#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
#include <psa/crypto.h>
#include <psa/crypto_extra.h>
@ -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 */

View File

@ -13,6 +13,10 @@
#include <psa_crypto_slot_management.h>
#include <test/psa_crypto_helpers.h>
#if defined(MBEDTLS_CTR_DRBG_C)
#include <mbedtls/ctr_drbg.h>
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include <psa/crypto.h>
@ -70,20 +74,14 @@ 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)
/* 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) {
/* 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.";
}
#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.";
}

View File

@ -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 <test/memory.h>
#include <test/psa_memory_poisoning_wrappers.h>
#include "psa_crypto_invasive.h"

View File

@ -950,10 +950,10 @@ 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,
unsigned char *buf, int buf_len,
int *written,
const int expected_fragments)
static int mbedtls_ssl_write_fragment(mbedtls_ssl_context *ssl,
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
@ -997,10 +997,10 @@ exit:
* Read application data and increase read counter and fragments counter
* if necessary.
*/
int mbedtls_ssl_read_fragment(mbedtls_ssl_context *ssl,
unsigned char *buf, int buf_len,
int *read, int *fragments,
const int expected_fragments)
static int mbedtls_ssl_read_fragment(mbedtls_ssl_context *ssl,
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

View File

@ -14403,6 +14403,18 @@ 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_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
requires_config_enabled MBEDTLS_MEMORY_DEBUG

View File

@ -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

View File

@ -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";

View File

@ -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;

View File

@ -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;

View File

@ -122,8 +122,8 @@ exit:
return ERR_PARSE_INCONSISTENCY;
}
int get_len_step(const data_t *input, size_t buffer_size,
size_t actual_length)
static int get_len_step(const data_t *input, size_t buffer_size,
size_t actual_length)
{
unsigned char *buf = NULL;
unsigned char *p = NULL;

View File

@ -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,8 +26,8 @@ exit:
return 0;
}
int generic_write_finish_step(generic_write_data_t *data,
const data_t *expected, int ret)
static int generic_write_finish_step(generic_write_data_t *data,
const data_t *expected, int ret)
{
int ok = 0;

View File

@ -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
@ -32,6 +33,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;
@ -44,9 +46,9 @@ 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,
unsigned char *buf,
size_t len)
static int mbedtls_test_mpi_miller_rabin_determinizer(void *state,
unsigned char *buf,
size_t len)
{
mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random *) state;
@ -73,6 +75,7 @@ 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)

View File

@ -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,19 +1230,56 @@ void mpi_core_exp_mod(char *input_N, char *input_A,
TEST_CALLOC(T, working_limbs);
mbedtls_mpi_core_exp_mod(Y, A, N, N_limbs, E, E_limbs, R2, T);
/* Test the safe variant */
#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) && !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)));
/* Check when output aliased to input */
/* Test the unsafe variant */
#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) && !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)));
/* 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) && !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) && !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) && !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) && !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)));
exit:
mbedtls_free(T);
mbedtls_free(A);
mbedtls_free(A_copy);
mbedtls_free(E);
mbedtls_free(N);
mbedtls_free(X);

View File

@ -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) {

View File

@ -1,7 +1,11 @@
/* 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;

View File

@ -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];

View File

@ -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;

View File

@ -1,9 +1,9 @@
/* BEGIN_HEADER */
#include "mbedtls/dhm.h"
int check_get_value(const mbedtls_dhm_context *ctx,
mbedtls_dhm_parameter param,
const mbedtls_mpi *expected)
static int check_get_value(const mbedtls_dhm_context *ctx,
mbedtls_dhm_parameter param,
const mbedtls_mpi *expected)
{
mbedtls_mpi actual;
int ok = 0;

View File

@ -60,12 +60,14 @@ 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
*/
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 +77,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;
@ -84,7 +86,9 @@ 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,7 +115,8 @@ 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)
#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 @@ 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 */

View File

@ -2,8 +2,8 @@
#include "lmots.h"
#include "mbedtls/lms.h"
#if defined(MBEDTLS_TEST_HOOKS)
int check_lmots_private_key_for_leak(unsigned char *sig)
#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 @@ 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 */

View File

@ -221,9 +221,9 @@ exit:
}
#if defined(MBEDTLS_PSA_CRYPTO_C)
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)
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_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status;
@ -320,11 +320,11 @@ 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,
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)
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_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
@ -467,19 +467,19 @@ exit:
}
#endif /* MBEDTLS_PSA_CRYPTO_C */
#if defined(MBEDTLS_RSA_C)
int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen,
const unsigned char *input, unsigned char *output,
size_t output_max_len)
#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)
{
return mbedtls_rsa_pkcs1_decrypt((mbedtls_rsa_context *) ctx,
mbedtls_test_rnd_std_rand, NULL,
olen, input, output, output_max_len);
}
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)
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)
{
((void) f_rng);
((void) p_rng);
@ -487,11 +487,11 @@ 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;
}
#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. */
@ -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;

View File

@ -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;

View File

@ -18,7 +18,7 @@
#else
#include <unistd.h>
#endif
void sleep_ms(int milliseconds)
static void sleep_ms(int milliseconds)
{
#if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \
defined(__MINGW32__) || defined(_WIN64)

View File

@ -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;
@ -175,12 +153,12 @@ static int construct_fake_rsa_key(unsigned char *buffer,
}
#endif /* MBEDTLS_ASN1_WRITE_C */
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)
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)
{
mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@ -207,12 +185,12 @@ exit:
return 0;
}
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)
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)
{
mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@ -285,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) \
@ -1338,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;
@ -1354,7 +1333,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;
@ -1428,7 +1407,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;
@ -1456,6 +1435,7 @@ 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;
@ -1468,7 +1448,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;

View File

@ -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

View File

@ -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,

View File

@ -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,12 +204,23 @@ 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();
}
exit:
PSA_DONE();
}
/* END_CASE */

View File

@ -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)
@ -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,9 +192,9 @@ void key_type_classification(psa_key_type_t type, unsigned flags)
exit:;
}
void mac_algorithm_core(psa_algorithm_t alg, int classification_flags,
psa_key_type_t key_type, size_t key_bits,
size_t length)
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)
{
/* Algorithm classification */
TEST_ASSERT(!PSA_ALG_IS_HASH(alg));
@ -218,9 +218,9 @@ void mac_algorithm_core(psa_algorithm_t alg, int classification_flags,
exit:;
}
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)
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)
{
/* Algorithm classification */
TEST_ASSERT(!PSA_ALG_IS_HASH(alg));

View File

@ -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 */

View File

@ -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 */

View File

@ -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)
@ -169,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

View File

@ -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)
@ -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;

View File

@ -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))
@ -162,11 +162,11 @@ 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,
psa_key_slot_number_t slot_number,
uint8_t *p_data,
size_t data_size,
size_t *p_data_length)
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)
{
(void) context;
(void) p_data;
@ -179,11 +179,11 @@ 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,
psa_key_slot_number_t slot_number,
uint8_t *p_data,
size_t data_size,
size_t *p_data_length)
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)
{
(void) context;
(void) p_data;
@ -196,14 +196,14 @@ 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,
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)
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)
{
(void) context;
(void) p_hash;
@ -219,13 +219,13 @@ 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,
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)
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)
{
(void) context;
(void) p_hash;
@ -240,11 +240,11 @@ 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,
void *persistent_data,
const psa_key_attributes_t *attributes,
psa_key_creation_method_t method,
psa_key_slot_number_t *key_slot)
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) drv_context;
(void) persistent_data;
@ -258,9 +258,9 @@ 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,
void *persistent_data,
psa_key_slot_number_t slot_number)
static psa_status_t mock_destroy(psa_drv_se_context_t *context,
void *persistent_data,
psa_key_slot_number_t slot_number)
{
(void) context;
(void) persistent_data;

View File

@ -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_STORE_DYNAMIC is enabled and
# volatile key IDs are assigned starting with the lowest value, and when
# 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
Open failure: non-existent identifier
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
@ -214,8 +225,25 @@ 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: 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
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

View File

@ -98,6 +98,31 @@ exit:
return 0;
}
#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
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@ -813,21 +838,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 +866,119 @@ 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;
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;
#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;
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);
/* 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. */
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);
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && defined(MBEDTLS_TEST_HOOKS)
mbedtls_test_hook_psa_volatile_key_slice_length = NULL;
#endif
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
void key_slot_eviction_to_import_new_key(int lifetime_arg)
{
@ -919,7 +1055,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;
@ -959,7 +1095,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++) {

View File

@ -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

View File

@ -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);

Some files were not shown because too many files have changed in this diff Show More