Merge branch 'development' into driver-wrapper-key-agreement

This commit is contained in:
Aditya Deshpande 2022-11-22 17:58:52 +00:00
commit 5e3c70e3be
52 changed files with 2701 additions and 825 deletions

View file

@ -0,0 +1,5 @@
Bugfix
* Fix a bug whereby the the list of signature algorithms sent as part of the
TLS 1.2 server certificate request would get corrupted, meaning the first
algorithm would not get sent and an entry consisting of two random bytes
would be sent instead. Found by Serban Bejan and Dudek Sebastian.

View file

@ -0,0 +1,4 @@
Bugfix
* Fix bug in error reporting in dh_genprime.c where upon failure,
the error code returned by mbedtls_mpi_write_file() is overwritten
and therefore not printed.

View file

@ -0,0 +1,4 @@
Bugfix
* Fix undefined behavior (typically harmless in practice) of
mbedtls_mpi_add_mpi(), mbedtls_mpi_add_abs() and mbedtls_mpi_add_int()
when both operands are 0 and the left operand is represented with 0 limbs.

View file

@ -0,0 +1,4 @@
Bugfix
* Fix undefined behavior (typically harmless in practice) when some bignum
functions receive the most negative value of mbedtls_mpi_sint. Credit
to OSS-Fuzz. Fixes #6597.

View file

@ -0,0 +1,6 @@
Bugfix
* In the bignum module, operations of the form (-A) - (+A) or (-A) - (-A)
with A > 0 created an unintended representation of the value 0 which was
not processed correctly by some bignum operations. Fix this. This had no
consequence on cryptography code, but might affect applications that call
bignum directly and use negative numbers.

View file

@ -13,6 +13,7 @@
# - the set of tests skipped in the driver-only build is the same as in an
# equivalent software-based configuration, or the difference is small enough,
# justified, and a github issue is created to track it.
# This part is verified by tests/scripts/analyze_outcomes.py
#
# WARNING: this script checks out a commit other than the head of the current
# branch; it checks out the current branch again when running successfully,
@ -26,30 +27,12 @@
# re-running this script (for example "get numbers before this PR").
# ----- BEGIN edit this -----
# The component in all.sh that builds and tests with drivers.
DRIVER_COMPONENT=test_psa_crypto_config_accel_hash_use_psa
# A similar configuration to that of the component, except without drivers,
# for comparison.
reference_config () {
# start with full
scripts/config.py full
# use PSA config and disable driver-less algs as in the component
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_ECB_NO_PADDING
# disable options as in the component
# (no need to disable whole modules, we'll just skip their test suite)
scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
}
# Space-separated list of test suites to ignore:
# if SSS is in that list, test_suite_SSS and test_suite_SSS.* are ignored.
IGNORE="md mdx shax" # accelerated
IGNORE="$IGNORE entropy hmac_drbg random" # disabled (ext. RNG)
IGNORE="$IGNORE psa_crypto_init" # needs internal RNG
IGNORE="$IGNORE hkdf" # disabled in the all.sh component tested
# Compare only "reference vs driver" or also "before vs after"?
BEFORE_AFTER=1 # 0 or 1
# ----- END edit this -----
set -eu
@ -65,38 +48,27 @@ record() {
make check
}
if [ "$BEFORE_AFTER" -eq 1 ]; then
# save current HEAD
HEAD=$(git branch --show-current)
# save current HEAD
HEAD=$(git branch --show-current)
# get the numbers before this PR for default and full
cleanup
git checkout $(git merge-base HEAD development)
record "before-default"
cleanup
scripts/config.py full
record "before-full"
# get the numbers now for default and full
cleanup
git checkout $HEAD
record "after-default"
cleanup
scripts/config.py full
record "after-full"
fi
# get the numbers now for driver-only and reference
# get the numbers before this PR for default and full
cleanup
reference_config
record "reference"
git checkout $(git merge-base HEAD development)
record "before-default"
cleanup
export MBEDTLS_TEST_OUTCOME_FILE="$PWD/outcome-drivers.csv"
export SKIP_SSL_OPT_COMPAT_SH=1
tests/scripts/all.sh -k test_psa_crypto_config_accel_hash_use_psa
scripts/config.py full
record "before-full"
# get the numbers now for default and full
cleanup
git checkout $HEAD
record "after-default"
cleanup
scripts/config.py full
record "after-full"
# analysis
@ -156,8 +128,5 @@ compare_builds () {
}
populate_suites
if [ "$BEFORE_AFTER" -eq 1 ]; then
compare_builds before-default after-default
compare_builds before-full after-full
fi
compare_builds reference drivers
compare_builds before-default after-default
compare_builds before-full after-full

View file

@ -179,6 +179,20 @@
#endif /* !MBEDTLS_NO_UDBL_DIVISION */
#endif /* !MBEDTLS_HAVE_INT64 */
/** \typedef mbedtls_mpi_uint
* \brief The type of machine digits in a bignum, called _limbs_.
*
* This is always an unsigned integer type with no padding bits. The size
* is platform-dependent.
*/
/** \typedef mbedtls_mpi_sint
* \brief The signed type corresponding to #mbedtls_mpi_uint.
*
* This is always an signed integer type with no padding bits. The size
* is platform-dependent.
*/
#ifdef __cplusplus
extern "C" {
#endif
@ -188,9 +202,27 @@ extern "C" {
*/
typedef struct mbedtls_mpi
{
int MBEDTLS_PRIVATE(s); /*!< Sign: -1 if the mpi is negative, 1 otherwise */
size_t MBEDTLS_PRIVATE(n); /*!< total # of limbs */
mbedtls_mpi_uint *MBEDTLS_PRIVATE(p); /*!< pointer to limbs */
/** Sign: -1 if the mpi is negative, 1 otherwise.
*
* The number 0 must be represented with `s = +1`. Although many library
* functions treat all-limbs-zero as equivalent to a valid representation
* of 0 regardless of the sign bit, there are exceptions, so bignum
* functions and external callers must always set \c s to +1 for the
* number zero.
*
* Note that this implies that calloc() or `... = {0}` does not create
* a valid MPI representation. You must call mbedtls_mpi_init().
*/
int MBEDTLS_PRIVATE(s);
/** Total number of limbs in \c p. */
size_t MBEDTLS_PRIVATE(n);
/** Pointer to limbs.
*
* This may be \c NULL if \c n is 0.
*/
mbedtls_mpi_uint *MBEDTLS_PRIVATE(p);
}
mbedtls_mpi;

View file

@ -842,10 +842,10 @@
"but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx"
#endif
/* Early data requires PSK related mode defined */
#if defined(MBEDTLS_SSL_EARLY_DATA) && \
( !defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) && \
!defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED))
( !defined(MBEDTLS_SSL_SESSION_TICKETS) || \
( !defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) && \
!defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) ) )
#error "MBEDTLS_SSL_EARLY_DATA defined, but not all prerequisites"
#endif

View file

@ -1637,7 +1637,8 @@
*
* Enable support for RFC 8446 TLS 1.3 early data.
*
* Requires: MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED or
* Requires: MBEDTLS_SSL_SESSION_TICKETS and either
* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED or
* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
*
* Comment this to disable support for early data. If MBEDTLS_SSL_PROTO_TLS1_3
@ -1647,7 +1648,7 @@
* production.
*
*/
//#define MBEDTLS_SSL_EARLY_DATA
#define MBEDTLS_SSL_EARLY_DATA
/**
* \def MBEDTLS_SSL_PROTO_DTLS

View file

@ -801,6 +801,29 @@ typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert;
typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item;
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN 0
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 1
#define MBEDTLS_SSL_EARLY_DATA_STATUS_INDICATION_SENT 2
#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 3
#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 4
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
typedef uint8_t mbedtls_ssl_tls13_ticket_flags;
#define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK /* 1U << 0 */
#define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL /* 1U << 2 */
#define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA ( 1U << 3 )
#define MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK \
( MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION | \
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION | \
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA )
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
/**
* \brief Callback type: server-side session cache getter
*
@ -1783,6 +1806,10 @@ struct mbedtls_ssl_context
* and #MBEDTLS_SSL_CID_DISABLED. */
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
int MBEDTLS_PRIVATE(early_data_status);
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
/** Callback to export key block and master secret */
mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys);
void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */

View file

@ -1829,7 +1829,7 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation );
*/
#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
#define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, 0, 0, \
MBEDTLS_SVC_KEY_ID_INIT, \
NULL, 0 , \
PSA_PAKE_ROLE_NONE, {0}, 0, 0, \
{.dummy = 0}}
#else
@ -1920,7 +1920,8 @@ struct psa_pake_operation_s
#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
unsigned int MBEDTLS_PRIVATE(input_step);
unsigned int MBEDTLS_PRIVATE(output_step);
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(password);
uint8_t* MBEDTLS_PRIVATE(password);
size_t MBEDTLS_PRIVATE(password_len);
psa_pake_role_t MBEDTLS_PRIVATE(role);
uint8_t MBEDTLS_PRIVATE(buffer[MBEDTLS_PSA_PAKE_BUFFER_SIZE]);
size_t MBEDTLS_PRIVATE(buffer_length);

View file

@ -252,6 +252,17 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
memcpy( Y, &T, sizeof( mbedtls_mpi ) );
}
static inline mbedtls_mpi_uint mpi_sint_abs( mbedtls_mpi_sint z )
{
if( z >= 0 )
return( z );
/* Take care to handle the most negative value (-2^(biL-1)) correctly.
* A naive -z would have undefined behavior.
* Write this in a way that makes popular compilers happy (GCC, Clang,
* MSVC). */
return( (mbedtls_mpi_uint) 0 - (mbedtls_mpi_uint) z );
}
/*
* Set value from integer
*/
@ -263,7 +274,7 @@ int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
memset( X->p, 0, X->n * ciL );
X->p[0] = ( z < 0 ) ? -z : z;
X->p[0] = mpi_sint_abs( z );
X->s = ( z < 0 ) ? -1 : 1;
cleanup:
@ -853,7 +864,7 @@ int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET( X != NULL );
*p = ( z < 0 ) ? -z : z;
*p = mpi_sint_abs( z );
Y.s = ( z < 0 ) ? -1 : 1;
Y.n = 1;
Y.p = p;
@ -889,6 +900,11 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
if( B->p[j - 1] != 0 )
break;
/* Exit early to avoid undefined behavior on NULL+0 when X->n == 0
* and B is 0 (of any size). */
if( j == 0 )
return( 0 );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
/* j is the number of non-zero limbs of B. Add those to X. */
@ -972,10 +988,12 @@ cleanup:
return( ret );
}
/*
* Signed addition: X = A + B
/* Common function for signed addition and subtraction.
* Calculate A + B * flip_B where flip_B is 1 or -1.
*/
int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
static int add_sub_mpi( mbedtls_mpi *X,
const mbedtls_mpi *A, const mbedtls_mpi *B,
int flip_B )
{
int ret, s;
MPI_VALIDATE_RET( X != NULL );
@ -983,16 +1001,21 @@ int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
MPI_VALIDATE_RET( B != NULL );
s = A->s;
if( A->s * B->s < 0 )
if( A->s * B->s * flip_B < 0 )
{
if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
int cmp = mbedtls_mpi_cmp_abs( A, B );
if( cmp >= 0 )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
X->s = s;
/* If |A| = |B|, the result is 0 and we must set the sign bit
* to +1 regardless of which of A or B was negative. Otherwise,
* since |A| > |B|, the sign is the sign of A. */
X->s = cmp == 0 ? 1 : s;
}
else
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
/* Since |A| < |B|, the sign is the opposite of A. */
X->s = -s;
}
}
@ -1007,39 +1030,20 @@ cleanup:
return( ret );
}
/*
* Signed addition: X = A + B
*/
int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
return( add_sub_mpi( X, A, B, 1 ) );
}
/*
* Signed subtraction: X = A - B
*/
int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
int ret, s;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );
s = A->s;
if( A->s * B->s > 0 )
{
if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
X->s = s;
}
else
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
X->s = -s;
}
}
else
{
MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
X->s = s;
}
cleanup:
return( ret );
return( add_sub_mpi( X, A, B, -1 ) );
}
/*
@ -1052,7 +1056,7 @@ int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
p[0] = ( b < 0 ) ? -b : b;
p[0] = mpi_sint_abs( b );
B.s = ( b < 0 ) ? -1 : 1;
B.n = 1;
B.p = p;
@ -1070,7 +1074,7 @@ int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
p[0] = ( b < 0 ) ? -b : b;
p[0] = mpi_sint_abs( b );
B.s = ( b < 0 ) ? -1 : 1;
B.n = 1;
B.p = p;
@ -1408,7 +1412,7 @@ int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET( A != NULL );
p[0] = ( b < 0 ) ? -b : b;
p[0] = mpi_sint_abs( b );
B.s = ( b < 0 ) ? -1 : 1;
B.n = 1;
B.p = p;

View file

@ -127,7 +127,40 @@ int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
/* END MERGE SLOT 6 */
/* BEGIN MERGE SLOT 7 */
int mbedtls_mpi_mod_raw_to_mont_rep( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m )
{
mbedtls_mpi_uint *T;
const size_t t_limbs = m->limbs * 2 + 1;
if( ( T = (mbedtls_mpi_uint *) mbedtls_calloc( t_limbs, ciL ) ) == NULL )
return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
mbedtls_mpi_core_montmul( X, X, m->rep.mont.rr, m->limbs, m->p, m->limbs,
m->rep.mont.mm, T );
mbedtls_platform_zeroize( T, t_limbs * ciL );
mbedtls_free( T );
return( 0 );
}
int mbedtls_mpi_mod_raw_from_mont_rep( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m )
{
const mbedtls_mpi_uint one = 1;
const size_t t_limbs = m->limbs * 2 + 1;
mbedtls_mpi_uint *T;
if( ( T = (mbedtls_mpi_uint *) mbedtls_calloc( t_limbs, ciL ) ) == NULL )
return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
mbedtls_mpi_core_montmul( X, X, &one, 1, m->p, m->limbs,
m->rep.mont.mm, T );
mbedtls_platform_zeroize( T, t_limbs * ciL );
mbedtls_free( T );
return( 0 );
}
/* END MERGE SLOT 7 */
/* BEGIN MERGE SLOT 8 */

View file

@ -163,7 +163,29 @@ int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
/* END MERGE SLOT 6 */
/* BEGIN MERGE SLOT 7 */
/** Convert an MPI into Montgomery form.
*
* \param X The address of the MPI.
* Must have the same number of limbs as \p m.
* \param m The address of the modulus, which gives the size of
* the base `R` = 2^(biL*m->limbs).
*
* \return \c 0 if successful.
*/
int mbedtls_mpi_mod_raw_to_mont_rep( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m );
/** Convert an MPI back from Montgomery representation.
*
* \param X The address of the MPI.
* Must have the same number of limbs as \p m.
* \param m The address of the modulus, which gives the size of
* the base `R`= 2^(biL*m->limbs).
*
* \return \c 0 if successful.
*/
int mbedtls_mpi_mod_raw_from_mont_rep( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m );
/* END MERGE SLOT 7 */
/* BEGIN MERGE SLOT 8 */

View file

@ -877,20 +877,7 @@ static psa_status_t psa_restrict_key_policy(
return( PSA_SUCCESS );
}
/** Get the description of a key given its identifier and policy constraints
* and lock it.
*
* The key must have allow all the usage flags set in \p usage. If \p alg is
* nonzero, the key must allow operations with this algorithm. If \p alg is
* zero, the algorithm is not checked.
*
* In case of a persistent key, the function loads the description of the key
* into a key slot if not already done.
*
* On success, the returned key slot is locked. It is the responsibility of
* the caller to unlock the key slot when it does not access it anymore.
*/
static psa_status_t psa_get_and_lock_key_slot_with_policy(
psa_status_t psa_get_and_lock_key_slot_with_policy(
mbedtls_svc_key_id_t key,
psa_key_slot_t **p_slot,
psa_key_usage_t usage,

View file

@ -183,6 +183,24 @@ static inline psa_key_slot_number_t psa_key_slot_get_slot_number(
}
#endif
/** Get the description of a key given its identifier and policy constraints
* and lock it.
*
* The key must have allow all the usage flags set in \p usage. If \p alg is
* nonzero, the key must allow operations with this algorithm. If \p alg is
* zero, the algorithm is not checked.
*
* In case of a persistent key, the function loads the description of the key
* into a key slot if not already done.
*
* On success, the returned key slot is locked. It is the responsibility of
* the caller to unlock the key slot when it does not access it anymore.
*/
psa_status_t psa_get_and_lock_key_slot_with_policy( mbedtls_svc_key_id_t key,
psa_key_slot_t **p_slot,
psa_key_usage_t usage,
psa_algorithm_t alg );
/** Completely wipe a slot in memory, including its policy.
*
* Persistent storage is not affected.

View file

@ -248,6 +248,7 @@ psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation,
psa_key_attributes_t attributes = psa_key_attributes_init();
psa_key_type_t type;
psa_key_usage_t usage;
psa_key_slot_t *slot = NULL;
if( operation->alg == PSA_ALG_NONE ||
operation->state != PSA_PAKE_STATE_SETUP )
@ -273,7 +274,27 @@ psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation,
if( ( usage & PSA_KEY_USAGE_DERIVE ) == 0 )
return( PSA_ERROR_NOT_PERMITTED );
operation->password = password;
if( operation->password != NULL )
return( PSA_ERROR_BAD_STATE );
status = psa_get_and_lock_key_slot_with_policy( password, &slot,
PSA_KEY_USAGE_DERIVE,
PSA_ALG_JPAKE );
if( status != PSA_SUCCESS )
return( status );
operation->password = mbedtls_calloc( 1, slot->key.bytes );
if( operation->password == NULL )
{
psa_unlock_key_slot( slot );
return( PSA_ERROR_INSUFFICIENT_MEMORY );
}
memcpy( operation->password, slot->key.data, slot->key.bytes );
operation->password_len = slot->key.bytes;
status = psa_unlock_key_slot( slot );
if( status != PSA_SUCCESS )
return( status );
return( PSA_SUCCESS );
}
@ -348,9 +369,7 @@ psa_status_t psa_pake_set_role( psa_pake_operation_t *operation,
static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_ecjpake_role role;
psa_key_slot_t *slot = NULL;
if( operation->role == PSA_PAKE_ROLE_CLIENT )
role = MBEDTLS_ECJPAKE_CLIENT;
@ -359,22 +378,20 @@ static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation )
else
return( PSA_ERROR_BAD_STATE );
if( psa_is_valid_key_id( operation->password, 1 ) == 0 )
if( operation->password_len == 0 )
return( PSA_ERROR_BAD_STATE );
status = psa_get_and_lock_key_slot( operation->password, &slot );
if( status != PSA_SUCCESS )
return( status );
ret = mbedtls_ecjpake_setup( &operation->ctx.ecjpake,
role,
MBEDTLS_MD_SHA256,
MBEDTLS_ECP_DP_SECP256R1,
slot->key.data, slot->key.bytes );
operation->password,
operation->password_len );
psa_unlock_key_slot( slot );
slot = NULL;
mbedtls_platform_zeroize( operation->password, operation->password_len );
mbedtls_free( operation->password );
operation->password = NULL;
operation->password_len = 0;
if( ret != 0 )
return( mbedtls_ecjpake_to_psa_error( ret ) );
@ -840,7 +857,11 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation)
{
operation->input_step = PSA_PAKE_STEP_INVALID;
operation->output_step = PSA_PAKE_STEP_INVALID;
operation->password = MBEDTLS_SVC_KEY_ID_INIT;
if( operation->password_len > 0 )
mbedtls_platform_zeroize( operation->password, operation->password_len );
mbedtls_free( operation->password );
operation->password = NULL;
operation->password_len = 0;
operation->role = PSA_PAKE_ROLE_NONE;
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
operation->buffer_length = 0;

View file

@ -106,6 +106,9 @@ static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
*olen = hostname_len + 9;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_SERVERNAME );
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
return( 0 );
}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
@ -177,6 +180,9 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
/* Extension length = *out_len - 2 (ext_type) - 2 (ext_len) */
MBEDTLS_PUT_UINT16_BE( *out_len - 4, buf, 2 );
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_ALPN );
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
return( 0 );
}
#endif /* MBEDTLS_SSL_ALPN */
@ -296,7 +302,8 @@ static int ssl_write_supported_groups_ext( mbedtls_ssl_context *ssl,
*out_len = p - buf;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_GROUPS;
mbedtls_ssl_tls13_set_hs_sent_ext_mask(
ssl, MBEDTLS_TLS_EXT_SUPPORTED_GROUPS );
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
return( 0 );
@ -557,7 +564,7 @@ static int ssl_write_client_hello_body( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
/* Keeping track of the included extensions */
handshake->extensions_present = MBEDTLS_SSL_EXT_NONE;
handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
#endif
/* First write extensions, then the total length */
@ -667,6 +674,11 @@ static int ssl_write_client_hello_body( mbedtls_ssl_context *ssl,
p_extensions_len, extensions_len );
}
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
MBEDTLS_SSL_PRINT_EXTS(
3, MBEDTLS_SSL_HS_CLIENT_HELLO, handshake->sent_extensions );
#endif
*out_len = p - buf;
return( 0 );
}

View file

@ -43,6 +43,32 @@ const char *mbedtls_ssl_sig_alg_to_str( uint16_t in );
const char *mbedtls_ssl_named_group_to_str( uint16_t in );
const char *mbedtls_ssl_get_extension_name( unsigned int extension_type );
void mbedtls_ssl_print_extensions( const mbedtls_ssl_context *ssl,
int level, const char *file, int line,
int hs_msg_type, uint32_t extensions_mask,
const char *extra );
void mbedtls_ssl_print_extension( const mbedtls_ssl_context *ssl,
int level, const char *file, int line,
int hs_msg_type, unsigned int extension_type,
const char *extra_msg0, const char *extra_msg1 );
#define MBEDTLS_SSL_PRINT_EXTS( level, hs_msg_type, extensions_mask ) \
mbedtls_ssl_print_extensions( ssl, level, __FILE__, __LINE__, \
hs_msg_type, extensions_mask, NULL )
#define MBEDTLS_SSL_PRINT_EXT( level, hs_msg_type, extension_type, extra ) \
mbedtls_ssl_print_extension( ssl, level, __FILE__, __LINE__, \
hs_msg_type, extension_type, \
extra, NULL )
#else
#define MBEDTLS_SSL_PRINT_EXTS( level, hs_msg_type, extension_mask )
#define MBEDTLS_SSL_PRINT_EXT( level, hs_msg_type, extension_type, extra )
#endif /* MBEDTLS_DEBUG_C */
#endif /* SSL_DEBUG_HELPERS_H */
#endif /* MBEDTLS_SSL_DEBUG_HELPERS_H */

View file

@ -74,34 +74,147 @@
#define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */
#define MBEDTLS_SSL_RENEGOTIATION_PENDING 3 /* Requested (server only) */
/*
* Mask of TLS 1.3 handshake extensions used in extensions_present
* of mbedtls_ssl_handshake_params.
*/
#define MBEDTLS_SSL_EXT_NONE 0
/* Faked handshake message identity for HelloRetryRequest. */
#define MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST ( -MBEDTLS_SSL_HS_SERVER_HELLO )
#define MBEDTLS_SSL_EXT_SERVERNAME ( 1 << 0 )
#define MBEDTLS_SSL_EXT_MAX_FRAGMENT_LENGTH ( 1 << 1 )
#define MBEDTLS_SSL_EXT_STATUS_REQUEST ( 1 << 2 )
#define MBEDTLS_SSL_EXT_SUPPORTED_GROUPS ( 1 << 3 )
#define MBEDTLS_SSL_EXT_SIG_ALG ( 1 << 4 )
#define MBEDTLS_SSL_EXT_USE_SRTP ( 1 << 5 )
#define MBEDTLS_SSL_EXT_HEARTBEAT ( 1 << 6 )
#define MBEDTLS_SSL_EXT_ALPN ( 1 << 7 )
#define MBEDTLS_SSL_EXT_SCT ( 1 << 8 )
#define MBEDTLS_SSL_EXT_CLI_CERT_TYPE ( 1 << 9 )
#define MBEDTLS_SSL_EXT_SERV_CERT_TYPE ( 1 << 10 )
#define MBEDTLS_SSL_EXT_PADDING ( 1 << 11 )
#define MBEDTLS_SSL_EXT_PRE_SHARED_KEY ( 1 << 12 )
#define MBEDTLS_SSL_EXT_EARLY_DATA ( 1 << 13 )
#define MBEDTLS_SSL_EXT_SUPPORTED_VERSIONS ( 1 << 14 )
#define MBEDTLS_SSL_EXT_COOKIE ( 1 << 15 )
#define MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ( 1 << 16 )
#define MBEDTLS_SSL_EXT_CERT_AUTH ( 1 << 17 )
#define MBEDTLS_SSL_EXT_OID_FILTERS ( 1 << 18 )
#define MBEDTLS_SSL_EXT_POST_HANDSHAKE_AUTH ( 1 << 19 )
#define MBEDTLS_SSL_EXT_SIG_ALG_CERT ( 1 << 20 )
#define MBEDTLS_SSL_EXT_KEY_SHARE ( 1 << 21 )
/*
* Internal identity of handshake extensions
*/
#define MBEDTLS_SSL_EXT_ID_UNRECOGNIZED 0
#define MBEDTLS_SSL_EXT_ID_SERVERNAME 1
#define MBEDTLS_SSL_EXT_ID_SERVERNAME_HOSTNAME 1
#define MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH 2
#define MBEDTLS_SSL_EXT_ID_STATUS_REQUEST 3
#define MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS 4
#define MBEDTLS_SSL_EXT_ID_SUPPORTED_ELLIPTIC_CURVES 4
#define MBEDTLS_SSL_EXT_ID_SIG_ALG 5
#define MBEDTLS_SSL_EXT_ID_USE_SRTP 6
#define MBEDTLS_SSL_EXT_ID_HEARTBEAT 7
#define MBEDTLS_SSL_EXT_ID_ALPN 8
#define MBEDTLS_SSL_EXT_ID_SCT 9
#define MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE 10
#define MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE 11
#define MBEDTLS_SSL_EXT_ID_PADDING 12
#define MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY 13
#define MBEDTLS_SSL_EXT_ID_EARLY_DATA 14
#define MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS 15
#define MBEDTLS_SSL_EXT_ID_COOKIE 16
#define MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES 17
#define MBEDTLS_SSL_EXT_ID_CERT_AUTH 18
#define MBEDTLS_SSL_EXT_ID_OID_FILTERS 19
#define MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH 20
#define MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT 21
#define MBEDTLS_SSL_EXT_ID_KEY_SHARE 22
#define MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC 23
#define MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS 24
#define MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC 25
#define MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET 26
#define MBEDTLS_SSL_EXT_ID_SESSION_TICKET 27
/* Utility for translating IANA extension type. */
uint32_t mbedtls_ssl_get_extension_id( unsigned int extension_type );
uint32_t mbedtls_ssl_get_extension_mask( unsigned int extension_type );
/* Macros used to define mask constants */
#define MBEDTLS_SSL_EXT_MASK( id ) ( 1ULL << ( MBEDTLS_SSL_EXT_ID_##id ) )
/* Reset value of extension mask */
#define MBEDTLS_SSL_EXT_MASK_NONE 0
/* In messages containing extension requests, we should ignore unrecognized
* extensions. In messages containing extension responses, unrecognized
* extensions should result in handshake abortion. Messages containing
* extension requests include ClientHello, CertificateRequest and
* NewSessionTicket. Messages containing extension responses include
* ServerHello, HelloRetryRequest, EncryptedExtensions and Certificate.
*
* RFC 8446 section 4.1.3
*
* The ServerHello MUST only include extensions which are required to establish
* the cryptographic context and negotiate the protocol version.
*
* RFC 8446 section 4.2
*
* If an implementation receives an extension which it recognizes and which is
* not specified for the message in which it appears, it MUST abort the handshake
* with an "illegal_parameter" alert.
*/
/* Extensions that are not recognized by TLS 1.3 */
#define MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED \
( MBEDTLS_SSL_EXT_MASK( SUPPORTED_POINT_FORMATS ) | \
MBEDTLS_SSL_EXT_MASK( ENCRYPT_THEN_MAC ) | \
MBEDTLS_SSL_EXT_MASK( EXTENDED_MASTER_SECRET ) | \
MBEDTLS_SSL_EXT_MASK( SESSION_TICKET ) | \
MBEDTLS_SSL_EXT_MASK( TRUNCATED_HMAC ) | \
MBEDTLS_SSL_EXT_MASK( UNRECOGNIZED ) )
/* RFC 8446 section 4.2. Allowed extensions for ClienHello */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH \
( MBEDTLS_SSL_EXT_MASK( SERVERNAME ) | \
MBEDTLS_SSL_EXT_MASK( MAX_FRAGMENT_LENGTH ) | \
MBEDTLS_SSL_EXT_MASK( STATUS_REQUEST ) | \
MBEDTLS_SSL_EXT_MASK( SUPPORTED_GROUPS ) | \
MBEDTLS_SSL_EXT_MASK( SIG_ALG ) | \
MBEDTLS_SSL_EXT_MASK( USE_SRTP ) | \
MBEDTLS_SSL_EXT_MASK( HEARTBEAT ) | \
MBEDTLS_SSL_EXT_MASK( ALPN ) | \
MBEDTLS_SSL_EXT_MASK( SCT ) | \
MBEDTLS_SSL_EXT_MASK( CLI_CERT_TYPE ) | \
MBEDTLS_SSL_EXT_MASK( SERV_CERT_TYPE ) | \
MBEDTLS_SSL_EXT_MASK( PADDING ) | \
MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) | \
MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) | \
MBEDTLS_SSL_EXT_MASK( PSK_KEY_EXCHANGE_MODES ) | \
MBEDTLS_SSL_EXT_MASK( EARLY_DATA ) | \
MBEDTLS_SSL_EXT_MASK( COOKIE ) | \
MBEDTLS_SSL_EXT_MASK( SUPPORTED_VERSIONS ) | \
MBEDTLS_SSL_EXT_MASK( CERT_AUTH ) | \
MBEDTLS_SSL_EXT_MASK( POST_HANDSHAKE_AUTH ) | \
MBEDTLS_SSL_EXT_MASK( SIG_ALG_CERT ) | \
MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED )
/* RFC 8446 section 4.2. Allowed extensions for EncryptedExtensions */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_EE \
( MBEDTLS_SSL_EXT_MASK( SERVERNAME ) | \
MBEDTLS_SSL_EXT_MASK( MAX_FRAGMENT_LENGTH ) | \
MBEDTLS_SSL_EXT_MASK( SUPPORTED_GROUPS ) | \
MBEDTLS_SSL_EXT_MASK( USE_SRTP ) | \
MBEDTLS_SSL_EXT_MASK( HEARTBEAT ) | \
MBEDTLS_SSL_EXT_MASK( ALPN ) | \
MBEDTLS_SSL_EXT_MASK( CLI_CERT_TYPE ) | \
MBEDTLS_SSL_EXT_MASK( SERV_CERT_TYPE ) | \
MBEDTLS_SSL_EXT_MASK( EARLY_DATA ) )
/* RFC 8446 section 4.2. Allowed extensions for CertificateRequest */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CR \
( MBEDTLS_SSL_EXT_MASK( STATUS_REQUEST ) | \
MBEDTLS_SSL_EXT_MASK( SIG_ALG ) | \
MBEDTLS_SSL_EXT_MASK( SCT ) | \
MBEDTLS_SSL_EXT_MASK( CERT_AUTH ) | \
MBEDTLS_SSL_EXT_MASK( OID_FILTERS ) | \
MBEDTLS_SSL_EXT_MASK( SIG_ALG_CERT ) | \
MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED )
/* RFC 8446 section 4.2. Allowed extensions for Certificate */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CT \
( MBEDTLS_SSL_EXT_MASK( STATUS_REQUEST ) | \
MBEDTLS_SSL_EXT_MASK( SCT ) )
/* RFC 8446 section 4.2. Allowed extensions for ServerHello */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_SH \
( MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) | \
MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) | \
MBEDTLS_SSL_EXT_MASK( SUPPORTED_VERSIONS ) )
/* RFC 8446 section 4.2. Allowed extensions for HelloRetryRequest */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_HRR \
( MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) | \
MBEDTLS_SSL_EXT_MASK( COOKIE ) | \
MBEDTLS_SSL_EXT_MASK( SUPPORTED_VERSIONS ) )
/* RFC 8446 section 4.2. Allowed extensions for NewSessionTicket */
#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_NST \
( MBEDTLS_SSL_EXT_MASK( EARLY_DATA ) | \
MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED )
/*
* Helper macros for function call with return check.
@ -858,9 +971,8 @@ struct mbedtls_ssl_handshake_params
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
int extensions_present; /*!< extension presence; Each bitfield
represents an extension and defined
as \c MBEDTLS_SSL_EXT_XXX */
uint32_t sent_extensions; /*!< extensions sent by endpoint */
uint32_t received_extensions; /*!< extensions received by endpoint */
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
unsigned char certificate_request_context_len;
@ -1838,6 +1950,24 @@ static inline int mbedtls_ssl_tls13_some_psk_enabled( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_SRV_C &&
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
/*
* Helper functions for extensions checking.
*/
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_tls13_check_received_extension(
mbedtls_ssl_context *ssl,
int hs_msg_type,
unsigned int received_extension_type,
uint32_t hs_msg_allowed_extensions_mask );
static inline void mbedtls_ssl_tls13_set_hs_sent_ext_mask(
mbedtls_ssl_context *ssl, unsigned int extension_type )
{
ssl->handshake->sent_extensions |=
mbedtls_ssl_get_extension_mask( extension_type );
}
/*
* Helper functions to check the selected key exchange mode.
*/
@ -1916,6 +2046,12 @@ int mbedtls_ssl_tls13_generate_and_write_ecdh_key_exchange(
size_t *out_len );
#endif /* MBEDTLS_ECDH_C */
#if defined(MBEDTLS_SSL_EARLY_DATA)
int mbedtls_ssl_tls13_write_early_data_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *out_len );
#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

View file

@ -521,6 +521,245 @@ static void ssl_clear_peer_cert( mbedtls_ssl_session *session )
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
uint32_t mbedtls_ssl_get_extension_id( unsigned int extension_type )
{
switch( extension_type )
{
case MBEDTLS_TLS_EXT_SERVERNAME:
return( MBEDTLS_SSL_EXT_ID_SERVERNAME );
case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
return( MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH );
case MBEDTLS_TLS_EXT_STATUS_REQUEST:
return( MBEDTLS_SSL_EXT_ID_STATUS_REQUEST );
case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS:
return( MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS );
case MBEDTLS_TLS_EXT_SIG_ALG:
return( MBEDTLS_SSL_EXT_ID_SIG_ALG );
case MBEDTLS_TLS_EXT_USE_SRTP:
return( MBEDTLS_SSL_EXT_ID_USE_SRTP );
case MBEDTLS_TLS_EXT_HEARTBEAT:
return( MBEDTLS_SSL_EXT_ID_HEARTBEAT );
case MBEDTLS_TLS_EXT_ALPN:
return( MBEDTLS_SSL_EXT_ID_ALPN );
case MBEDTLS_TLS_EXT_SCT:
return( MBEDTLS_SSL_EXT_ID_SCT );
case MBEDTLS_TLS_EXT_CLI_CERT_TYPE:
return( MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE );
case MBEDTLS_TLS_EXT_SERV_CERT_TYPE:
return( MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE );
case MBEDTLS_TLS_EXT_PADDING:
return( MBEDTLS_SSL_EXT_ID_PADDING );
case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
return( MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY );
case MBEDTLS_TLS_EXT_EARLY_DATA:
return( MBEDTLS_SSL_EXT_ID_EARLY_DATA );
case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS:
return( MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS );
case MBEDTLS_TLS_EXT_COOKIE:
return( MBEDTLS_SSL_EXT_ID_COOKIE );
case MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES:
return( MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES );
case MBEDTLS_TLS_EXT_CERT_AUTH:
return( MBEDTLS_SSL_EXT_ID_CERT_AUTH );
case MBEDTLS_TLS_EXT_OID_FILTERS:
return( MBEDTLS_SSL_EXT_ID_OID_FILTERS );
case MBEDTLS_TLS_EXT_POST_HANDSHAKE_AUTH:
return( MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH );
case MBEDTLS_TLS_EXT_SIG_ALG_CERT:
return( MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT );
case MBEDTLS_TLS_EXT_KEY_SHARE:
return( MBEDTLS_SSL_EXT_ID_KEY_SHARE );
case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
return( MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC );
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
return( MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS );
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
return( MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC );
case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
return( MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET );
case MBEDTLS_TLS_EXT_SESSION_TICKET:
return( MBEDTLS_SSL_EXT_ID_SESSION_TICKET );
}
return( MBEDTLS_SSL_EXT_ID_UNRECOGNIZED );
}
uint32_t mbedtls_ssl_get_extension_mask( unsigned int extension_type )
{
return( 1 << mbedtls_ssl_get_extension_id( extension_type ) );
}
#if defined(MBEDTLS_DEBUG_C)
static const char *extension_name_table[] = {
[MBEDTLS_SSL_EXT_ID_UNRECOGNIZED] = "unrecognized",
[MBEDTLS_SSL_EXT_ID_SERVERNAME] = "server_name",
[MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH] = "max_fragment_length",
[MBEDTLS_SSL_EXT_ID_STATUS_REQUEST] = "status_request",
[MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS] = "supported_groups",
[MBEDTLS_SSL_EXT_ID_SIG_ALG] = "signature_algorithms",
[MBEDTLS_SSL_EXT_ID_USE_SRTP] = "use_srtp",
[MBEDTLS_SSL_EXT_ID_HEARTBEAT] = "heartbeat",
[MBEDTLS_SSL_EXT_ID_ALPN] = "application_layer_protocol_negotiation",
[MBEDTLS_SSL_EXT_ID_SCT] = "signed_certificate_timestamp",
[MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE] = "client_certificate_type",
[MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE] = "server_certificate_type",
[MBEDTLS_SSL_EXT_ID_PADDING] = "padding",
[MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY] = "pre_shared_key",
[MBEDTLS_SSL_EXT_ID_EARLY_DATA] = "early_data",
[MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS] = "supported_versions",
[MBEDTLS_SSL_EXT_ID_COOKIE] = "cookie",
[MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES] = "psk_key_exchange_modes",
[MBEDTLS_SSL_EXT_ID_CERT_AUTH] = "certificate_authorities",
[MBEDTLS_SSL_EXT_ID_OID_FILTERS] = "oid_filters",
[MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH] = "post_handshake_auth",
[MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT] = "signature_algorithms_cert",
[MBEDTLS_SSL_EXT_ID_KEY_SHARE] = "key_share",
[MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC] = "truncated_hmac",
[MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS] = "supported_point_formats",
[MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC] = "encrypt_then_mac",
[MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET] = "extended_master_secret",
[MBEDTLS_SSL_EXT_ID_SESSION_TICKET] = "session_ticket"
};
static unsigned int extension_type_table[]={
[MBEDTLS_SSL_EXT_ID_UNRECOGNIZED] = 0xff,
[MBEDTLS_SSL_EXT_ID_SERVERNAME] = MBEDTLS_TLS_EXT_SERVERNAME,
[MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH] = MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH,
[MBEDTLS_SSL_EXT_ID_STATUS_REQUEST] = MBEDTLS_TLS_EXT_STATUS_REQUEST,
[MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS] = MBEDTLS_TLS_EXT_SUPPORTED_GROUPS,
[MBEDTLS_SSL_EXT_ID_SIG_ALG] = MBEDTLS_TLS_EXT_SIG_ALG,
[MBEDTLS_SSL_EXT_ID_USE_SRTP] = MBEDTLS_TLS_EXT_USE_SRTP,
[MBEDTLS_SSL_EXT_ID_HEARTBEAT] = MBEDTLS_TLS_EXT_HEARTBEAT,
[MBEDTLS_SSL_EXT_ID_ALPN] = MBEDTLS_TLS_EXT_ALPN,
[MBEDTLS_SSL_EXT_ID_SCT] = MBEDTLS_TLS_EXT_SCT,
[MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE] = MBEDTLS_TLS_EXT_CLI_CERT_TYPE,
[MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE] = MBEDTLS_TLS_EXT_SERV_CERT_TYPE,
[MBEDTLS_SSL_EXT_ID_PADDING] = MBEDTLS_TLS_EXT_PADDING,
[MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY] = MBEDTLS_TLS_EXT_PRE_SHARED_KEY,
[MBEDTLS_SSL_EXT_ID_EARLY_DATA] = MBEDTLS_TLS_EXT_EARLY_DATA,
[MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS] = MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS,
[MBEDTLS_SSL_EXT_ID_COOKIE] = MBEDTLS_TLS_EXT_COOKIE,
[MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES] = MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES,
[MBEDTLS_SSL_EXT_ID_CERT_AUTH] = MBEDTLS_TLS_EXT_CERT_AUTH,
[MBEDTLS_SSL_EXT_ID_OID_FILTERS] = MBEDTLS_TLS_EXT_OID_FILTERS,
[MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH] = MBEDTLS_TLS_EXT_POST_HANDSHAKE_AUTH,
[MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT] = MBEDTLS_TLS_EXT_SIG_ALG_CERT,
[MBEDTLS_SSL_EXT_ID_KEY_SHARE] = MBEDTLS_TLS_EXT_KEY_SHARE,
[MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC] = MBEDTLS_TLS_EXT_TRUNCATED_HMAC,
[MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS] = MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS,
[MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC] = MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC,
[MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET] = MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET,
[MBEDTLS_SSL_EXT_ID_SESSION_TICKET] = MBEDTLS_TLS_EXT_SESSION_TICKET
};
const char *mbedtls_ssl_get_extension_name( unsigned int extension_type )
{
return( extension_name_table[
mbedtls_ssl_get_extension_id( extension_type ) ] );
}
static const char *ssl_tls13_get_hs_msg_name( int hs_msg_type )
{
switch( hs_msg_type )
{
case MBEDTLS_SSL_HS_CLIENT_HELLO:
return( "ClientHello" );
case MBEDTLS_SSL_HS_SERVER_HELLO:
return( "ServerHello" );
case MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST:
return( "HelloRetryRequest" );
case MBEDTLS_SSL_HS_NEW_SESSION_TICKET:
return( "NewSessionTicket" );
case MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS:
return( "EncryptedExtensions" );
case MBEDTLS_SSL_HS_CERTIFICATE:
return( "Certificate" );
case MBEDTLS_SSL_HS_CERTIFICATE_REQUEST:
return( "CertificateRequest" );
}
return( "Unknown" );
}
void mbedtls_ssl_print_extension( const mbedtls_ssl_context *ssl,
int level, const char *file, int line,
int hs_msg_type, unsigned int extension_type,
const char *extra_msg0, const char *extra_msg1 )
{
const char *extra_msg;
if( extra_msg0 && extra_msg1 )
{
mbedtls_debug_print_msg(
ssl, level, file, line,
"%s: %s(%u) extension %s %s.",
ssl_tls13_get_hs_msg_name( hs_msg_type ),
mbedtls_ssl_get_extension_name( extension_type ),
extension_type,
extra_msg0, extra_msg1 );
return;
}
extra_msg = extra_msg0 ? extra_msg0 : extra_msg1;
if( extra_msg )
{
mbedtls_debug_print_msg(
ssl, level, file, line,
"%s: %s(%u) extension %s.", ssl_tls13_get_hs_msg_name( hs_msg_type ),
mbedtls_ssl_get_extension_name( extension_type ), extension_type,
extra_msg );
return;
}
mbedtls_debug_print_msg(
ssl, level, file, line,
"%s: %s(%u) extension.", ssl_tls13_get_hs_msg_name( hs_msg_type ),
mbedtls_ssl_get_extension_name( extension_type ), extension_type );
}
void mbedtls_ssl_print_extensions( const mbedtls_ssl_context *ssl,
int level, const char *file, int line,
int hs_msg_type, uint32_t extensions_mask,
const char *extra )
{
for( unsigned i = 0;
i < sizeof( extension_name_table ) / sizeof( extension_name_table[0] );
i++ )
{
mbedtls_ssl_print_extension(
ssl, level, file, line, hs_msg_type, extension_type_table[i],
extensions_mask & ( 1 << i ) ? "exists" : "does not exist", extra );
}
}
#endif /* MBEDTLS_DEBUG_C */
void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
const mbedtls_ssl_ciphersuite_t *ciphersuite_info )
{
@ -8744,8 +8983,9 @@ int mbedtls_ssl_write_sig_alg_ext( mbedtls_ssl_context *ssl, unsigned char *buf,
*out_len = p - buf;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SIG_ALG;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_SIG_ALG );
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
return( 0 );
}
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
@ -8944,6 +9184,11 @@ int mbedtls_ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
p[6] = MBEDTLS_BYTE_0( protocol_name_len );
memcpy( p + 7, ssl->alpn_chosen, protocol_name_len );
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_ALPN );
#endif
return ( 0 );
}
#endif /* MBEDTLS_SSL_ALPN */

View file

@ -2654,7 +2654,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
for( size_t i = 0; i < sig_alg_len; i += 2 )
{
MBEDTLS_SSL_DEBUG_MSG( 3,
( "Supported Signature Algorithm found: %d,%d",
( "Supported Signature Algorithm found: %02x %02x",
sig_alg[i], sig_alg[i + 1] ) );
}
#endif

View file

@ -2531,10 +2531,15 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
if( ! mbedtls_ssl_sig_alg_is_supported( ssl, *sig_alg ) )
continue;
MBEDTLS_PUT_UINT16_BE( *sig_alg, p, sa_len );
/* Write elements at offsets starting from 1 (offset 0 is for the
* length). Thus the offset of each element is the length of the
* partial list including that element. */
sa_len += 2;
MBEDTLS_PUT_UINT16_BE( *sig_alg, p, sa_len );
}
/* Fill in list length. */
MBEDTLS_PUT_UINT16_BE( sa_len, p, 0 );
sa_len += 2;
p += sa_len;

View file

@ -32,6 +32,7 @@
#include "ssl_misc.h"
#include "ssl_client.h"
#include "ssl_tls13_keys.h"
#include "ssl_debug_helpers.h"
/* Write extensions */
@ -89,6 +90,9 @@ static int ssl_tls13_write_supported_versions_ext( mbedtls_ssl_context *ssl,
*out_len = 5 + versions_len;
mbedtls_ssl_tls13_set_hs_sent_ext_mask(
ssl, MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS );
return( 0 );
}
@ -359,7 +363,7 @@ static int ssl_tls13_write_key_share_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, key_share extension", buf, *out_len );
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_KEY_SHARE;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_KEY_SHARE );
cleanup:
@ -512,7 +516,6 @@ static int ssl_tls13_parse_key_share_ext( mbedtls_ssl_context *ssl,
else
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_KEY_SHARE;
return( ret );
}
@ -600,6 +603,8 @@ static int ssl_tls13_write_cookie_ext( mbedtls_ssl_context *ssl,
*out_len = handshake->hrr_cookie_len + 6;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_COOKIE );
return( 0 );
}
@ -669,7 +674,10 @@ static int ssl_tls13_write_psk_key_exchange_modes_ext( mbedtls_ssl_context *ssl,
buf[4] = ke_modes_len;
*out_len = p - buf;
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES;
mbedtls_ssl_tls13_set_hs_sent_ext_mask(
ssl, MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES );
return ( 0 );
}
@ -692,6 +700,19 @@ static int ssl_tls13_has_configured_ticket( mbedtls_ssl_context *ssl )
session != NULL && session->ticket != NULL );
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
static int ssl_tls13_early_data_has_valid_ticket( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_session *session = ssl->session_negotiate;
return( ssl->handshake->resume &&
session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
( session->ticket_flags &
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA ) &&
mbedtls_ssl_tls13_cipher_suite_is_offered(
ssl, session->ciphersuite ) );
}
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_ticket_get_identity( mbedtls_ssl_context *ssl,
psa_algorithm_t *hash_alg,
@ -981,8 +1002,6 @@ int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
MBEDTLS_SSL_DEBUG_BUF( 3, "pre_shared_key identities", buf, p - buf );
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
return( 0 );
}
@ -1037,6 +1056,9 @@ int mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(
MBEDTLS_SSL_DEBUG_BUF( 3, "pre_shared_key binders", buf, p - buf );
mbedtls_ssl_tls13_set_hs_sent_ext_mask(
ssl, MBEDTLS_TLS_EXT_PRE_SHARED_KEY );
return( 0 );
}
@ -1109,8 +1131,6 @@ static int ssl_tls13_parse_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
return( 0 );
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
@ -1153,6 +1173,29 @@ int mbedtls_ssl_tls13_write_client_hello_exts( mbedtls_ssl_context *ssl,
}
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA)
if( mbedtls_ssl_conf_tls13_some_psk_enabled( ssl ) &&
ssl_tls13_early_data_has_valid_ticket( ssl ) &&
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED )
{
ret = mbedtls_ssl_tls13_write_early_data_ext( ssl, p, end, &ext_len );
if( ret != 0 )
return( ret );
p += ext_len;
/* Initializes the status to `indication sent`. It will be updated to
* `accepted` or `rejected` depending on whether the EncryptedExtension
* message will contain an early data indication extension or not.
*/
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_INDICATION_SENT;
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write early_data extension" ) );
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
/* For PSK-based key exchange we need the pre_shared_key extension
* and the psk_key_exchange_modes extension.
@ -1388,7 +1431,7 @@ static int ssl_tls13_preprocess_server_hello( mbedtls_ssl_context *ssl,
ssl->session_negotiate->tls_version = ssl->tls_version;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
handshake->extensions_present = MBEDTLS_SSL_EXT_NONE;
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
ret = ssl_server_hello_is_hrr( ssl, buf, end );
switch( ret )
@ -1498,6 +1541,9 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
uint16_t cipher_suite;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
int fatal_alert = 0;
uint32_t allowed_extensions_mask;
int hs_msg_type = is_hrr ? MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST :
MBEDTLS_SSL_HS_SERVER_HELLO;
/*
* Check there is space for minimal fields
@ -1640,6 +1686,11 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello extensions", p, extensions_len );
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
allowed_extensions_mask = is_hrr ?
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_HRR :
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_SH;
while( p < extensions_end )
{
unsigned int extension_type;
@ -1654,16 +1705,15 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
extension_data_end = p + extension_data_len;
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, hs_msg_type, extension_type, allowed_extensions_mask );
if( ret != 0 )
return( ret );
switch( extension_type )
{
case MBEDTLS_TLS_EXT_COOKIE:
if( !is_hrr )
{
fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
goto cleanup;
}
ret = ssl_tls13_parse_cookie_ext( ssl,
p, extension_data_end );
if( ret != 0 )
@ -1686,11 +1736,6 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found pre_shared_key extension" ) );
if( is_hrr )
{
fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
goto cleanup;
}
if( ( ret = ssl_tls13_parse_server_pre_shared_key_ext(
ssl, p, extension_data_end ) ) != 0 )
@ -1726,18 +1771,15 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
break;
default:
MBEDTLS_SSL_DEBUG_MSG(
3,
( "unknown extension found: %u ( ignoring )",
extension_type ) );
fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto cleanup;
}
p += extension_data_len;
}
MBEDTLS_SSL_PRINT_EXTS( 3, hs_msg_type, handshake->received_extensions );
cleanup:
if( fatal_alert == MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT )
@ -1786,21 +1828,21 @@ static int ssl_tls13_postprocess_server_hello( mbedtls_ssl_context *ssl )
* 3) If only the key_share extension was received then the key
* exchange mode is EPHEMERAL-only.
*/
switch( handshake->extensions_present &
( MBEDTLS_SSL_EXT_PRE_SHARED_KEY | MBEDTLS_SSL_EXT_KEY_SHARE ) )
switch( handshake->received_extensions &
( MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) | MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) ) )
{
/* Only the pre_shared_key extension was received */
case MBEDTLS_SSL_EXT_PRE_SHARED_KEY:
case MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ):
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
break;
/* Only the key_share extension was received */
case MBEDTLS_SSL_EXT_KEY_SHARE:
case MBEDTLS_SSL_EXT_MASK( KEY_SHARE ):
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
break;
/* Both the pre_shared_key and key_share extensions were received */
case ( MBEDTLS_SSL_EXT_PRE_SHARED_KEY | MBEDTLS_SSL_EXT_KEY_SHARE ):
case ( MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) | MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) ):
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
break;
@ -1969,6 +2011,7 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl,
size_t extensions_len;
const unsigned char *p = buf;
const unsigned char *extensions_end;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
extensions_len = MBEDTLS_GET_UINT16_BE( p, 0 );
@ -1978,6 +2021,8 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, extensions_len );
extensions_end = p + extensions_len;
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
while( p < extensions_end )
{
unsigned int extension_type;
@ -1996,22 +2041,14 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
/* The client MUST check EncryptedExtensions for the
* presence of any forbidden extensions and if any are found MUST abort
* the handshake with an "unsupported_extension" alert.
*/
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_EE );
if( ret != 0 )
return( ret );
switch( extension_type )
{
case MBEDTLS_TLS_EXT_SERVERNAME:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found server_name extension" ) );
/* The server_name extension should be an empty extension */
break;
case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extensions supported groups" ) );
break;
#if defined(MBEDTLS_SSL_ALPN)
case MBEDTLS_TLS_EXT_ALPN:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
@ -2024,17 +2061,18 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl,
break;
#endif /* MBEDTLS_SSL_ALPN */
default:
MBEDTLS_SSL_DEBUG_MSG(
3, ( "unsupported extension found: %u ", extension_type) );
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
return ( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
MBEDTLS_SSL_PRINT_EXT(
3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
extension_type, "( ignored )" );
break;
}
p += extension_data_len;
}
MBEDTLS_SSL_PRINT_EXTS( 3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
handshake->received_extensions );
/* Check that we consumed all the message. */
if( p != end )
{
@ -2140,7 +2178,7 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
size_t certificate_request_context_len = 0;
size_t extensions_len = 0;
const unsigned char *extensions_end;
unsigned char sig_alg_ext_found = 0;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
/* ...
* opaque certificate_request_context<0..2^8-1>
@ -2156,7 +2194,6 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "Certificate Request Context",
p, certificate_request_context_len );
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
handshake->certificate_request_context =
mbedtls_calloc( 1, certificate_request_context_len );
if( handshake->certificate_request_context == NULL )
@ -2180,6 +2217,8 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, extensions_len );
extensions_end = p + extensions_len;
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
while( p < extensions_end )
{
unsigned int extension_type;
@ -2192,6 +2231,12 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CR );
if( ret != 0 )
return( ret );
switch( extension_type )
{
case MBEDTLS_TLS_EXT_SIG_ALG:
@ -2201,25 +2246,22 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
p + extension_data_len );
if( ret != 0 )
return( ret );
if( ! sig_alg_ext_found )
sig_alg_ext_found = 1;
else
{
MBEDTLS_SSL_DEBUG_MSG( 3,
( "Duplicate signature algorithms extensions found" ) );
goto decode_error;
}
break;
default:
MBEDTLS_SSL_DEBUG_MSG(
3,
( "unknown extension found: %u ( ignoring )",
extension_type ) );
MBEDTLS_SSL_PRINT_EXT(
3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
extension_type, "( ignored )" );
break;
}
p += extension_data_len;
}
MBEDTLS_SSL_PRINT_EXTS( 3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
handshake->received_extensions );
/* Check that we consumed all the message. */
if( p != end )
{
@ -2227,8 +2269,12 @@ static int ssl_tls13_parse_certificate_request( mbedtls_ssl_context *ssl,
( "CertificateRequest misaligned" ) );
goto decode_error;
}
/* Check that we found signature algorithms extension */
if( ! sig_alg_ext_found )
/* RFC 8446 section 4.3.2
*
* The "signature_algorithms" extension MUST be specified
*/
if( ( handshake->received_extensions & MBEDTLS_SSL_EXT_MASK( SIG_ALG ) ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3,
( "no signature algorithms extension found" ) );
@ -2468,14 +2514,17 @@ static int ssl_tls13_parse_new_session_ticket_exts( mbedtls_ssl_context *ssl,
const unsigned char *buf,
const unsigned char *end )
{
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
const unsigned char *p = buf;
((void) ssl);
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
while( p < end )
{
unsigned int extension_type;
size_t extension_data_len;
int ret;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 4 );
extension_type = MBEDTLS_GET_UINT16_BE( p, 0 );
@ -2484,18 +2533,44 @@ static int ssl_tls13_parse_new_session_ticket_exts( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, extension_data_len );
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_NST );
if( ret != 0 )
return( ret );
switch( extension_type )
{
#if defined(MBEDTLS_SSL_EARLY_DATA)
case MBEDTLS_TLS_EXT_EARLY_DATA:
MBEDTLS_SSL_DEBUG_MSG( 4, ( "early_data extension received" ) );
if( extension_data_len != 4 )
{
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
MBEDTLS_ERR_SSL_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_DECODE_ERROR );
}
if( ssl->session != NULL )
{
ssl->session->ticket_flags |=
MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA;
}
break;
#endif /* MBEDTLS_SSL_EARLY_DATA */
default:
MBEDTLS_SSL_PRINT_EXT(
3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
extension_type, "( ignored )" );
break;
}
p += extension_data_len;
}
MBEDTLS_SSL_PRINT_EXTS( 3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
handshake->received_extensions );
return( 0 );
}

View file

@ -398,6 +398,7 @@ int mbedtls_ssl_tls13_parse_certificate( mbedtls_ssl_context *ssl,
size_t certificate_list_len = 0;
const unsigned char *p = buf;
const unsigned char *certificate_list_end;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 4 );
certificate_request_context_len = p[0];
@ -447,6 +448,7 @@ int mbedtls_ssl_tls13_parse_certificate( mbedtls_ssl_context *ssl,
while( p < certificate_list_end )
{
size_t cert_data_len, extensions_len;
const unsigned char *extensions_end;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, certificate_list_end, 3 );
cert_data_len = MBEDTLS_GET_UINT24_BE( p, 0 );
@ -504,7 +506,48 @@ int mbedtls_ssl_tls13_parse_certificate( mbedtls_ssl_context *ssl,
extensions_len = MBEDTLS_GET_UINT16_BE( p, 0 );
p += 2;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, certificate_list_end, extensions_len );
p += extensions_len;
extensions_end = p + extensions_len;
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
while( p < extensions_end )
{
unsigned int extension_type;
size_t extension_data_len;
/*
* struct {
* ExtensionType extension_type; (2 bytes)
* opaque extension_data<0..2^16-1>;
* } Extension;
*/
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, 4 );
extension_type = MBEDTLS_GET_UINT16_BE( p, 0 );
extension_data_len = MBEDTLS_GET_UINT16_BE( p, 2 );
p += 4;
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_CERTIFICATE, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CT );
if( ret != 0 )
return( ret );
switch( extension_type )
{
default:
MBEDTLS_SSL_PRINT_EXT(
3, MBEDTLS_SSL_HS_CERTIFICATE,
extension_type, "( ignored )" );
break;
}
p += extension_data_len;
}
MBEDTLS_SSL_PRINT_EXTS( 3, MBEDTLS_SSL_HS_CERTIFICATE,
handshake->received_extensions );
}
exit:
@ -512,7 +555,7 @@ exit:
if( p != end )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad Certificate message" ) );
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, \
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
MBEDTLS_ERR_SSL_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_DECODE_ERROR );
}
@ -843,6 +886,9 @@ static int ssl_tls13_write_certificate_body( mbedtls_ssl_context *ssl,
*out_len = p - buf;
MBEDTLS_SSL_PRINT_EXTS(
3, MBEDTLS_SSL_HS_CERTIFICATE, ssl->handshake->sent_extensions );
return( 0 );
}
@ -1328,6 +1374,39 @@ cleanup:
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
/* Early Data Indication Extension
*
* struct {
* select ( Handshake.msg_type ) {
* ...
* case client_hello: Empty;
* case encrypted_extensions: Empty;
* };
* } EarlyDataIndication;
*/
#if defined(MBEDTLS_SSL_EARLY_DATA)
int mbedtls_ssl_tls13_write_early_data_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *out_len )
{
unsigned char *p = buf;
*out_len = 0;
((void) ssl);
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_EARLY_DATA, p, 0 );
MBEDTLS_PUT_UINT16_BE( 0, p, 2 );
*out_len = 4;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_EARLY_DATA );
return( 0 );
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
/* Reset SSL context and update hash for handling HRR.
*
* Replace Transcript-Hash(X) by
@ -1485,4 +1564,61 @@ int mbedtls_ssl_tls13_generate_and_write_ecdh_key_exchange(
}
#endif /* MBEDTLS_ECDH_C */
/* RFC 8446 section 4.2
*
* If an implementation receives an extension which it recognizes and which is
* not specified for the message in which it appears, it MUST abort the handshake
* with an "illegal_parameter" alert.
*
*/
int mbedtls_ssl_tls13_check_received_extension(
mbedtls_ssl_context *ssl,
int hs_msg_type,
unsigned int received_extension_type,
uint32_t hs_msg_allowed_extensions_mask )
{
uint32_t extension_mask = mbedtls_ssl_get_extension_mask(
received_extension_type );
MBEDTLS_SSL_PRINT_EXT(
3, hs_msg_type, received_extension_type, "received" );
if( ( extension_mask & hs_msg_allowed_extensions_mask ) == 0 )
{
MBEDTLS_SSL_PRINT_EXT(
3, hs_msg_type, received_extension_type, "is illegal" );
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
}
ssl->handshake->received_extensions |= extension_mask;
/*
* If it is a message containing extension responses, check that we
* previously sent the extension.
*/
switch( hs_msg_type )
{
case MBEDTLS_SSL_HS_SERVER_HELLO:
case MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST:
case MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS:
case MBEDTLS_SSL_HS_CERTIFICATE:
/* Check if the received extension is sent by peer message.*/
if( ( ssl->handshake->sent_extensions & extension_mask ) != 0 )
return( 0 );
break;
default:
return( 0 );
}
MBEDTLS_SSL_PRINT_EXT(
3, hs_msg_type, received_extension_type, "is unsupported" );
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
}
#endif /* MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_PROTO_TLS1_3 */

View file

@ -700,6 +700,8 @@ static int ssl_tls13_write_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 4, ( "sent selected_identity: %u",
ssl->handshake->selected_identity ) );
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_PRE_SHARED_KEY );
return( 0 );
}
@ -926,110 +928,69 @@ static int ssl_tls13_parse_key_shares_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_ECDH_C */
#if defined(MBEDTLS_DEBUG_C)
static void ssl_tls13_debug_print_client_hello_exts( mbedtls_ssl_context *ssl )
{
((void) ssl);
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Extensions:" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- KEY_SHARE_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_KEY_SHARE ) > 0 ) ? "TRUE" : "FALSE" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- PSK_KEY_EXCHANGE_MODES_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ) > 0 ) ?
"TRUE" : "FALSE" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- PRE_SHARED_KEY_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_PRE_SHARED_KEY ) > 0 ) ? "TRUE" : "FALSE" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- SIGNATURE_ALGORITHM_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_SIG_ALG ) > 0 ) ? "TRUE" : "FALSE" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- SUPPORTED_GROUPS_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_SUPPORTED_GROUPS ) >0 ) ?
"TRUE" : "FALSE" ) );
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- SUPPORTED_VERSION_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_SUPPORTED_VERSIONS ) > 0 ) ?
"TRUE" : "FALSE" ) );
#if defined ( MBEDTLS_SSL_SERVER_NAME_INDICATION )
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- SERVERNAME_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_SERVERNAME ) > 0 ) ?
"TRUE" : "FALSE" ) );
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined ( MBEDTLS_SSL_ALPN )
MBEDTLS_SSL_DEBUG_MSG( 3,
( "- ALPN_EXTENSION ( %s )",
( ( ssl->handshake->extensions_present
& MBEDTLS_SSL_EXT_ALPN ) > 0 ) ?
"TRUE" : "FALSE" ) );
#endif /* MBEDTLS_SSL_ALPN */
}
#endif /* MBEDTLS_DEBUG_C */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts( mbedtls_ssl_context *ssl,
int exts_mask )
{
int masked = ssl->handshake->extensions_present & exts_mask;
int masked = ssl->handshake->received_extensions & exts_mask;
return( masked == exts_mask );
}
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange(
mbedtls_ssl_context *ssl )
{
return( ssl_tls13_client_hello_has_exts(
ssl,
MBEDTLS_SSL_EXT_SUPPORTED_GROUPS |
MBEDTLS_SSL_EXT_KEY_SHARE |
MBEDTLS_SSL_EXT_SIG_ALG ) );
MBEDTLS_SSL_EXT_MASK( SUPPORTED_GROUPS ) |
MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) |
MBEDTLS_SSL_EXT_MASK( SIG_ALG ) ) );
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_psk_key_exchange(
mbedtls_ssl_context *ssl )
{
return( ssl_tls13_client_hello_has_exts(
ssl,
MBEDTLS_SSL_EXT_PRE_SHARED_KEY |
MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ) );
MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) |
MBEDTLS_SSL_EXT_MASK( PSK_KEY_EXCHANGE_MODES ) ) );
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(
mbedtls_ssl_context *ssl )
{
return( ssl_tls13_client_hello_has_exts(
ssl,
MBEDTLS_SSL_EXT_SUPPORTED_GROUPS |
MBEDTLS_SSL_EXT_KEY_SHARE |
MBEDTLS_SSL_EXT_PRE_SHARED_KEY |
MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ) );
MBEDTLS_SSL_EXT_MASK( SUPPORTED_GROUPS ) |
MBEDTLS_SSL_EXT_MASK( KEY_SHARE ) |
MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) |
MBEDTLS_SSL_EXT_MASK( PSK_KEY_EXCHANGE_MODES ) ) );
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_check_ephemeral_key_exchange( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
return( mbedtls_ssl_conf_tls13_ephemeral_enabled( ssl ) &&
ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange( ssl ) );
#else
((void) ssl);
return( 0 );
#endif
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_check_psk_key_exchange( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
return( mbedtls_ssl_conf_tls13_psk_enabled( ssl ) &&
mbedtls_ssl_tls13_psk_enabled( ssl ) &&
ssl_tls13_client_hello_has_exts_for_psk_key_exchange( ssl ) );
@ -1042,7 +1003,7 @@ static int ssl_tls13_check_psk_key_exchange( mbedtls_ssl_context *ssl )
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_check_psk_ephemeral_key_exchange( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
return( mbedtls_ssl_conf_tls13_psk_ephemeral_enabled( ssl ) &&
mbedtls_ssl_tls13_psk_ephemeral_enabled( ssl ) &&
ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange( ssl ) );
@ -1289,6 +1250,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
const unsigned char *cipher_suites_end;
size_t extensions_len;
const unsigned char *extensions_end;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
int hrr_required = 0;
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
@ -1297,8 +1259,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
const unsigned char *pre_shared_key_ext_end = NULL;
#endif
ssl->handshake->extensions_present = MBEDTLS_SSL_EXT_NONE;
/*
* ClientHello layout:
* 0 . 1 protocol version
@ -1356,7 +1316,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes",
p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN );
memcpy( &ssl->handshake->randbytes[0], p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN );
memcpy( &handshake->randbytes[0], p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN );
p += MBEDTLS_CLIENT_HELLO_RANDOM_LEN;
/* ...
@ -1426,13 +1386,13 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
continue;
ssl->session_negotiate->ciphersuite = cipher_suite;
ssl->handshake->ciphersuite_info = ciphersuite_info;
handshake->ciphersuite_info = ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %04x - %s",
cipher_suite,
ciphersuite_info->name ) );
}
if( ssl->handshake->ciphersuite_info == NULL )
if( handshake->ciphersuite_info == NULL )
{
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
@ -1468,27 +1428,29 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", p, extensions_len );
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
while( p < extensions_end )
{
unsigned int extension_type;
size_t extension_data_len;
const unsigned char *extension_data_end;
/* RFC 8446, page 57
/* RFC 8446, section 4.2.11
*
* The "pre_shared_key" extension MUST be the last extension in the
* ClientHello (this facilitates implementation as described below).
* Servers MUST check that it is the last extension and otherwise fail
* the handshake with an "illegal_parameter" alert.
*/
if( ssl->handshake->extensions_present & MBEDTLS_SSL_EXT_PRE_SHARED_KEY )
if( handshake->received_extensions & MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) )
{
MBEDTLS_SSL_DEBUG_MSG(
3, ( "pre_shared_key is not last extension." ) );
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
}
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, 4 );
@ -1499,6 +1461,12 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, extensions_end, extension_data_len );
extension_data_end = p + extension_data_len;
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_CLIENT_HELLO, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH );
if( ret != 0 )
return( ret );
switch( extension_type )
{
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@ -1512,7 +1480,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
1, "mbedtls_ssl_parse_servername_ext", ret );
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SERVERNAME;
break;
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
@ -1535,7 +1502,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_GROUPS;
break;
#endif /* MBEDTLS_ECDH_C */
@ -1565,7 +1531,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_KEY_SHARE;
break;
#endif /* MBEDTLS_ECDH_C */
@ -1580,7 +1545,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
( "ssl_tls13_parse_supported_versions_ext" ), ret );
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_VERSIONS;
break;
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
@ -1596,19 +1560,18 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES;
break;
#endif
case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found pre_shared_key extension" ) );
if( ( ssl->handshake->extensions_present &
MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ) == 0 )
if( ( handshake->received_extensions &
MBEDTLS_SSL_EXT_MASK( PSK_KEY_EXCHANGE_MODES ) ) == 0 )
{
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
}
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
/* Delay processing of the PSK identity once we have
@ -1617,8 +1580,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
*/
pre_shared_key_ext = p;
pre_shared_key_ext_end = extension_data_end;
#endif
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
break;
#if defined(MBEDTLS_SSL_ALPN)
@ -1632,7 +1594,6 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
1, ( "mbedtls_ssl_parse_alpn_ext" ), ret );
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_ALPN;
break;
#endif /* MBEDTLS_SSL_ALPN */
@ -1649,23 +1610,21 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
ret ) );
return( ret );
}
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SIG_ALG;
break;
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
default:
MBEDTLS_SSL_DEBUG_MSG( 3,
( "unknown extension found: %ud ( ignoring )",
extension_type ) );
MBEDTLS_SSL_PRINT_EXT(
3, MBEDTLS_SSL_HS_CLIENT_HELLO,
extension_type, "( ignored )" );
break;
}
p += extension_data_len;
}
#if defined(MBEDTLS_DEBUG_C)
/* List all the extensions we have received */
ssl_tls13_debug_print_client_hello_exts( ssl );
#endif /* MBEDTLS_DEBUG_C */
MBEDTLS_SSL_PRINT_EXTS( 3, MBEDTLS_SSL_HS_CLIENT_HELLO,
handshake->received_extensions );
mbedtls_ssl_add_hs_hdr_to_checksum( ssl,
MBEDTLS_SSL_HS_CLIENT_HELLO,
@ -1679,9 +1638,9 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
/* If we've settled on a PSK-based exchange, parse PSK identity ext */
if( mbedtls_ssl_tls13_some_psk_enabled( ssl ) &&
mbedtls_ssl_conf_tls13_some_psk_enabled( ssl ) &&
( ssl->handshake->extensions_present & MBEDTLS_SSL_EXT_PRE_SHARED_KEY ) )
( handshake->received_extensions & MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY ) ) )
{
ssl->handshake->update_checksum( ssl, buf,
handshake->update_checksum( ssl, buf,
pre_shared_key_ext - buf );
ret = ssl_tls13_parse_pre_shared_key_ext( ssl,
pre_shared_key_ext,
@ -1690,26 +1649,26 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
cipher_suites_end );
if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY )
{
ssl->handshake->extensions_present &= ~MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
handshake->received_extensions &= ~MBEDTLS_SSL_EXT_MASK( PRE_SHARED_KEY );
}
else if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_tls13_parse_pre_shared_key_ext" ),
ret );
MBEDTLS_SSL_DEBUG_RET(
1, "ssl_tls13_parse_pre_shared_key_ext" , ret );
return( ret );
}
}
else
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
{
ssl->handshake->update_checksum( ssl, buf, p - buf );
handshake->update_checksum( ssl, buf, p - buf );
}
ret = ssl_tls13_determine_key_exchange_mode( ssl );
if( ret < 0 )
return( ret );
mbedtls_ssl_optimize_checksum( ssl, ssl->handshake->ciphersuite_info );
mbedtls_ssl_optimize_checksum( ssl, handshake->ciphersuite_info );
return( hrr_required ? SSL_CLIENT_HELLO_HRR_REQUIRED : SSL_CLIENT_HELLO_OK );
}
@ -1856,6 +1815,9 @@ static int ssl_tls13_write_server_hello_supported_versions_ext(
*out_len = 6;
mbedtls_ssl_tls13_set_hs_sent_ext_mask(
ssl, MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS );
return( 0 );
}
@ -1962,6 +1924,8 @@ static int ssl_tls13_write_key_share_ext( mbedtls_ssl_context *ssl,
*out_len = p - buf;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_KEY_SHARE );
return( 0 );
}
@ -2026,6 +1990,8 @@ static int ssl_tls13_write_hrr_key_share_ext( mbedtls_ssl_context *ssl,
*out_len = 6;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_KEY_SHARE );
return( 0 );
}
@ -2054,6 +2020,7 @@ static int ssl_tls13_write_server_hello_body( mbedtls_ssl_context *ssl,
size_t output_len;
*out_len = 0;
ssl->handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
/* ...
* ProtocolVersion legacy_version = 0x0303; // TLS 1.2
@ -2179,6 +2146,11 @@ static int ssl_tls13_write_server_hello_body( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello", buf, *out_len );
MBEDTLS_SSL_PRINT_EXTS(
3, is_hrr ? MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST :
MBEDTLS_SSL_HS_SERVER_HELLO,
ssl->handshake->sent_extensions );
return( ret );
}
@ -2363,6 +2335,9 @@ static int ssl_tls13_write_encrypted_extensions_body( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 4, "encrypted extensions", buf, *out_len );
MBEDTLS_SSL_PRINT_EXTS(
3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, ssl->handshake->sent_extensions );
return( 0 );
}
@ -2492,6 +2467,9 @@ static int ssl_tls13_write_certificate_request_body( mbedtls_ssl_context *ssl,
*out_len = p - buf;
MBEDTLS_SSL_PRINT_EXTS(
3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, ssl->handshake->sent_extensions );
return( 0 );
}
@ -2877,6 +2855,8 @@ static int ssl_tls13_write_new_session_ticket_body( mbedtls_ssl_context *ssl,
* Note: We currently don't have any extensions.
* Set length to zero.
*/
ssl->handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
MBEDTLS_PUT_UINT16_BE( 0, p, 0 );
p += 2;
@ -2885,6 +2865,9 @@ static int ssl_tls13_write_new_session_ticket_body( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 4, "ticket", buf, *out_len );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) );
MBEDTLS_SSL_PRINT_EXTS(
3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, ssl->handshake->sent_extensions );
return( 0 );
}

View file

@ -157,8 +157,8 @@ int main( int argc, char **argv )
goto exit;
}
if( ( ret = mbedtls_mpi_write_file( "P = ", &P, 16, fout ) != 0 ) ||
( ret = mbedtls_mpi_write_file( "G = ", &G, 16, fout ) != 0 ) )
if( ( ( ret = mbedtls_mpi_write_file( "P = ", &P, 16, fout ) ) != 0 ) ||
( ( ret = mbedtls_mpi_write_file( "G = ", &G, 16, fout ) ) != 0 ) )
{
mbedtls_printf( " failed\n ! mbedtls_mpi_write_file returned %d\n\n", ret );
fclose( fout );

View file

@ -64,6 +64,7 @@ int main( void )
#define DFL_KEY_OPAQUE 0
#define DFL_KEY_PWD ""
#define DFL_PSK ""
#define DFL_EARLY_DATA MBEDTLS_SSL_EARLY_DATA_DISABLED
#define DFL_PSK_OPAQUE 0
#define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL
@ -344,6 +345,14 @@ int main( void )
#define USAGE_SERIALIZATION ""
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA)
#define USAGE_EARLY_DATA \
" early_data=%%d default: 0 (disabled)\n" \
" options: 0 (disabled), 1 (enabled)\n"
#else
#define USAGE_EARLY_DATA ""
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_PROTO_TLS1_3 */
#define USAGE_KEY_OPAQUE_ALGS \
" key_opaque_algs=%%s Allowed opaque key algorithms.\n" \
" comma-separated pair of values among the following:\n" \
@ -422,6 +431,7 @@ int main( void )
USAGE_REPRODUCIBLE \
USAGE_CURVES \
USAGE_SIG_ALGS \
USAGE_EARLY_DATA \
USAGE_DHMLEN \
USAGE_KEY_OPAQUE_ALGS \
"\n"
@ -533,6 +543,9 @@ struct options
* after renegotiation */
int reproducible; /* make communication reproducible */
int skip_close_notify; /* skip sending the close_notify alert */
#if defined(MBEDTLS_SSL_EARLY_DATA)
int early_data; /* support for early data */
#endif
int query_config_mode; /* whether to read config */
int use_srtp; /* Support SRTP */
int force_srtp_profile; /* SRTP protection profile to use or all */
@ -932,6 +945,9 @@ int main( int argc, char *argv[] )
opt.alpn_string = DFL_ALPN_STRING;
opt.curves = DFL_CURVES;
opt.sig_algs = DFL_SIG_ALGS;
#if defined(MBEDTLS_SSL_EARLY_DATA)
opt.early_data = DFL_EARLY_DATA;
#endif
opt.transport = DFL_TRANSPORT;
opt.hs_to_min = DFL_HS_TO_MIN;
opt.hs_to_max = DFL_HS_TO_MAX;
@ -1189,7 +1205,24 @@ int main( int argc, char *argv[] )
default: goto usage;
}
}
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
#if defined(MBEDTLS_SSL_EARLY_DATA)
else if( strcmp( p, "early_data" ) == 0 )
{
switch( atoi( q ) )
{
case 0:
opt.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
break;
case 1:
opt.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
break;
default: goto usage;
}
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
else if( strcmp( p, "tls13_kex_modes" ) == 0 )
{
if( strcmp( q, "psk" ) == 0 )
@ -2091,6 +2124,10 @@ int main( int argc, char *argv[] )
if( opt.max_version != DFL_MAX_VERSION )
mbedtls_ssl_conf_max_tls_version( &conf, opt.max_version );
#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_tls13_conf_early_data( &conf, opt.early_data );
#endif /* MBEDTLS_SSL_EARLY_DATA */
if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned -0x%x\n\n",

View file

@ -14,11 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import itertools
import typing
from abc import abstractmethod
from typing import Iterator, List, Tuple, TypeVar
from typing import Iterator, List, Tuple, TypeVar, Any
from itertools import chain
from . import test_case
from . import test_data_generation
from .bignum_data import INPUTS_DEFAULT, MODULI_DEFAULT
T = TypeVar('T') #pylint: disable=invalid-name
@ -38,7 +40,13 @@ def invmod(a: int, n: int) -> int:
raise ValueError("Not invertible")
def hex_to_int(val: str) -> int:
return int(val, 16) if val else 0
"""Implement the syntax accepted by mbedtls_test_read_mpi().
This is a superset of what is accepted by mbedtls_test_read_mpi_core().
"""
if val in ['', '-']:
return 0
return int(val, 16)
def quote_str(val) -> str:
return "\"{}\"".format(val)
@ -57,18 +65,10 @@ def limbs_mpi(val: int, bits_in_limb: int) -> int:
return (val.bit_length() + bits_in_limb - 1) // bits_in_limb
def combination_pairs(values: List[T]) -> List[Tuple[T, T]]:
"""Return all pair combinations from input values.
"""Return all pair combinations from input values."""
return [(x, y) for x in values for y in values]
The return value is cast, as older versions of mypy are unable to derive
the specific type returned by itertools.combinations_with_replacement.
"""
return typing.cast(
List[Tuple[T, T]],
list(itertools.combinations_with_replacement(values, 2))
)
class OperationCommon:
class OperationCommon(test_data_generation.BaseTest):
"""Common features for bignum binary operations.
This adds functionality common in binary operation tests.
@ -82,22 +82,106 @@ class OperationCommon:
unique_combinations_only: Boolean to select if test case combinations
must be unique. If True, only A,B or B,A would be included as a test
case. If False, both A,B and B,A would be included.
input_style: Controls the way how test data is passed to the functions
in the generated test cases. "variable" passes them as they are
defined in the python source. "arch_split" pads the values with
zeroes depending on the architecture/limb size. If this is set,
test cases are generated for all architectures.
arity: the number of operands for the operation. Currently supported
values are 1 and 2.
"""
symbol = ""
input_values = [] # type: List[str]
input_cases = [] # type: List[Tuple[str, str]]
unique_combinations_only = True
input_values = INPUTS_DEFAULT # type: List[str]
input_cases = [] # type: List[Any]
unique_combinations_only = False
input_styles = ["variable", "fixed", "arch_split"] # type: List[str]
input_style = "variable" # type: str
limb_sizes = [32, 64] # type: List[int]
arities = [1, 2]
arity = 2
def __init__(self, val_a: str, val_b: str) -> None:
self.arg_a = val_a
self.arg_b = val_b
def __init__(self, val_a: str, val_b: str = "0", bits_in_limb: int = 32) -> None:
self.val_a = val_a
self.val_b = val_b
# Setting the int versions here as opposed to making them @properties
# provides earlier/more robust input validation.
self.int_a = hex_to_int(val_a)
self.int_b = hex_to_int(val_b)
if bits_in_limb not in self.limb_sizes:
raise ValueError("Invalid number of bits in limb!")
if self.input_style == "arch_split":
self.dependencies = ["MBEDTLS_HAVE_INT{:d}".format(bits_in_limb)]
self.bits_in_limb = bits_in_limb
@property
def boundary(self) -> int:
if self.arity == 1:
return self.int_a
elif self.arity == 2:
return max(self.int_a, self.int_b)
raise ValueError("Unsupported number of operands!")
@property
def limb_boundary(self) -> int:
return bound_mpi(self.boundary, self.bits_in_limb)
@property
def limbs(self) -> int:
return limbs_mpi(self.boundary, self.bits_in_limb)
@property
def hex_digits(self) -> int:
return 2 * (self.limbs * self.bits_in_limb // 8)
def format_arg(self, val) -> str:
if self.input_style not in self.input_styles:
raise ValueError("Unknown input style!")
if self.input_style == "variable":
return val
else:
return val.zfill(self.hex_digits)
def format_result(self, res) -> str:
res_str = '{:x}'.format(res)
return quote_str(self.format_arg(res_str))
@property
def arg_a(self) -> str:
return self.format_arg(self.val_a)
@property
def arg_b(self) -> str:
if self.arity == 1:
raise AttributeError("Operation is unary and doesn't have arg_b!")
return self.format_arg(self.val_b)
def arguments(self) -> List[str]:
return [
quote_str(self.arg_a), quote_str(self.arg_b)
] + self.result()
args = [quote_str(self.arg_a)]
if self.arity == 2:
args.append(quote_str(self.arg_b))
return args + self.result()
def description(self) -> str:
"""Generate a description for the test case.
If not set, case_description uses the form A `symbol` B, where symbol
is used to represent the operation. Descriptions of each value are
generated to provide some context to the test case.
"""
if not self.case_description:
if self.arity == 1:
self.case_description = "{} {:x}".format(
self.symbol, self.int_a
)
elif self.arity == 2:
self.case_description = "{:x} {} {:x}".format(
self.int_a, self.symbol, self.int_b
)
return super().description()
@property
def is_valid(self) -> bool:
return True
@abstractmethod
def result(self) -> List[str]:
@ -115,15 +199,134 @@ class OperationCommon:
Combinations are first generated from all input values, and then
specific cases provided.
"""
if cls.unique_combinations_only:
yield from combination_pairs(cls.input_values)
if cls.arity == 1:
yield from ((a, "0") for a in cls.input_values)
elif cls.arity == 2:
if cls.unique_combinations_only:
yield from combination_pairs(cls.input_values)
else:
yield from (
(a, b)
for a in cls.input_values
for b in cls.input_values
)
else:
yield from (
(a, b)
for a in cls.input_values
for b in cls.input_values
)
yield from cls.input_cases
raise ValueError("Unsupported number of operands!")
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
if cls.input_style not in cls.input_styles:
raise ValueError("Unknown input style!")
if cls.arity not in cls.arities:
raise ValueError("Unsupported number of operands!")
if cls.input_style == "arch_split":
test_objects = (cls(a, b, bits_in_limb=bil)
for a, b in cls.get_value_pairs()
for bil in cls.limb_sizes)
special_cases = (cls(*args, bits_in_limb=bil) # type: ignore
for args in cls.input_cases
for bil in cls.limb_sizes)
else:
test_objects = (cls(a, b)
for a, b in cls.get_value_pairs())
special_cases = (cls(*args) for args in cls.input_cases)
yield from (valid_test_object.create_test_case()
for valid_test_object in filter(
lambda test_object: test_object.is_valid,
chain(test_objects, special_cases)
)
)
class ModOperationCommon(OperationCommon):
#pylint: disable=abstract-method
"""Target for bignum mod_raw test case generation."""
moduli = MODULI_DEFAULT # type: List[str]
def __init__(self, val_n: str, val_a: str, val_b: str = "0",
bits_in_limb: int = 64) -> None:
super().__init__(val_a=val_a, val_b=val_b, bits_in_limb=bits_in_limb)
self.val_n = val_n
# Setting the int versions here as opposed to making them @properties
# provides earlier/more robust input validation.
self.int_n = hex_to_int(val_n)
@property
def boundary(self) -> int:
return self.int_n
@property
def arg_n(self) -> str:
return self.format_arg(self.val_n)
def arguments(self) -> List[str]:
return [quote_str(self.arg_n)] + super().arguments()
@property
def r(self) -> int: # pylint: disable=invalid-name
l = limbs_mpi(self.int_n, self.bits_in_limb)
return bound_mpi_limbs(l, self.bits_in_limb)
@property
def r_inv(self) -> int:
return invmod(self.r, self.int_n)
@property
def r2(self) -> int: # pylint: disable=invalid-name
return pow(self.r, 2)
@property
def is_valid(self) -> bool:
if self.int_a >= self.int_n:
return False
if self.arity == 2 and self.int_b >= self.int_n:
return False
return True
def description(self) -> str:
"""Generate a description for the test case.
It uses the form A `symbol` B mod N, where symbol is used to represent
the operation.
"""
if not self.case_description:
return super().description() + " mod {:x}".format(self.int_n)
return super().description()
@classmethod
def input_cases_args(cls) -> Iterator[Tuple[Any, Any, Any]]:
if cls.arity == 1:
yield from ((n, a, "0") for a, n in cls.input_cases)
elif cls.arity == 2:
yield from ((n, a, b) for a, b, n in cls.input_cases)
else:
raise ValueError("Unsupported number of operands!")
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
if cls.input_style not in cls.input_styles:
raise ValueError("Unknown input style!")
if cls.arity not in cls.arities:
raise ValueError("Unsupported number of operands!")
if cls.input_style == "arch_split":
test_objects = (cls(n, a, b, bits_in_limb=bil)
for n in cls.moduli
for a, b in cls.get_value_pairs()
for bil in cls.limb_sizes)
special_cases = (cls(*args, bits_in_limb=bil)
for args in cls.input_cases_args()
for bil in cls.limb_sizes)
else:
test_objects = (cls(n, a, b)
for n in cls.moduli
for a, b in cls.get_value_pairs())
special_cases = (cls(*args) for args in cls.input_cases_args())
yield from (valid_test_object.create_test_case()
for valid_test_object in filter(
lambda test_object: test_object.is_valid,
chain(test_objects, special_cases)
))
# BEGIN MERGE SLOT 1

View file

@ -16,20 +16,19 @@
import random
from abc import ABCMeta
from typing import Dict, Iterator, List, Tuple
from . import test_case
from . import test_data_generation
from . import bignum_common
class BignumCoreTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
#pylint: disable=abstract-method
class BignumCoreTarget(test_data_generation.BaseTarget):
#pylint: disable=abstract-method, too-few-public-methods
"""Target for bignum core test case generation."""
target_basename = 'test_suite_bignum_core.generated'
class BignumCoreShiftR(BignumCoreTarget, metaclass=ABCMeta):
class BignumCoreShiftR(BignumCoreTarget, test_data_generation.BaseTest):
"""Test cases for mbedtls_bignum_core_shift_r()."""
count = 0
test_function = "mpi_core_shift_r"
@ -69,7 +68,7 @@ class BignumCoreShiftR(BignumCoreTarget, metaclass=ABCMeta):
for count in counts:
yield cls(input_hex, descr, count).create_test_case()
class BignumCoreCTLookup(BignumCoreTarget, metaclass=ABCMeta):
class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest):
"""Test cases for mbedtls_mpi_core_ct_uint_table_lookup()."""
test_function = "mpi_core_ct_uint_table_lookup"
test_name = "Constant time MPI table lookup"
@ -107,104 +106,33 @@ class BignumCoreCTLookup(BignumCoreTarget, metaclass=ABCMeta):
yield (cls(bitsize, bitsize_description, window_size)
.create_test_case())
class BignumCoreOperation(bignum_common.OperationCommon, BignumCoreTarget, metaclass=ABCMeta):
#pylint: disable=abstract-method
"""Common features for bignum core operations."""
input_values = [
"0", "1", "3", "f", "fe", "ff", "100", "ff00", "fffe", "ffff", "10000",
"fffffffe", "ffffffff", "100000000", "1f7f7f7f7f7f7f",
"8000000000000000", "fefefefefefefefe", "fffffffffffffffe",
"ffffffffffffffff", "10000000000000000", "1234567890abcdef0",
"fffffffffffffffffefefefefefefefe", "fffffffffffffffffffffffffffffffe",
"ffffffffffffffffffffffffffffffff", "100000000000000000000000000000000",
"1234567890abcdef01234567890abcdef0",
"fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe",
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"10000000000000000000000000000000000000000000000000000000000000000",
"1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0",
(
"4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029"
"643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947"
"c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0"
"cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b"
)
]
def description(self) -> str:
"""Generate a description for the test case.
If not set, case_description uses the form A `symbol` B, where symbol
is used to represent the operation. Descriptions of each value are
generated to provide some context to the test case.
"""
if not self.case_description:
self.case_description = "{:x} {} {:x}".format(
self.int_a, self.symbol, self.int_b
)
return super().description()
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
for a_value, b_value in cls.get_value_pairs():
yield cls(a_value, b_value).create_test_case()
class BignumCoreOperationArchSplit(BignumCoreOperation):
#pylint: disable=abstract-method
"""Common features for bignum core operations where the result depends on
the limb size."""
def __init__(self, val_a: str, val_b: str, bits_in_limb: int) -> None:
super().__init__(val_a, val_b)
bound_val = max(self.int_a, self.int_b)
self.bits_in_limb = bits_in_limb
self.bound = bignum_common.bound_mpi(bound_val, self.bits_in_limb)
limbs = bignum_common.limbs_mpi(bound_val, self.bits_in_limb)
byte_len = limbs * self.bits_in_limb // 8
self.hex_digits = 2 * byte_len
if self.bits_in_limb == 32:
self.dependencies = ["MBEDTLS_HAVE_INT32"]
elif self.bits_in_limb == 64:
self.dependencies = ["MBEDTLS_HAVE_INT64"]
else:
raise ValueError("Invalid number of bits in limb!")
self.arg_a = self.arg_a.zfill(self.hex_digits)
self.arg_b = self.arg_b.zfill(self.hex_digits)
def pad_to_limbs(self, val) -> str:
return "{:x}".format(val).zfill(self.hex_digits)
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
for a_value, b_value in cls.get_value_pairs():
yield cls(a_value, b_value, 32).create_test_case()
yield cls(a_value, b_value, 64).create_test_case()
class BignumCoreAddAndAddIf(BignumCoreOperationArchSplit):
class BignumCoreAddAndAddIf(BignumCoreTarget, bignum_common.OperationCommon):
"""Test cases for bignum core add and add-if."""
count = 0
symbol = "+"
test_function = "mpi_core_add_and_add_if"
test_name = "mpi_core_add_and_add_if"
input_style = "arch_split"
unique_combinations_only = True
def result(self) -> List[str]:
result = self.int_a + self.int_b
carry, result = divmod(result, self.bound)
carry, result = divmod(result, self.limb_boundary)
return [
bignum_common.quote_str(self.pad_to_limbs(result)),
self.format_result(result),
str(carry)
]
class BignumCoreSub(BignumCoreOperation):
class BignumCoreSub(BignumCoreTarget, bignum_common.OperationCommon):
"""Test cases for bignum core sub."""
count = 0
symbol = "-"
test_function = "mpi_core_sub"
test_name = "mbedtls_mpi_core_sub"
unique_combinations_only = False
def result(self) -> List[str]:
if self.int_a >= self.int_b:
@ -224,12 +152,11 @@ class BignumCoreSub(BignumCoreOperation):
]
class BignumCoreMLA(BignumCoreOperation):
class BignumCoreMLA(BignumCoreTarget, bignum_common.OperationCommon):
"""Test cases for fixed-size multiply accumulate."""
count = 0
test_function = "mpi_core_mla"
test_name = "mbedtls_mpi_core_mla"
unique_combinations_only = False
input_values = [
"0", "1", "fffe", "ffffffff", "100000000", "20000000000000",
@ -288,6 +215,16 @@ class BignumCoreMLA(BignumCoreOperation):
"\"{:x}\"".format(carry_8)
]
@classmethod
def get_value_pairs(cls) -> Iterator[Tuple[str, str]]:
"""Generator to yield pairs of inputs.
Combinations are first generated from all input values, and then
specific cases provided.
"""
yield from super().get_value_pairs()
yield from cls.input_cases
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
"""Override for additional scalar input."""
@ -297,7 +234,7 @@ class BignumCoreMLA(BignumCoreOperation):
yield cur_op.create_test_case()
class BignumCoreMontmul(BignumCoreTarget):
class BignumCoreMontmul(BignumCoreTarget, test_data_generation.BaseTest):
"""Test cases for Montgomery multiplication."""
count = 0
test_function = "mpi_core_montmul"

View file

@ -0,0 +1,136 @@
"""Base values and datasets for bignum generated tests and helper functions that
produced them."""
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import random
# Functions calling these were used to produce test data and are here only for
# reproducability, they are not used by the test generation framework/classes
try:
from Cryptodome.Util.number import isPrime, getPrime #type: ignore #pylint: disable=import-error
except ImportError:
pass
# Generated by bignum_common.gen_safe_prime(192,1)
SAFE_PRIME_192_BIT_SEED_1 = "d1c127a667786703830500038ebaef20e5a3e2dc378fb75b"
# First number generated by random.getrandbits(192) - seed(2,2), not a prime
RANDOM_192_BIT_SEED_2_NO1 = "177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"
# Second number generated by random.getrandbits(192) - seed(2,2), not a prime
RANDOM_192_BIT_SEED_2_NO2 = "cf1822ffbc6887782b491044d5e341245c6e433715ba2bdd"
# Third number generated by random.getrandbits(192) - seed(2,2), not a prime
RANDOM_192_BIT_SEED_2_NO3 = "3653f8dd9b1f282e4067c3584ee207f8da94e3e8ab73738f"
# Fourth number generated by random.getrandbits(192) - seed(2,2), not a prime
RANDOM_192_BIT_SEED_2_NO4 = "ffed9235288bc781ae66267594c9c9500925e4749b575bd1"
# Ninth number generated by random.getrandbits(192) - seed(2,2), not a prime
RANDOM_192_BIT_SEED_2_NO9 = "2a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"
# Generated by bignum_common.gen_safe_prime(1024,3)
SAFE_PRIME_1024_BIT_SEED_3 = ("c93ba7ec74d96f411ba008bdb78e63ff11bb5df46a51e16b"
"2c9d156f8e4e18abf5e052cb01f47d0d1925a77f60991577"
"e128fb6f52f34a27950a594baadd3d8057abeb222cf3cca9"
"62db16abf79f2ada5bd29ab2f51244bf295eff9f6aaba130"
"2efc449b128be75eeaca04bc3c1a155d11d14e8be32a2c82"
"87b3996cf6ad5223")
# First number generated by random.getrandbits(1024) - seed(4,2), not a prime
RANDOM_1024_BIT_SEED_4_NO1 = ("6905269ed6f0b09f165c8ce36e2f24b43000de01b2ed40ed"
"3addccb2c33be0ac79d679346d4ac7a5c3902b38963dc6e8"
"534f45738d048ec0f1099c6c3e1b258fd724452ccea71ff4"
"a14876aeaff1a098ca5996666ceab360512bd13110722311"
"710cf5327ac435a7a97c643656412a9b8a1abcd1a6916c74"
"da4f9fc3c6da5d7")
# Second number generated by random.getrandbits(1024) - seed(4,2), not a prime
RANDOM_1024_BIT_SEED_4_NO2 = ("f1cfd99216df648647adec26793d0e453f5082492d83a823"
"3fb62d2c81862fc9634f806fabf4a07c566002249b191bf4"
"d8441b5616332aca5f552773e14b0190d93936e1daca3c06"
"f5ff0c03bb5d7385de08caa1a08179104a25e4664f5253a0"
"2a3187853184ff27459142deccea264542a00403ce80c4b0"
"a4042bb3d4341aad")
# Third number generated by random.getrandbits(1024) - seed(4,2), not a prime
RANDOM_1024_BIT_SEED_4_NO3 = ("14c15c910b11ad28cc21ce88d0060cc54278c2614e1bcb38"
"3bb4a570294c4ea3738d243a6e58d5ca49c7b59b995253fd"
"6c79a3de69f85e3131f3b9238224b122c3e4a892d9196ada"
"4fcfa583e1df8af9b474c7e89286a1754abcb06ae8abb93f"
"01d89a024cdce7a6d7288ff68c320f89f1347e0cdd905ecf"
"d160c5d0ef412ed6")
# Fourth number generated by random.getrandbits(1024) - seed(4,2), not a prime
RANDOM_1024_BIT_SEED_4_NO4 = ("32decd6b8efbc170a26a25c852175b7a96b98b5fbf37a2be"
"6f98bca35b17b9662f0733c846bbe9e870ef55b1a1f65507"
"a2909cb633e238b4e9dd38b869ace91311021c9e32111ac1"
"ac7cc4a4ff4dab102522d53857c49391b36cc9aa78a330a1"
"a5e333cb88dcf94384d4cd1f47ca7883ff5a52f1a05885ac"
"7671863c0bdbc23a")
# Fifth number generated by random.getrandbits(1024) - seed(4,2), not a prime
RANDOM_1024_BIT_SEED_4_NO5 = ("53be4721f5b9e1f5acdac615bc20f6264922b9ccf469aef8"
"f6e7d078e55b85dd1525f363b281b8885b69dc230af5ac87"
"0692b534758240df4a7a03052d733dcdef40af2e54c0ce68"
"1f44ebd13cc75f3edcb285f89d8cf4d4950b16ffc3e1ac3b"
"4708d9893a973000b54a23020fc5b043d6e4a51519d9c9cc"
"52d32377e78131c1")
# Adding 192 bit and 1024 bit numbers because these are the shortest required
# for ECC and RSA respectively.
INPUTS_DEFAULT = [
"0", "1", # corner cases
"2", "3", # small primes
"4", # non-prime even
"38", # small random
SAFE_PRIME_192_BIT_SEED_1, # prime
RANDOM_192_BIT_SEED_2_NO1, # not a prime
RANDOM_192_BIT_SEED_2_NO2, # not a prime
SAFE_PRIME_1024_BIT_SEED_3, # prime
RANDOM_1024_BIT_SEED_4_NO1, # not a prime
RANDOM_1024_BIT_SEED_4_NO3, # not a prime
RANDOM_1024_BIT_SEED_4_NO2, # largest (not a prime)
]
# Only odd moduli are present as in the new bignum code only odd moduli are
# supported for now.
MODULI_DEFAULT = [
"53", # safe prime
"45", # non-prime
SAFE_PRIME_192_BIT_SEED_1, # safe prime
RANDOM_192_BIT_SEED_2_NO4, # not a prime
SAFE_PRIME_1024_BIT_SEED_3, # safe prime
RANDOM_1024_BIT_SEED_4_NO5, # not a prime
]
def __gen_safe_prime(bits, seed):
'''
Generate a safe prime.
This function is intended for generating constants offline and shouldn't be
used in test generation classes.
Requires pycryptodomex for getPrime and isPrime and python 3.9 or later for
randbytes.
'''
rng = random.Random()
# We want reproducability across python versions
rng.seed(seed, version=2)
while True:
prime = 2*getPrime(bits-1, rng.randbytes)+1 #pylint: disable=no-member
if isPrime(prime, 1e-30):
return prime

View file

@ -14,12 +14,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from abc import ABCMeta
from . import test_data_generation
class BignumModTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
#pylint: disable=abstract-method
class BignumModTarget(test_data_generation.BaseTarget):
#pylint: disable=abstract-method, too-few-public-methods
"""Target for bignum mod test case generation."""
target_basename = 'test_suite_bignum_mod.generated'

View file

@ -14,12 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from abc import ABCMeta
from typing import Dict, List
from . import test_data_generation
from . import bignum_common
class BignumModRawTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
#pylint: disable=abstract-method
class BignumModRawTarget(test_data_generation.BaseTarget):
#pylint: disable=abstract-method, too-few-public-methods
"""Target for bignum mod_raw test case generation."""
target_basename = 'test_suite_bignum_mod_raw.generated'
@ -49,6 +50,34 @@ class BignumModRawTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
# BEGIN MERGE SLOT 7
class BignumModRawConvertToMont(bignum_common.ModOperationCommon,
BignumModRawTarget):
""" Test cases for mpi_mod_raw_to_mont_rep(). """
test_function = "mpi_mod_raw_to_mont_rep"
test_name = "Convert into Mont: "
symbol = "R *"
input_style = "arch_split"
arity = 1
def result(self) -> List[str]:
result = (self.int_a * self.r) % self.int_n
return [self.format_result(result)]
class BignumModRawConvertFromMont(bignum_common.ModOperationCommon,
BignumModRawTarget):
""" Test cases for mpi_mod_raw_from_mont_rep(). """
test_function = "mpi_mod_raw_from_mont_rep"
test_name = "Convert from Mont: "
symbol = "1/R *"
input_style = "arch_split"
arity = 1
def result(self) -> List[str]:
result = (self.int_a * self.r_inv) % self.int_n
return [self.format_result(result)]
# END MERGE SLOT 7
# BEGIN MERGE SLOT 8

View file

@ -25,6 +25,7 @@ import argparse
import os
import posixpath
import re
import inspect
from abc import ABCMeta, abstractmethod
from typing import Callable, Dict, Iterable, Iterator, List, Type, TypeVar
@ -35,12 +36,8 @@ from . import test_case
T = TypeVar('T') #pylint: disable=invalid-name
class BaseTarget(metaclass=ABCMeta):
"""Base target for test case generation.
Child classes of this class represent an output file, and can be referred
to as file targets. These indicate where test cases will be written to for
all subclasses of the file target, which is set by `target_basename`.
class BaseTest(metaclass=ABCMeta):
"""Base class for test case generation.
Attributes:
count: Counter for test cases from this class.
@ -48,8 +45,6 @@ class BaseTarget(metaclass=ABCMeta):
automatically generated using the class, or manually set.
dependencies: A list of dependencies required for the test case.
show_test_count: Toggle for inclusion of `count` in the test description.
target_basename: Basename of file to write generated tests to. This
should be specified in a child class of BaseTarget.
test_function: Test function which the class generates cases for.
test_name: A common name or description of the test function. This can
be `test_function`, a clearer equivalent, or a short summary of the
@ -59,7 +54,6 @@ class BaseTarget(metaclass=ABCMeta):
case_description = ""
dependencies = [] # type: List[str]
show_test_count = True
target_basename = ""
test_function = ""
test_name = ""
@ -121,6 +115,21 @@ class BaseTarget(metaclass=ABCMeta):
"""
raise NotImplementedError
class BaseTarget:
#pylint: disable=too-few-public-methods
"""Base target for test case generation.
Child classes of this class represent an output file, and can be referred
to as file targets. These indicate where test cases will be written to for
all subclasses of the file target, which is set by `target_basename`.
Attributes:
target_basename: Basename of file to write generated tests to. This
should be specified in a child class of BaseTarget.
"""
target_basename = ""
@classmethod
def generate_tests(cls) -> Iterator[test_case.TestCase]:
"""Generate test cases for the class and its subclasses.
@ -132,7 +141,8 @@ class BaseTarget(metaclass=ABCMeta):
yield from `generate_tests()` in each. Calling this method on a class X
will yield test cases from all classes derived from X.
"""
if cls.test_function:
if issubclass(cls, BaseTest) and not inspect.isabstract(cls):
#pylint: disable=no-member
yield from cls.generate_function_tests()
for subclass in sorted(cls.__subclasses__(), key=lambda c: c.__name__):
yield from subclass.generate_tests()

View file

@ -884,6 +884,11 @@ server1.req.sha256: server1.key
$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O=PolarSSL,CN=PolarSSL Server 1" md=SHA256
all_final += server1.req.sha256
server1.req.sha256.ext: server1.key
# Generating this with OpenSSL as a comparison point to test we're getting the same result
openssl req -new -out $@ -key $< -subj '/C=NL/O=PolarSSL/CN=PolarSSL Server 1' -sha256 -addext "extendedKeyUsage=serverAuth"
all_final += server1.req.sha256.ext
server1.req.sha384: server1.key
$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O=PolarSSL,CN=PolarSSL Server 1" md=SHA384
all_final += server1.req.sha384

View file

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICpzCCAY8CAQAwPDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRow
GAYDVQQDDBFQb2xhclNTTCBTZXJ2ZXIgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAKkCHz1AatVVU4v9Nu6CZS4VYV6Jv7joRZDb7ogWUtPxQ1BHlhJZ
ZIdr/SvgRvlzvt3PkuGRW+1moG+JKXlFgNCDatVBQ3dfOXwJBEeCsFc5cO2j7BUZ
HqgzCEfBBUKp/UzDtN/dBh9NEFFAZ3MTD0D4bYElXwqxU8YwfhU5rPla7n+SnqYF
W+cTl4W1I5LZ1CQG1QkliXUH3aYajz8JGb6tZSxk65Wb3P5BXhem2mxbacwCuhQs
FiScStzN0PdSZ3PxLaAj/X70McotcMqJCwTbLqZPcG6ezr1YieJTWZ5uWpJl4og/
DJQZo93l6J2VE+0p26twEtxaymsXq1KCVLECAwEAAaAmMCQGCSqGSIb3DQEJDjEX
MBUwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAHi0yEGu
Fh5tuLiLuT95UrRnly55+lTY9xchFiKtlcoEdSheybYxqk3JHuSSqojOFKZBlRdk
oG6Azg56/aMHPWyvtCMSRQX4b+FgjeQsm9IfhYNMquQOxyPxm62vjuU3MfZIofXH
hKdI6Ci2CDF4Fyvw50KBWniV38eE9+kjsvDLdXD3ESZJGhjjuFl8ReUiA2wdBTcP
XEZaXUIc6B4tUnlPeqn/2zp4GBqqWzNZx6TXBpApASGG3BEJnM52FVPC7E9p+8YZ
qIGuiF5Cz/rYZkpwffBWIfS2zZakHLm5TB8FgZkWlyReJU9Ihk2Tl/sZ1kllFdYa
xLPnLCL82KFL1Co=
-----END CERTIFICATE REQUEST-----

View file

@ -295,13 +295,19 @@ int mbedtls_test_read_mpi_core( mbedtls_mpi_uint **pX, size_t *plimbs,
/** Read an MPI from a hexadecimal string.
*
* Like mbedtls_mpi_read_string(), but size the resulting bignum based
* on the number of digits in the string. In particular, construct a
* bignum with 0 limbs for an empty string, and a bignum with leading 0
* limbs if the string has sufficiently many leading 0 digits.
* Like mbedtls_mpi_read_string(), but with tighter guarantees around
* edge cases.
*
* This is important so that the "0 (null)" and "0 (1 limb)" and
* "leading zeros" test cases do what they claim.
* - This function guarantees that if \p s begins with '-' then the sign
* bit of the result will be negative, even if the value is 0.
* When this function encounters such a "negative 0", it
* increments #mbedtls_test_case_uses_negative_0.
* - The size of the result is exactly the minimum number of limbs needed
* to fit the digits in the input. In particular, this function constructs
* a bignum with 0 limbs for an empty string, and a bignum with leading 0
* limbs if the string has sufficiently many leading 0 digits.
* This is important so that the "0 (null)" and "0 (1 limb)" and
* "leading zeros" test cases do what they claim.
*
* \param[out] X The MPI object to populate. It must be initialized.
* \param[in] s The null-terminated hexadecimal string to read from.
@ -309,6 +315,14 @@ int mbedtls_test_read_mpi_core( mbedtls_mpi_uint **pX, size_t *plimbs,
* \return \c 0 on success, an \c MBEDTLS_ERR_MPI_xxx error code otherwise.
*/
int mbedtls_test_read_mpi( mbedtls_mpi *X, const char *s );
/** Nonzero if the current test case had an input parsed with
* mbedtls_test_read_mpi() that is a negative 0 (`"-"`, `"-0"`, `"-00"`, etc.,
* constructing a result with the sign bit set to -1 and the value being
* all-limbs-0, which is not a valid representation in #mbedtls_mpi but is
* tested for robustness).
*/
extern unsigned mbedtls_test_case_uses_negative_0;
#endif /* MBEDTLS_BIGNUM_C */
#endif /* TEST_HELPERS_H */

View file

@ -18,228 +18,8 @@
# limitations under the License.
#
get_srv_psk_list ()
{
case $(( TESTS % 3 )) in
0) echo "psk_list=abc,dead,def,beef,Client_identity,6162636465666768696a6b6c6d6e6f70";;
1) echo "psk_list=abc,dead,Client_identity,6162636465666768696a6b6c6d6e6f70,def,beef";;
2) echo "psk_list=Client_identity,6162636465666768696a6b6c6d6e6f70,abc,dead,def,beef";;
esac
}
requires_gnutls_tls1_3
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3: PSK: No valid ciphersuite. G->m" \
"$P_SRV force_version=tls13 tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \
"$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-CIPHER-ALL:+AES-256-GCM:+AEAD:+SHA384:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3 \
--pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \
localhost" \
1 \
-s "found psk key exchange modes extension" \
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "No matched ciphersuite"
requires_openssl_tls1_3
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3: PSK: No valid ciphersuite. O->m" \
"$P_SRV force_version=tls13 tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \
"$O_NEXT_CLI -tls1_3 -msg -allow_no_dhe_kex -ciphersuites TLS_AES_256_GCM_SHA384\
-psk_identity Client_identity -psk 6162636465666768696a6b6c6d6e6f70" \
1 \
-s "found psk key exchange modes extension" \
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "No matched ciphersuite"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Multiple PSKs: valid ticket, reconnect with ticket" \
"$P_SRV force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 tickets=8" \
"$P_CLI force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 2" \
-s "sent selected_identity: 0" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "key exchange mode: ephemeral$" \
-S "ticket is not authentic"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Multiple PSKs: invalid ticket, reconnect with PSK" \
"$P_SRV force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 tickets=8 dummy_ticket=1" \
"$P_CLI force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 2" \
-s "sent selected_identity: 1" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "key exchange mode: ephemeral$" \
-s "ticket is not authentic"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, ticket authentication failed." \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=1" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-s "ticket is not authentic" \
-S "ticket is expired" \
-S "Invalid ticket start time" \
-S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, ticket expired." \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=2" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-s "ticket is expired" \
-S "Invalid ticket start time" \
-S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, invalid start time." \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=3" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
-s "Invalid ticket start time" \
-S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, ticket expired. too old" \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=4" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
-S "Invalid ticket start time" \
-s "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window, too young." \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=5" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
-S "Invalid ticket start time" \
-S "Ticket age exceeds limitation" \
-s "Ticket age outside tolerance window"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window, too old." \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=6" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
-S "Invalid ticket start time" \
-S "Ticket age exceeds limitation" \
-s "Ticket age outside tolerance window"
requires_gnutls_tls1_3
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3: G->m: ephemeral_all/psk, fail, no common kex mode" \
"$P_SRV force_version=tls13 tls13_kex_modes=psk debug_level=5 $(get_srv_psk_list)" \
"$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:-PSK:+VERS-TLS1.3 \
--pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \
localhost" \
1 \
-s "found psk key exchange modes extension" \
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
# DO NOT ADD NEW TEST CASES INTO THIS FILE. The left cases will be generated by
# scripts in future(#6280)
requires_gnutls_tls1_3
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C

346
tests/opt-testcases/tls13-misc.sh Executable file
View file

@ -0,0 +1,346 @@
#!/bin/sh
# tls13-misc.sh
#
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
requires_gnutls_tls1_3
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3: PSK: No valid ciphersuite. G->m" \
"$P_SRV force_version=tls13 tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \
"$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-CIPHER-ALL:+AES-256-GCM:+AEAD:+SHA384:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3 \
--pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \
localhost" \
1 \
-s "found psk key exchange modes extension" \
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "No matched ciphersuite"
requires_openssl_tls1_3
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3: PSK: No valid ciphersuite. O->m" \
"$P_SRV force_version=tls13 tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \
"$O_NEXT_CLI -tls1_3 -msg -allow_no_dhe_kex -ciphersuites TLS_AES_256_GCM_SHA384\
-psk_identity Client_identity -psk 6162636465666768696a6b6c6d6e6f70" \
1 \
-s "found psk key exchange modes extension" \
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "No matched ciphersuite"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Multiple PSKs: valid ticket, reconnect with ticket" \
"$P_SRV force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 tickets=8" \
"$P_CLI force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 2" \
-s "sent selected_identity: 0" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "key exchange mode: ephemeral$" \
-S "ticket is not authentic"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Multiple PSKs: invalid ticket, reconnect with PSK" \
"$P_SRV force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 tickets=8 dummy_ticket=1" \
"$P_CLI force_version=tls13 tls13_kex_modes=psk_ephemeral debug_level=5 psk_identity=Client_identity psk=6162636465666768696a6b6c6d6e6f70 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 2" \
-s "sent selected_identity: 1" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "key exchange mode: ephemeral$" \
-s "ticket is not authentic"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, ticket authentication failed." \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=1" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-s "ticket is not authentic" \
-S "ticket is expired" \
-S "Invalid ticket start time" \
-S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, ticket expired." \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=2" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-s "ticket is expired" \
-S "Invalid ticket start time" \
-S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, invalid start time." \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=3" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
-s "Invalid ticket start time" \
-S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, ticket expired. too old" \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=4" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
-S "Invalid ticket start time" \
-s "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window, too young." \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=5" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
-S "Invalid ticket start time" \
-S "Ticket age exceeds limitation" \
-s "Ticket age outside tolerance window"
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \
MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED \
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
requires_any_configs_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window, too old." \
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=8 dummy_ticket=6" \
"$P_CLI debug_level=4 reco_mode=1 reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
-S "sent selected_identity:" \
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
-S "Invalid ticket start time" \
-S "Ticket age exceeds limitation" \
-s "Ticket age outside tolerance window"
requires_gnutls_tls1_3
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3: G->m: ephemeral_all/psk, fail, no common kex mode" \
"$P_SRV force_version=tls13 tls13_kex_modes=psk debug_level=5 $(get_srv_psk_list)" \
"$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:-PSK:+VERS-TLS1.3 \
--pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \
localhost" \
1 \
-s "found psk key exchange modes extension" \
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
requires_gnutls_tls1_3
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \
MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
requires_all_configs_disabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
run_test "TLS 1.3: G->m: PSK: configured psk only, good." \
"$P_SRV force_version=tls13 tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \
"$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3:+GROUP-ALL \
--pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \
localhost" \
0 \
-s "found psk key exchange modes extension" \
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "key exchange mode: psk$"
requires_gnutls_tls1_3
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \
MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
requires_all_configs_disabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
run_test "TLS 1.3: G->m: PSK: configured psk_ephemeral only, good." \
"$P_SRV force_version=tls13 tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \
"$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3:+GROUP-ALL \
--pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \
localhost" \
0 \
-s "found psk key exchange modes extension" \
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "key exchange mode: psk_ephemeral$"
requires_gnutls_tls1_3
requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \
MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
requires_all_configs_disabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
run_test "TLS 1.3: G->m: PSK: configured ephemeral only, good." \
"$P_SRV force_version=tls13 tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \
"$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3:+GROUP-ALL \
--pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \
localhost" \
0 \
-s "key exchange mode: ephemeral$"
# skip the basic check now cause it will randomly trigger the anti-replay protection in gnutls_server
# Add it back once we fix the issue
skip_next_test
requires_gnutls_tls1_3
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_CLI_C
requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
MBEDTLS_SSL_EARLY_DATA
requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3 m->G: EarlyData: basic check, good" \
"$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --earlydata --disable-client-cert" \
"$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=2" \
1 \
-c "Reconnecting with saved session" \
-c "NewSessionTicket: early_data(42) extension received." \
-c "ClientHello: early_data(42) extension exists." \
-c "EncryptedExtensions: early_data(42) extension received." \
-c "EncryptedExtensions: early_data(42) extension ( ignored )." \
-s "Parsing extension 'Early Data/42' (0 bytes)" \
-s "Sending extension Early Data/42 (0 bytes)" \
-s "early data accepted"
requires_gnutls_tls1_3
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_CLI_C
requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
MBEDTLS_SSL_EARLY_DATA
requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3 m->G: EarlyData: no early_data in NewSessionTicket, good" \
"$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --disable-client-cert" \
"$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=2" \
0 \
-c "Reconnecting with saved session" \
-C "NewSessionTicket: early_data(42) extension received." \
-c "ClientHello: early_data(42) extension does not exist." \
-C "EncryptedExtensions: early_data(42) extension received." \
-C "EncryptedExtensions: early_data(42) extension ( ignored )."
#TODO: OpenSSL tests don't work now. It might be openssl options issue, cause GnuTLS has worked.
skip_next_test
requires_openssl_tls1_3
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_CLI_C
requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
MBEDTLS_SSL_EARLY_DATA
requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3, ext PSK, early data" \
"$O_NEXT_SRV_EARLY_DATA -msg -debug -tls1_3 -psk_identity 0a0b0c -psk 010203 -allow_no_dhe_kex -nocert" \
"$P_CLI debug_level=5 force_version=tls13 tls13_kex_modes=psk early_data=1 psk=010203 psk_identity=0a0b0c" \
1 \
-c "Reconnecting with saved session" \
-c "NewSessionTicket: early_data(42) extension received." \
-c "ClientHello: early_data(42) extension exists." \
-c "EncryptedExtensions: early_data(42) extension received." \
-c "EncryptedExtensions: early_data(42) extension ( ignored )."

View file

@ -2097,6 +2097,47 @@ component_test_psa_crypto_config_accel_hash () {
make test
}
# Auxiliary function to build config for hashes with and without drivers
config_psa_crypto_hash_use_psa () {
DRIVER_ONLY="$1"
# start with config full for maximum coverage (also enables USE_PSA)
scripts/config.py full
# enable support for drivers and configuring PSA-only algorithms
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
if [ "$DRIVER_ONLY" -eq 1 ]; then
# disable the built-in implementation of hashes
scripts/config.py unset MBEDTLS_MD5_C
scripts/config.py unset MBEDTLS_RIPEMD160_C
scripts/config.py unset MBEDTLS_SHA1_C
scripts/config.py unset MBEDTLS_SHA224_C
scripts/config.py unset MBEDTLS_SHA256_C # see external RNG below
scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
scripts/config.py unset MBEDTLS_SHA384_C
scripts/config.py unset MBEDTLS_SHA512_C
scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
fi
# Use an external RNG as currently internal RNGs depend on entropy.c
# which in turn hard-depends on SHA256_C (or SHA512_C).
# See component_test_psa_external_rng_no_drbg_use_psa.
scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
scripts/config.py unset MBEDTLS_ENTROPY_C
scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED # depends on ENTROPY_C
scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT # depends on former
# Also unset MD_C and things that depend on it;
# see component_test_crypto_full_no_md.
if [ "$DRIVER_ONLY" -eq 1 ]; then
scripts/config.py unset MBEDTLS_MD_C
fi
scripts/config.py unset MBEDTLS_HKDF_C # has independent PSA implementation
scripts/config.py unset MBEDTLS_HMAC_DRBG_C
scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
}
# Note that component_test_psa_crypto_config_reference_hash_use_psa
# is related to this component and both components need to be kept in sync.
# For details please see comments for component_test_psa_crypto_config_reference_hash_use_psa.
component_test_psa_crypto_config_accel_hash_use_psa () {
msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash and USE_PSA"
@ -2109,35 +2150,7 @@ component_test_psa_crypto_config_accel_hash_use_psa () {
loc_accel_flags=$( echo "$loc_accel_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' )
make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS"
# start with config full for maximum coverage (also enables USE_PSA)
scripts/config.py full
# enable support for drivers and configuring PSA-only algorithms
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
# disable the built-in implementation of hashes
scripts/config.py unset MBEDTLS_MD5_C
scripts/config.py unset MBEDTLS_RIPEMD160_C
scripts/config.py unset MBEDTLS_SHA1_C
scripts/config.py unset MBEDTLS_SHA224_C
scripts/config.py unset MBEDTLS_SHA256_C # see external RNG below
scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
scripts/config.py unset MBEDTLS_SHA384_C
scripts/config.py unset MBEDTLS_SHA512_C
scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
# Use an external RNG as currently internal RNGs depend on entropy.c
# which in turn hard-depends on SHA256_C (or SHA512_C).
# See component_test_psa_external_rng_no_drbg_use_psa.
scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
scripts/config.py unset MBEDTLS_ENTROPY_C
scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED # depends on ENTROPY_C
scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT # depends on former
# Also unset MD_C and things that depend on it;
# see component_test_crypto_full_no_md.
scripts/config.py unset MBEDTLS_MD_C
scripts/config.py unset MBEDTLS_HKDF_C # has independent PSA implementation
scripts/config.py unset MBEDTLS_HMAC_DRBG_C
scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
config_psa_crypto_hash_use_psa 1
loc_accel_flags="$loc_accel_flags $( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )"
make CFLAGS="$ASAN_CFLAGS -Werror -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS" all
@ -2154,16 +2167,32 @@ component_test_psa_crypto_config_accel_hash_use_psa () {
msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash and USE_PSA"
make test
# hidden option: when running outcome-analysis.sh, we can skip this
if [ "${SKIP_SSL_OPT_COMPAT_SH-unset}" = "unset" ]; then
msg "test: ssl-opt.sh, MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash and USE_PSA"
tests/ssl-opt.sh
msg "test: ssl-opt.sh, MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash and USE_PSA"
tests/ssl-opt.sh
msg "test: compat.sh, MBEDTLS_PSA_CRYPTO_CONFIG with accelerated hash and USE_PSA"
tests/compat.sh
else
echo "skip ssl-opt.sh and compat.sh"
fi
msg "test: compat.sh, MBEDTLS_PSA_CRYPTO_CONFIG without accelerated hash and USE_PSA"
tests/compat.sh
}
# This component provides reference configuration for test_psa_crypto_config_accel_hash_use_psa
# without accelerated hash. The outcome from both components are used by the analyze_outcomes.py
# script to find regression in test coverage when accelerated hash is used (tests and ssl-opt).
# Both components need to be kept in sync.
component_test_psa_crypto_config_reference_hash_use_psa() {
msg "test: MBEDTLS_PSA_CRYPTO_CONFIG without accelerated hash and USE_PSA"
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER
scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_ECB_NO_PADDING
config_psa_crypto_hash_use_psa 0
make
msg "test: MBEDTLS_PSA_CRYPTO_CONFIG without accelerated hash and USE_PSA"
make test
msg "test: ssl-opt.sh, MBEDTLS_PSA_CRYPTO_CONFIG without accelerated hash and USE_PSA"
tests/ssl-opt.sh
}
component_test_psa_crypto_config_accel_cipher () {
@ -3285,6 +3314,7 @@ component_test_tls13_only_ephemeral () {
msg "build: TLS 1.3 only from default, only ephemeral key exchange mode"
scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
scripts/config.py unset MBEDTLS_SSL_EARLY_DATA
make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
msg "test_suite_ssl: TLS 1.3 only, only ephemeral key exchange mode"

View file

@ -9,6 +9,7 @@ less likely to be useful.
import argparse
import sys
import traceback
import re
import check_test_cases
@ -60,6 +61,37 @@ def analyze_coverage(results, outcomes):
# fixed this branch to have full coverage of test cases.
results.warning('Test case not executed: {}', key)
def analyze_driver_vs_reference(outcomes, component_ref, component_driver, ignored_tests):
"""Check that all tests executed in the reference component are also
executed in the corresponding driver component.
Skip test suites provided in ignored_tests list.
"""
available = check_test_cases.collect_available_test_cases()
result = True
for key in available:
# Skip ignored test suites
test_suite = key.split(';')[0] # retrieve test suit name
test_suite = test_suite.split('.')[0] # retrieve main part of test suit name
if test_suite in ignored_tests:
continue
# Continue if test was not executed by any component
hits = outcomes[key].hits() if key in outcomes else 0
if hits == 0:
continue
# Search for tests that run in reference component and not in driver component
driver_test_passed = False
reference_test_passed = False
for entry in outcomes[key].successes:
if component_driver in entry:
driver_test_passed = True
if component_ref in entry:
reference_test_passed = True
if(driver_test_passed is False and reference_test_passed is True):
print('{}: driver: skipped/failed; reference: passed'.format(key))
result = False
return result
def analyze_outcomes(outcomes):
"""Run all analyses on the given outcome collection."""
results = Results()
@ -87,20 +119,75 @@ by a semicolon.
outcomes[key].failures.append(setup)
return outcomes
def analyze_outcome_file(outcome_file):
"""Analyze the given outcome file."""
def do_analyze_coverage(outcome_file, args):
"""Perform coverage analysis."""
del args # unused
outcomes = read_outcome_file(outcome_file)
return analyze_outcomes(outcomes)
results = analyze_outcomes(outcomes)
return results.error_count == 0
def do_analyze_driver_vs_reference(outcome_file, args):
"""Perform driver vs reference analyze."""
ignored_tests = ['test_suite_' + x for x in args['ignored_suites']]
outcomes = read_outcome_file(outcome_file)
return analyze_driver_vs_reference(outcomes, args['component_ref'],
args['component_driver'], ignored_tests)
# List of tasks with a function that can handle this task and additional arguments if required
TASKS = {
'analyze_coverage': {
'test_function': do_analyze_coverage,
'args': {}},
'analyze_driver_vs_reference_hash': {
'test_function': do_analyze_driver_vs_reference,
'args': {
'component_ref': 'test_psa_crypto_config_reference_hash_use_psa',
'component_driver': 'test_psa_crypto_config_accel_hash_use_psa',
'ignored_suites': ['shax', 'mdx', # the software implementations that are being excluded
'md', # the legacy abstraction layer that's being excluded
]}}
}
def main():
try:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('outcomes', metavar='OUTCOMES.CSV',
help='Outcome file to analyze')
parser.add_argument('task', default='all', nargs='?',
help='Analysis to be done. By default, run all tasks. '
'With one or more TASK, run only those. '
'TASK can be the name of a single task or '
'comma/space-separated list of tasks. ')
parser.add_argument('--list', action='store_true',
help='List all available tasks and exit.')
options = parser.parse_args()
results = analyze_outcome_file(options.outcomes)
if results.error_count > 0:
if options.list:
for task in TASKS:
print(task)
sys.exit(0)
result = True
if options.task == 'all':
tasks = TASKS.keys()
else:
tasks = re.split(r'[, ]+', options.task)
for task in tasks:
if task not in TASKS:
print('Error: invalid task: {}'.format(task))
sys.exit(1)
for task in TASKS:
if task in tasks:
if not TASKS[task]['test_function'](options.outcomes, TASKS[task]['args']):
result = False
if result is False:
sys.exit(1)
print("SUCCESS :-)")
except Exception: # pylint: disable=broad-except
# Print the backtrace and exit explicitly with our chosen status.
traceback.print_exc()

View file

@ -57,7 +57,7 @@ of BaseTarget in test_data_generation.py.
import sys
from abc import ABCMeta
from typing import Iterator, List
from typing import List
import scripts_path # pylint: disable=unused-import
from mbedtls_dev import test_case
@ -66,23 +66,31 @@ from mbedtls_dev import bignum_common
# Import modules containing additional test classes
# Test function classes in these modules will be registered by
# the framework
from mbedtls_dev import bignum_core # pylint: disable=unused-import
from mbedtls_dev import bignum_core, bignum_mod_raw # pylint: disable=unused-import
class BignumTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
#pylint: disable=abstract-method
class BignumTarget(test_data_generation.BaseTarget):
#pylint: disable=too-few-public-methods
"""Target for bignum (legacy) test case generation."""
target_basename = 'test_suite_bignum.generated'
class BignumOperation(bignum_common.OperationCommon, BignumTarget, metaclass=ABCMeta):
class BignumOperation(bignum_common.OperationCommon, BignumTarget,
metaclass=ABCMeta):
#pylint: disable=abstract-method
"""Common features for bignum operations in legacy tests."""
unique_combinations_only = True
input_values = [
"", "0", "7b", "-7b",
"", "0", "-", "-0",
"7b", "-7b",
"0000000000000000123", "-0000000000000000123",
"1230000000000000000", "-1230000000000000000"
]
def description_suffix(self) -> str:
#pylint: disable=no-self-use # derived classes need self
"""Text to add at the end of the test case description."""
return ""
def description(self) -> str:
"""Generate a description for the test case.
@ -96,6 +104,9 @@ class BignumOperation(bignum_common.OperationCommon, BignumTarget, metaclass=ABC
self.symbol,
self.value_description(self.arg_b)
)
description_suffix = self.description_suffix()
if description_suffix:
self.case_description += " " + description_suffix
return super().description()
@staticmethod
@ -107,6 +118,8 @@ class BignumOperation(bignum_common.OperationCommon, BignumTarget, metaclass=ABC
"""
if val == "":
return "0 (null)"
if val == "-":
return "negative 0 (null)"
if val == "0":
return "0 (1 limb)"
@ -121,11 +134,6 @@ class BignumOperation(bignum_common.OperationCommon, BignumTarget, metaclass=ABC
tmp = "large " + tmp
return tmp
@classmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
for a_value, b_value in cls.get_value_pairs():
yield cls(a_value, b_value).create_test_case()
class BignumCmp(BignumOperation):
"""Test cases for bignum value comparison."""
@ -171,9 +179,21 @@ class BignumAdd(BignumOperation):
]
)
def result(self) -> List[str]:
return [bignum_common.quote_str("{:x}").format(self.int_a + self.int_b)]
def __init__(self, val_a: str, val_b: str) -> None:
super().__init__(val_a, val_b)
self._result = self.int_a + self.int_b
def description_suffix(self) -> str:
if (self.int_a >= 0 and self.int_b >= 0):
return "" # obviously positive result or 0
if (self.int_a <= 0 and self.int_b <= 0):
return "" # obviously negative result or 0
# The sign of the result is not obvious, so indicate it
return ", result{}0".format('>' if self._result > 0 else
'<' if self._result < 0 else '=')
def result(self) -> List[str]:
return [bignum_common.quote_str("{:x}".format(self._result))]
if __name__ == '__main__':
# Use the section of the docstring relevant to the CLI as description

View file

@ -50,10 +50,10 @@ GetOptions(
'verbose|v:1' => \$verbose,
) or die;
# All test suites = executable files derived from a .data file.
# All test suites = executable files with a .datax file.
my @suites = ();
for my $data_file (glob 'suites/test_suite_*.data') {
(my $base = $data_file) =~ s#^suites/(.*)\.data$#$1#;
for my $data_file (glob 'test_suite_*.datax') {
(my $base = $data_file) =~ s/\.datax$//;
push @suites, $base if -x $base;
push @suites, "$base.exe" if -e "$base.exe";
}

View file

@ -89,6 +89,10 @@ void mbedtls_test_set_step( unsigned long step )
mbedtls_test_info.step = step;
}
#if defined(MBEDTLS_BIGNUM_C)
unsigned mbedtls_test_case_uses_negative_0 = 0;
#endif
void mbedtls_test_info_reset( void )
{
mbedtls_test_info.result = MBEDTLS_TEST_RESULT_SUCCESS;
@ -98,6 +102,9 @@ void mbedtls_test_info_reset( void )
mbedtls_test_info.filename = 0;
memset( mbedtls_test_info.line1, 0, sizeof( mbedtls_test_info.line1 ) );
memset( mbedtls_test_info.line2, 0, sizeof( mbedtls_test_info.line2 ) );
#if defined(MBEDTLS_BIGNUM_C)
mbedtls_test_case_uses_negative_0 = 0;
#endif
}
int mbedtls_test_equal( const char *test, int line_no, const char* filename,
@ -396,6 +403,15 @@ exit:
int mbedtls_test_read_mpi( mbedtls_mpi *X, const char *s )
{
int negative = 0;
/* Always set the sign bit to -1 if the input has a minus sign, even for 0.
* This creates an invalid representation, which mbedtls_mpi_read_string()
* avoids but we want to be able to create that in test data. */
if( s[0] == '-' )
{
++s;
negative = 1;
}
/* mbedtls_mpi_read_string() currently retains leading zeros.
* It always allocates at least one limb for the value 0. */
if( s[0] == 0 )
@ -403,7 +419,15 @@ int mbedtls_test_read_mpi( mbedtls_mpi *X, const char *s )
mbedtls_mpi_free( X );
return( 0 );
}
else
return( mbedtls_mpi_read_string( X, 16, s ) );
int ret = mbedtls_mpi_read_string( X, 16, s );
if( ret != 0 )
return( ret );
if( negative )
{
if( mbedtls_mpi_cmp_int( X, 0 ) == 0 )
++mbedtls_test_case_uses_negative_0;
X->s = -1;
}
return( 0 );
}
#endif

View file

@ -80,12 +80,14 @@ fi
if [ -n "${OPENSSL_NEXT:-}" ]; then
O_NEXT_SRV="$OPENSSL_NEXT s_server -www -cert data_files/server5.crt -key data_files/server5.key"
O_NEXT_SRV_EARLY_DATA="$OPENSSL_NEXT s_server -early_data -cert data_files/server5.crt -key data_files/server5.key"
O_NEXT_SRV_NO_CERT="$OPENSSL_NEXT s_server -www "
O_NEXT_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_NEXT s_client -CAfile data_files/test-ca_cat12.crt"
O_NEXT_CLI_NO_CERT="echo 'GET / HTTP/1.0' | $OPENSSL_NEXT s_client"
else
O_NEXT_SRV=false
O_NEXT_SRV_NO_CERT=false
O_NEXT_SRV_EARLY_DATA=false
O_NEXT_CLI_NO_CERT=false
O_NEXT_CLI=false
fi
@ -1024,6 +1026,16 @@ is_gnutls() {
esac
}
# Generate random psk_list argument for ssl_server2
get_srv_psk_list ()
{
case $(( TESTS % 3 )) in
0) echo "psk_list=abc,dead,def,beef,Client_identity,6162636465666768696a6b6c6d6e6f70";;
1) echo "psk_list=abc,dead,Client_identity,6162636465666768696a6b6c6d6e6f70,def,beef";;
2) echo "psk_list=Client_identity,6162636465666768696a6b6c6d6e6f70,abc,dead,def,beef";;
esac
}
# Determine what calc_verify trace is to be expected, if any.
#
# calc_verify is only called for two things: to calculate the
@ -1680,6 +1692,7 @@ fi
if [ -n "${OPENSSL_NEXT:-}" ]; then
O_NEXT_SRV="$O_NEXT_SRV -accept $SRV_PORT"
O_NEXT_SRV_NO_CERT="$O_NEXT_SRV_NO_CERT -accept $SRV_PORT"
O_NEXT_SRV_EARLY_DATA="$O_NEXT_SRV_EARLY_DATA -accept $SRV_PORT"
O_NEXT_CLI="$O_NEXT_CLI -connect 127.0.0.1:+SRV_PORT"
O_NEXT_CLI_NO_CERT="$O_NEXT_CLI_NO_CERT -connect 127.0.0.1:+SRV_PORT"
fi
@ -2371,6 +2384,31 @@ run_test "Unique IV in GCM" \
-u "IV used" \
-U "IV used"
# Test for correctness of sent single supported algorithm
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_CLI_C
requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_ECDSA_C
requires_hash_alg SHA_256
run_test "Single supported algorithm sending: mbedtls client" \
"$P_SRV sig_algs=ecdsa_secp256r1_sha256 auth_mode=required" \
"$P_CLI sig_algs=ecdsa_secp256r1_sha256 debug_level=3" \
0 \
-c "Supported Signature Algorithm found: 04 03"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_SSL_SRV_C
requires_config_enabled MBEDTLS_ECDSA_C
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_hash_alg SHA_256
run_test "Single supported algorithm sending: openssl client" \
"$P_SRV sig_algs=ecdsa_secp256r1_sha256 auth_mode=required" \
"$O_CLI -cert data_files/server6.crt \
-key data_files/server6.key" \
0
# Tests for certificate verification callback
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Configuration-specific CRT verification callback" \
@ -5274,8 +5312,8 @@ run_test "Authentication: client SHA256, server required" \
key_file=data_files/server6.key \
force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384" \
0 \
-c "Supported Signature Algorithm found: 4," \
-c "Supported Signature Algorithm found: 5,"
-c "Supported Signature Algorithm found: 04 " \
-c "Supported Signature Algorithm found: 05 "
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
@ -5285,8 +5323,8 @@ run_test "Authentication: client SHA384, server required" \
key_file=data_files/server6.key \
force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" \
0 \
-c "Supported Signature Algorithm found: 4," \
-c "Supported Signature Algorithm found: 5,"
-c "Supported Signature Algorithm found: 04 " \
-c "Supported Signature Algorithm found: 05 "
requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: client has no cert, server required (TLS)" \
@ -5687,8 +5725,8 @@ run_test "Authentication, CA callback: client SHA256, server required" \
force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384" \
0 \
-s "use CA callback for X.509 CRT verification" \
-c "Supported Signature Algorithm found: 4," \
-c "Supported Signature Algorithm found: 5,"
-c "Supported Signature Algorithm found: 04 " \
-c "Supported Signature Algorithm found: 05 "
requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
@ -5700,8 +5738,8 @@ run_test "Authentication, CA callback: client SHA384, server required" \
force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" \
0 \
-s "use CA callback for X.509 CRT verification" \
-c "Supported Signature Algorithm found: 4," \
-c "Supported Signature Algorithm found: 5,"
-c "Supported Signature Algorithm found: 04 " \
-c "Supported Signature Algorithm found: 05 "
requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2

View file

@ -13,10 +13,21 @@
* constructing the value. */
static int sign_is_valid( const mbedtls_mpi *X )
{
/* Only +1 and -1 are valid sign bits, not e.g. 0 */
if( X->s != 1 && X->s != -1 )
return( 0 ); // invalid sign bit, e.g. 0
if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
return( 0 ); // negative zero
return( 0 );
/* The value 0 must be represented with the sign +1. A "negative zero"
* with s=-1 is an invalid representation. Forbid that. As an exception,
* we sometimes test the robustness of library functions when given
* a negative zero input. If a test case has a negative zero as input,
* we don't mind if the function has a negative zero output. */
if( ! mbedtls_test_case_uses_negative_0 &&
mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
{
return( 0 );
}
return( 1 );
}
@ -959,24 +970,57 @@ exit:
/* END_CASE */
/* BEGIN_CASE */
void mpi_mod_int( char * input_X, int input_Y,
int input_A, int div_result )
void mpi_mod_int( char * input_X, char * input_Y,
char * input_A, int mod_result )
{
mbedtls_mpi X;
mbedtls_mpi Y;
mbedtls_mpi A;
int res;
mbedtls_mpi_uint r;
mbedtls_mpi_init( &X );
TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
res = mbedtls_mpi_mod_int( &r, &X, input_Y );
TEST_ASSERT( res == div_result );
mbedtls_mpi_init( &X );
mbedtls_mpi_init( &Y );
mbedtls_mpi_init( &A );
/* We use MPIs to read Y and A since the test framework limits us to
* ints, so we can't have 64-bit values */
TEST_EQUAL( mbedtls_test_read_mpi( &X, input_X ), 0 );
TEST_EQUAL( mbedtls_test_read_mpi( &Y, input_Y ), 0 );
TEST_EQUAL( mbedtls_test_read_mpi( &A, input_A ), 0 );
TEST_EQUAL( Y.n, 1 );
TEST_EQUAL( A.n, 1 );
/* Convert the MPIs for Y and A to (signed) mbedtls_mpi_sints */
/* Since we're converting sign+magnitude to two's complement, we lose one
* bit of value in the output. This means there are some values we can't
* represent, e.g. (hex) -A0000000 on 32-bit systems. These are technically
* invalid test cases, so could be considered "won't happen", but they are
* easy to test for, and this helps guard against human error. */
mbedtls_mpi_sint y = (mbedtls_mpi_sint) Y.p[0];
TEST_ASSERT( y >= 0 ); /* If y < 0 here, we can't make negative y */
if( Y.s == -1 )
y = -y;
mbedtls_mpi_sint a = (mbedtls_mpi_sint) A.p[0];
TEST_ASSERT( a >= 0 ); /* Same goes for a */
if( A.s == -1 )
a = -a;
res = mbedtls_mpi_mod_int( &r, &X, y );
TEST_EQUAL( res, mod_result );
if( res == 0 )
{
TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
TEST_EQUAL( r, a );
}
exit:
mbedtls_mpi_free( &X );
mbedtls_mpi_free( &Y );
mbedtls_mpi_free( &A );
}
/* END_CASE */
@ -1414,6 +1458,150 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE */
void most_negative_mpi_sint( )
{
/* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
* guarantee that mbedtls_mpi_sint is a two's complement type, so this
* is a valid value. However, negating it (`-n`) has undefined behavior
* (although in practice `-n` evaluates to the value n).
*
* This function has ad hoc tests for this value. It's separated from other
* functions because the test framework makes it hard to pass this value
* into test cases.
*
* In the comments here:
* - biL = number of bits in limbs
* - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
* - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
*/
mbedtls_mpi A, R, X;
mbedtls_mpi_init( &A );
mbedtls_mpi_init( &R );
mbedtls_mpi_init( &X );
const size_t biL = 8 * sizeof( mbedtls_mpi_sint );
mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << ( biL - 1 );
const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
const mbedtls_mpi_sint most_negative = - most_positive - 1;
TEST_EQUAL( (mbedtls_mpi_uint) most_negative,
(mbedtls_mpi_uint) 1 << ( biL - 1 ) );
TEST_EQUAL( (mbedtls_mpi_uint) most_negative << 1, 0 );
/* Test mbedtls_mpi_lset() */
TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
TEST_EQUAL( A.s, -1 );
TEST_EQUAL( A.n, 1 );
TEST_EQUAL( A.p[0], most_positive_plus_1 );
/* Test mbedtls_mpi_cmp_int(): -p == -p */
TEST_EQUAL( mbedtls_mpi_cmp_int( &A, most_negative ), 0 );
/* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
A.p[0] = most_positive_plus_1 + 1;
TEST_EQUAL( mbedtls_mpi_cmp_int( &A, most_negative ), -1 );
/* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
A.p[0] = most_positive_plus_1 - 1;
TEST_EQUAL( mbedtls_mpi_cmp_int( &A, most_negative ), 1 );
/* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
TEST_EQUAL( mbedtls_mpi_lset( &A, most_positive ), 0 );
TEST_EQUAL( mbedtls_mpi_add_int( &X, &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &X, -1 ), 0 );
/* Test mbedtls_mpi_add_int(): (0) + (-p) */
TEST_EQUAL( mbedtls_mpi_lset( &A, 0 ), 0 );
TEST_EQUAL( mbedtls_mpi_add_int( &X, &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &X, most_negative ), 0 );
/* Test mbedtls_mpi_add_int(): (-p) + (-p) */
TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_add_int( &X, &A, most_negative ), 0 );
TEST_EQUAL( X.s, -1 );
TEST_EQUAL( X.n, 2 );
TEST_EQUAL( X.p[0], 0 );
TEST_EQUAL( X.p[1], 1 );
/* Test mbedtls_mpi_sub_int(): (p) - (-p) */
mbedtls_mpi_free( &X );
TEST_EQUAL( mbedtls_mpi_lset( &A, most_positive ), 0 );
TEST_EQUAL( mbedtls_mpi_sub_int( &X, &A, most_negative ), 0 );
TEST_EQUAL( X.s, 1 );
TEST_EQUAL( X.n, 1 );
TEST_EQUAL( X.p[0], ~(mbedtls_mpi_uint)0 );
/* Test mbedtls_mpi_sub_int(): (0) - (-p) */
TEST_EQUAL( mbedtls_mpi_lset( &A, 0 ), 0 );
TEST_EQUAL( mbedtls_mpi_sub_int( &X, &A, most_negative ), 0 );
TEST_EQUAL( X.s, 1 );
TEST_EQUAL( X.n, 1 );
TEST_EQUAL( X.p[0], most_positive_plus_1 );
/* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_sub_int( &X, &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 0 ), 0 );
/* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
TEST_EQUAL( mbedtls_mpi_lset( &A, -most_positive ), 0 );
TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 0 ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &R, -most_positive ), 0 );
/* Test mbedtls_mpi_div_int(): (-p) / (-p) */
TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 1 ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
/* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
TEST_EQUAL( mbedtls_mpi_shift_l( &A, 1 ), 0 );
TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 2 ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
/* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
TEST_EQUAL( mbedtls_mpi_add_int( &A, &A, 1 ), 0 );
TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 1 ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &R, -most_positive ), 0 );
/* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
TEST_EQUAL( mbedtls_mpi_lset( &A, most_positive ), 0 );
TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 0 ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &R, most_positive ), 0 );
/* Test mbedtls_mpi_div_int(): (p) / (-p) */
TEST_EQUAL( mbedtls_mpi_add_int( &A, &A, 1 ), 0 );
TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &X, -1 ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
/* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
TEST_EQUAL( mbedtls_mpi_shift_l( &A, 1 ), 0 );
TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &X, -2 ), 0 );
TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
/* Test mbedtls_mpi_mod_int(): never valid */
TEST_EQUAL( mbedtls_mpi_mod_int( X.p, &A, most_negative ),
MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
/* Test mbedtls_mpi_random(): never valid */
TEST_EQUAL( mbedtls_mpi_random( &X, most_negative, &A,
mbedtls_test_rnd_std_rand, NULL ),
MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
exit:
mbedtls_mpi_free( &A );
mbedtls_mpi_free( &R );
mbedtls_mpi_free( &X );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void mpi_selftest( )
{

View file

@ -1144,6 +1144,18 @@ mpi_div_mpi:"":"1":"":"":0
Test mbedtls_mpi_div_mpi: 0 (null) / -1
mpi_div_mpi:"":"-1":"":"":0
Test mbedtls_mpi_div_mpi: -0 (null) / 1
mpi_div_mpi:"-":"1":"":"":0
Test mbedtls_mpi_div_mpi: -0 (null) / -1
mpi_div_mpi:"-":"-1":"":"":0
Test mbedtls_mpi_div_mpi: -0 (null) / 42
mpi_div_mpi:"-":"2a":"":"":0
Test mbedtls_mpi_div_mpi: -0 (null) / -42
mpi_div_mpi:"-":"-2a":"":"":0
Test mbedtls_mpi_div_mpi #1
mpi_div_mpi:"9e22d6da18a33d1ef28d2a82242b3f6e9c9742f63e5d440f58a190bfaf23a7866e67589adb80":"22":"4a6abf75b13dc268ea9cc8b5b6aaf0ac85ecd437a4e0987fb13cf8d2acc57c0306c738c1583":"1a":0
@ -1204,41 +1216,85 @@ mpi_mod_mpi:"":"1":"":0
Test mbedtls_mpi_mod_mpi: 0 (null) % -1
mpi_mod_mpi:"":"-1":"":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
Test mbedtls_mpi_mod_mpi: -0 (null) % 1
mpi_mod_mpi:"-":"1":"":0
Test mbedtls_mpi_mod_mpi: -0 (null) % -1
mpi_mod_mpi:"-":"-1":"":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
Test mbedtls_mpi_mod_mpi: -0 (null) % 42
mpi_mod_mpi:"-":"2a":"":0
Test mbedtls_mpi_mod_mpi: -0 (null) % -42
mpi_mod_mpi:"-":"-2a":"":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
Base test mbedtls_mpi_mod_int #1
mpi_mod_int:"3e8":13:12:0
mpi_mod_int:"3e8":"d":"c":0
Base test mbedtls_mpi_mod_int #2 (Divide by zero)
mpi_mod_int:"3e8":0:0:MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
mpi_mod_int:"3e8":"0":"0":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
Base test mbedtls_mpi_mod_int #3
mpi_mod_int:"-3e8":13:1:0
mpi_mod_int:"-3e8":"d":"1":0
Base test mbedtls_mpi_mod_int #4 (Negative modulo)
mpi_mod_int:"3e8":-13:0:MBEDTLS_ERR_MPI_NEGATIVE_VALUE
mpi_mod_int:"3e8":"-d":"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
Base test mbedtls_mpi_mod_int #5 (Negative modulo)
mpi_mod_int:"-3e8":-13:0:MBEDTLS_ERR_MPI_NEGATIVE_VALUE
mpi_mod_int:"-3e8":"-d":"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
Base test mbedtls_mpi_mod_int #6 (By 1)
mpi_mod_int:"3e8":1:0:0
mpi_mod_int:"3e8":"1":"0":0
Base test mbedtls_mpi_mod_int #7 (By 2)
mpi_mod_int:"3e9":2:1:0
mpi_mod_int:"3e9":"2":"1":0
Base test mbedtls_mpi_mod_int #8 (By 2)
mpi_mod_int:"3e8":2:0:0
mpi_mod_int:"3e8":"2":"0":0
Test mbedtls_mpi_mod_int: 0 (null) % 1
mpi_mod_int:"":1:0:0
mpi_mod_int:"":"1":"0":0
Test mbedtls_mpi_mod_int: 0 (null) % 2
mpi_mod_int:"":2:0:0
mpi_mod_int:"":"2":"0":0
Test mbedtls_mpi_mod_int: 0 (null) % -1
mpi_mod_int:"":-1:0:MBEDTLS_ERR_MPI_NEGATIVE_VALUE
mpi_mod_int:"":"-1":"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
Test mbedtls_mpi_mod_int: 0 (null) % -2
mpi_mod_int:"":-2:0:MBEDTLS_ERR_MPI_NEGATIVE_VALUE
mpi_mod_int:"":"-2":"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
# CURRENTLY FAILS - SEE GITHUB ISSUE #6540
#Test mbedtls_mpi_mod_int: 230772460340063000000100500000300000010 % 5178236083361335880 -> 3386266129388798810
#depends_on:MBEDTLS_HAVE_INT64
#mpi_mod_int:"AD9D28BF6C4E98FDF156BF0980CEE30A":"47DCCA4847DCCA48":"2EFE6F1A7D28035A":0
Test mbedtls_mpi_mod_mpi: 230772460340063000000100500000300000010 % 5178236083361335880 -> 3386266129388798810
mpi_mod_mpi:"AD9D28BF6C4E98FDF156BF0980CEE30A":"47DCCA4847DCCA48":"2EFE6F1A7D28035A":0
# CURRENTLY FAILS - SEE GITHUB ISSUE #6540
#Test mbedtls_mpi_mod_int: 230772460340062999996714233870911201200 % 5178236083361335880 -> 0
#depends_on:MBEDTLS_HAVE_INT64
#mpi_mod_int:"AD9D28BF6C4E98FDC2584FEF03A6DFB0":"47DCCA4847DCCA48":"0":0
Test mbedtls_mpi_mod_mpi: 230772460340062999996714233870911201200 % 5178236083361335880 -> 0
mpi_mod_mpi:"AD9D28BF6C4E98FDC2584FEF03A6DFB0":"47DCCA4847DCCA48":"0":0
# CURRENTLY FAILS WHEN MPIS ARE 32-BIT (ISSUE #6450): WHEN FIXED, REMOVE "depends_on" LINE
Test mbedtls_mpi_mod_int: 230772460340063000000100500000300000010 % 1205652040 -> 3644370
depends_on:MBEDTLS_HAVE_INT64
mpi_mod_int:"AD9D28BF6C4E98FDF156BF0980CEE30A":"47DCCA48":"379BD2":0
Test mbedtls_mpi_mod_mpi: 230772460340063000000100500000300000010 % 1205652040 -> 3644370
mpi_mod_mpi:"AD9D28BF6C4E98FDF156BF0980CEE30A":"47DCCA48":"379BD2":0
# CURRENTLY FAILS WHEN MPIS ARE 32-BIT (ISSUE #6450): WHEN FIXED, REMOVE "depends_on" LINE
Test mbedtls_mpi_mod_int: 230772460340063000000100500000296355640 % 1205652040 -> 0
depends_on:MBEDTLS_HAVE_INT64
mpi_mod_int:"AD9D28BF6C4E98FDF156BF0980974738":"47DCCA48":"0":0
Test mbedtls_mpi_mod_mpi: 230772460340063000000100500000296355640 % 1205652040 -> 0
mpi_mod_mpi:"AD9D28BF6C4E98FDF156BF0980974738":"47DCCA48":"0":0
Base test mbedtls_mpi_exp_mod #1
mpi_exp_mod:"17":"d":"1d":"18":0
@ -1902,6 +1958,9 @@ mpi_random_fail:2:"01":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
MPI random bad arguments: min > N = 1, 0 limb in upper bound
mpi_random_fail:2:"000000000000000001":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Most negative mbedtls_mpi_sint
most_negative_mpi_sint:
MPI Selftest
depends_on:MBEDTLS_SELF_TEST
mpi_selftest:

View file

@ -117,10 +117,12 @@ void mpi_mod_raw_cond_assign( char * input_X,
mbedtls_mpi_uint *X = NULL;
mbedtls_mpi_uint *Y = NULL;
mbedtls_mpi_uint *buff_m = NULL;
mbedtls_mpi_mod_modulus m;
size_t limbs_X;
size_t limbs_Y;
mbedtls_mpi_mod_modulus m;
mbedtls_mpi_mod_modulus_init( &m );
TEST_EQUAL( mbedtls_test_read_mpi_core( &X, &limbs_X, input_X ), 0 );
TEST_EQUAL( mbedtls_test_read_mpi_core( &Y, &limbs_Y, input_Y ), 0 );
@ -129,8 +131,6 @@ void mpi_mod_raw_cond_assign( char * input_X,
size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
mbedtls_mpi_mod_modulus_init( &m );
TEST_EQUAL( limbs_X, limbs_Y );
TEST_ASSERT( copy_limbs <= limbs );
@ -190,10 +190,12 @@ void mpi_mod_raw_cond_swap( char * input_X,
mbedtls_mpi_uint *X = NULL;
mbedtls_mpi_uint *Y = NULL;
mbedtls_mpi_uint *buff_m = NULL;
mbedtls_mpi_mod_modulus m;
size_t limbs_X;
size_t limbs_Y;
mbedtls_mpi_mod_modulus m;
mbedtls_mpi_mod_modulus_init( &m );
TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_X, &limbs_X, input_X ), 0 );
TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_Y, &limbs_Y, input_Y ), 0 );
@ -202,8 +204,6 @@ void mpi_mod_raw_cond_swap( char * input_X,
size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
mbedtls_mpi_mod_modulus_init( &m );
TEST_EQUAL( limbs_X, limbs_Y );
TEST_ASSERT( copy_limbs <= limbs );
@ -294,7 +294,77 @@ exit:
/* END MERGE SLOT 6 */
/* BEGIN MERGE SLOT 7 */
/* BEGIN_CASE */
void mpi_mod_raw_to_mont_rep( char * input_N, char * input_A, char * input_X )
{
mbedtls_mpi_uint *N = NULL;
mbedtls_mpi_uint *A = NULL;
mbedtls_mpi_uint *X = NULL;
size_t n_limbs, a_limbs, x_limbs, x_bytes;
mbedtls_mpi_mod_modulus m;
mbedtls_mpi_mod_modulus_init( &m );
/* Read inputs */
TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &a_limbs, input_A ) );
TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &x_limbs, input_X ) );
x_bytes = x_limbs * sizeof(mbedtls_mpi_uint);
/* Test that input does not require more limbs than modulo */
TEST_LE_U(a_limbs, n_limbs);
TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
MBEDTLS_MPI_MOD_EXT_REP_BE, MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
/* Convert from cannonical into Montgomery representation */
TEST_EQUAL(0, mbedtls_mpi_mod_raw_to_mont_rep( A, &m ) );
/* The result matches expected value */
ASSERT_COMPARE( A, x_bytes, X, x_bytes );
exit:
mbedtls_mpi_mod_modulus_free( &m );
mbedtls_free( N );
mbedtls_free( A );
mbedtls_free( X );
}
/* END_CASE */
/* BEGIN_CASE */
void mpi_mod_raw_from_mont_rep( char * input_N, char * input_A, char * input_X )
{
mbedtls_mpi_uint *N = NULL;
mbedtls_mpi_uint *A = NULL;
mbedtls_mpi_uint *X = NULL;
size_t n_limbs, a_limbs, x_limbs, x_bytes;
mbedtls_mpi_mod_modulus m;
mbedtls_mpi_mod_modulus_init( &m );
/* Read inputs */
TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &a_limbs, input_A ) );
TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &x_limbs, input_X ) );
x_bytes = x_limbs * sizeof(mbedtls_mpi_uint);
/* Test that input does not require more limbs than modulo */
TEST_LE_U(a_limbs, n_limbs);
TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
MBEDTLS_MPI_MOD_EXT_REP_BE, MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
/* Convert from Montgomery into cannonical representation */
TEST_EQUAL(0, mbedtls_mpi_mod_raw_from_mont_rep( A, &m ) );
/* The result matches expected value */
ASSERT_COMPARE( A, x_bytes, X, x_bytes );
exit:
mbedtls_mpi_mod_modulus_free( &m );
mbedtls_free( N );
mbedtls_free( A );
mbedtls_free( X );
}
/* END_CASE */
/* END MERGE SLOT 7 */
/* BEGIN MERGE SLOT 8 */

View file

@ -6549,11 +6549,16 @@ ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_
PSA PAKE: ecjpake rounds
depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PSK_TO_MS
ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":0
ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":0:0
PSA PAKE: ecjpake rounds, client input first
depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PSK_TO_MS
ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":1
ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":1:0
# This test case relies on implementation (it may need to be adjusted in the future)
PSA PAKE: ecjpake rounds - key is destroyed after being passed to set_password_key
depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PSK_TO_MS
ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":0:1
PSA PAKE: ecjpake no input errors
depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256

View file

@ -31,6 +31,27 @@
#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;
@ -8740,7 +8761,6 @@ void ecjpake_setup( int alg_arg, int key_type_pw_arg, int key_usage_pw_arg,
{
psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
psa_pake_operation_t operation = psa_pake_operation_init();
psa_pake_operation_t op_copy = psa_pake_operation_init();
psa_algorithm_t alg = alg_arg;
psa_pake_primitive_t primitive = primitive_arg;
psa_key_type_t key_type_pw = key_type_pw_arg;
@ -8839,22 +8859,25 @@ void ecjpake_setup( int alg_arg, int key_type_pw_arg, int key_usage_pw_arg,
if( input_first )
{
/* Invalid parameters (input) */
op_copy = operation;
TEST_EQUAL( psa_pake_input( &op_copy, PSA_PAKE_STEP_ZK_PROOF,
TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PROOF,
NULL, 0 ),
PSA_ERROR_INVALID_ARGUMENT );
/* Invalid parameters (step) */
op_copy = operation;
TEST_EQUAL( psa_pake_input( &op_copy, PSA_PAKE_STEP_ZK_PROOF + 10,
TEST_EQUAL( ecjpake_operation_setup( &operation, &cipher_suite, role,
key, pw_data->len ) , 0 );
TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PROOF + 10,
output_buffer, size_zk_proof ),
PSA_ERROR_INVALID_ARGUMENT );
/* Invalid first step */
op_copy = operation;
TEST_EQUAL( psa_pake_input( &op_copy, PSA_PAKE_STEP_ZK_PROOF,
TEST_EQUAL( ecjpake_operation_setup( &operation, &cipher_suite, role,
key, pw_data->len ), 0 );
TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PROOF,
output_buffer, size_zk_proof ),
PSA_ERROR_BAD_STATE );
/* Possibly valid */
TEST_EQUAL( ecjpake_operation_setup( &operation, &cipher_suite, role,
key, pw_data->len ), 0 );
TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_KEY_SHARE,
output_buffer, size_key_share ),
expected_status_input_output);
@ -8875,22 +8898,25 @@ void ecjpake_setup( int alg_arg, int key_type_pw_arg, int key_usage_pw_arg,
else
{
/* Invalid parameters (output) */
op_copy = operation;
TEST_EQUAL( psa_pake_output( &op_copy, PSA_PAKE_STEP_ZK_PROOF,
TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PROOF,
NULL, 0, NULL ),
PSA_ERROR_INVALID_ARGUMENT );
op_copy = operation;
/* Invalid parameters (step) */
TEST_EQUAL( psa_pake_output( &op_copy, PSA_PAKE_STEP_ZK_PROOF + 10,
TEST_EQUAL( ecjpake_operation_setup( &operation, &cipher_suite, role,
key, pw_data->len ), 0 );
TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PROOF + 10,
output_buffer, buf_size, &output_len ),
PSA_ERROR_INVALID_ARGUMENT );
/* Invalid first step */
op_copy = operation;
TEST_EQUAL( psa_pake_output( &op_copy, PSA_PAKE_STEP_ZK_PROOF,
TEST_EQUAL( ecjpake_operation_setup( &operation, &cipher_suite, role,
key, pw_data->len ), 0 );
TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PROOF,
output_buffer, buf_size, &output_len ),
PSA_ERROR_BAD_STATE );
/* Possibly valid */
TEST_EQUAL( ecjpake_operation_setup( &operation, &cipher_suite, role,
key, pw_data->len ), 0 );
TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_KEY_SHARE,
output_buffer, buf_size, &output_len ),
expected_status_input_output );
@ -8974,7 +9000,7 @@ exit:
/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */
void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg,
int derive_alg_arg, data_t *pw_data,
int client_input_first )
int client_input_first, int destroy_key )
{
psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
psa_pake_operation_t server = psa_pake_operation_init();
@ -9025,6 +9051,9 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg,
PSA_ASSERT( psa_pake_set_password_key( &server, key ) );
PSA_ASSERT( psa_pake_set_password_key( &client, key ) );
if( destroy_key == 1 )
psa_destroy_key( key );
TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ),
PSA_ERROR_BAD_STATE );
TEST_EQUAL( psa_pake_get_implicit_key( &client, &client_derive ),

View file

@ -1,30 +1,30 @@
Certificate Request check Server1 SHA1
depends_on:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha1":MBEDTLS_MD_SHA1:0:0:0:0
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha1":MBEDTLS_MD_SHA1:0:0:0:0:0
Certificate Request check Server1 SHA224
depends_on:MBEDTLS_HAS_ALG_SHA_224_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha224":MBEDTLS_MD_SHA224:0:0:0:0
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha224":MBEDTLS_MD_SHA224:0:0:0:0:0
Certificate Request check Server1 SHA256
depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha256":MBEDTLS_MD_SHA256:0:0:0:0
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha256":MBEDTLS_MD_SHA256:0:0:0:0:0
Certificate Request check Server1 SHA384
depends_on:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha384":MBEDTLS_MD_SHA384:0:0:0:0
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha384":MBEDTLS_MD_SHA384:0:0:0:0:0
Certificate Request check Server1 SHA512
depends_on:MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha512":MBEDTLS_MD_SHA512:0:0:0:0
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha512":MBEDTLS_MD_SHA512:0:0:0:0:0
Certificate Request check Server1 MD5
depends_on:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.md5":MBEDTLS_MD_MD5:0:0:0:0
x509_csr_check:"data_files/server1.key":"data_files/server1.req.md5":MBEDTLS_MD_MD5:0:0:0:0:0
Certificate Request check Server1 key_usage
depends_on:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.key_usage":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:0:0
x509_csr_check:"data_files/server1.key":"data_files/server1.req.key_usage":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:0:0:0
Certificate Request check opaque Server1 key_usage
depends_on:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
@ -32,23 +32,27 @@ x509_csr_check_opaque:"data_files/server1.key":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_D
Certificate Request check Server1 key_usage empty
depends_on:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.key_usage_empty":MBEDTLS_MD_SHA1:0:1:0:0
x509_csr_check:"data_files/server1.key":"data_files/server1.req.key_usage_empty":MBEDTLS_MD_SHA1:0:1:0:0:0
Certificate Request check Server1 ns_cert_type
depends_on:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.cert_type":MBEDTLS_MD_SHA1:0:0:MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1
x509_csr_check:"data_files/server1.key":"data_files/server1.req.cert_type":MBEDTLS_MD_SHA1:0:0:MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:0
Certificate Request check Server1 ns_cert_type empty
depends_on:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.cert_type_empty":MBEDTLS_MD_SHA1:0:0:0:1
x509_csr_check:"data_files/server1.key":"data_files/server1.req.cert_type_empty":MBEDTLS_MD_SHA1:0:0:0:1:0
Certificate Request check Server1 key_usage + ns_cert_type
depends_on:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.ku-ct":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1
x509_csr_check:"data_files/server1.key":"data_files/server1.req.ku-ct":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:0
Certificate Request check Server5 ECDSA, key_usage
depends_on:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_ECP_DP_SECP256R1_ENABLED
x509_csr_check:"data_files/server5.key":"data_files/server5.req.ku.sha1":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION:1:0:0
x509_csr_check:"data_files/server5.key":"data_files/server5.req.ku.sha1":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION:1:0:0:0
Certificate Request check Server1, set_extension
depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
x509_csr_check:"data_files/server1.key":"data_files/server1.req.sha256.ext":MBEDTLS_MD_SHA256:0:0:0:0:1
Certificate Request check opaque Server5 ECDSA, key_usage
depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED

View file

@ -5,6 +5,7 @@
#include "mbedtls/pem.h"
#include "mbedtls/oid.h"
#include "mbedtls/rsa.h"
#include "mbedtls/asn1write.h"
#include "hash_info.h"
#include "mbedtls/legacy_or_psa.h"
@ -74,6 +75,56 @@ cleanup:
}
#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_PEM_WRITE_C && MBEDTLS_X509_CSR_WRITE_C */
#if defined(MBEDTLS_X509_CSR_WRITE_C)
/*
* The size of this temporary buffer is given by the sequence of functions
* called hereinafter:
* - mbedtls_asn1_write_oid()
* - 8 bytes for MBEDTLS_OID_EXTENDED_KEY_USAGE raw value
* - 1 byte for MBEDTLS_OID_EXTENDED_KEY_USAGE length
* - 1 byte for MBEDTLS_ASN1_OID tag
* - mbedtls_asn1_write_len()
* - 1 byte since we're dealing with sizes which are less than 0x80
* - mbedtls_asn1_write_tag()
* - 1 byte
*
* This length is fine as long as this function is called using the
* MBEDTLS_OID_SERVER_AUTH OID. If this is changed in the future, then this
* buffer's length should be adjusted accordingly.
* Unfortunately there's no predefined max size for OIDs which can be used
* to set an overall upper boundary which is always guaranteed.
*/
#define EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH 12
static int csr_set_extended_key_usage( mbedtls_x509write_csr *ctx,
const char *oid, size_t oid_len )
{
unsigned char buf[EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH] = { 0 };
unsigned char *p = buf + sizeof( buf );
int ret;
size_t len = 0;
/*
* Following functions fail anyway if the temporary buffer is not large,
* but we set an extra check here to emphasize a possible source of errors
*/
if ( oid_len > EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH )
{
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
}
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &p, buf, oid, oid_len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, ret ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_EXTENDED_KEY_USAGE,
MBEDTLS_OID_SIZE( MBEDTLS_OID_EXTENDED_KEY_USAGE ), 0, p, len );
return ret;
}
#endif /* MBEDTLS_X509_CSR_WRITE_C */
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@ -84,7 +135,7 @@ cleanup:
/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CSR_WRITE_C */
void x509_csr_check( char * key_file, char * cert_req_check_file, int md_type,
int key_usage, int set_key_usage, int cert_type,
int set_cert_type )
int set_cert_type, int set_extension )
{
mbedtls_pk_context key;
mbedtls_x509write_csr req;
@ -117,6 +168,9 @@ void x509_csr_check( char * key_file, char * cert_req_check_file, int md_type,
TEST_ASSERT( mbedtls_x509write_csr_set_key_usage( &req, key_usage ) == 0 );
if( set_cert_type != 0 )
TEST_ASSERT( mbedtls_x509write_csr_set_ns_cert_type( &req, cert_type ) == 0 );
if ( set_extension != 0 )
TEST_ASSERT( csr_set_extended_key_usage( &req, MBEDTLS_OID_SERVER_AUTH,
MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH ) ) == 0 );
ret = mbedtls_x509write_csr_pem( &req, buf, sizeof( buf ),
mbedtls_test_rnd_pseudo_rand, &rnd_info );