Commit 2529e431 authored by ROOL's avatar ROOL 🤖
Browse files

Library update

Detail:
  Includes fix for CVE-2022-35409.
  This is release 2.28.1 direct from ARM, with customisations to
  * ro_[crypto_]config.h
  * timing.c
  * entropy_poll.c
  * net_sockets.[c|h]
  * platform.h/debug.h (_MSC_VER is unset)
  to port to RISC OS.

Version 2.26. Tagged as 'mbedTLS-2_26'
parent f4f63c0b
...@@ -48,7 +48,7 @@ OBJS_PSA = psa_crypto psa_crypto_aead psa_crypto_cipher psa_crypto_client \ ...@@ -48,7 +48,7 @@ OBJS_PSA = psa_crypto psa_crypto_aead psa_crypto_cipher psa_crypto_client \
psa_crypto_rsa psa_crypto_se psa_crypto_slot_management psa_crypto_storage \ psa_crypto_rsa psa_crypto_se psa_crypto_slot_management psa_crypto_storage \
psa_its_file psa_its_file
OBJS = ${OBJS_X509} ${OBJS_TLS} ${OBJS_CRYPTO} ${OBJS_PSA} OBJS = ${OBJS_X509} ${OBJS_TLS} ${OBJS_CRYPTO} ${OBJS_PSA}
HDRS = ro_config check_config other_mbedtls_hdrs HDRS = ro_config ro_crypto_config check_config other_mbedtls_hdrs
RO_CONFIG = h${SEP}ro_config RO_CONFIG = h${SEP}ro_config
CINCLUDES = ${TCPIPINC} CINCLUDES = ${TCPIPINC}
CDEFINES = -DMBEDTLS_CONFIG_FILE="\"${RO_CONFIG}\"" -DRISCOS CDEFINES = -DMBEDTLS_CONFIG_FILE="\"${RO_CONFIG}\"" -DRISCOS
......
/* (2.25) /* (2.26)
* *
* This file is automatically maintained by srccommit, do not edit manually. * This file is automatically maintained by srccommit, do not edit manually.
* *
*/ */
#define Module_MajorVersion_CMHG 2.25 #define Module_MajorVersion_CMHG 2.26
#define Module_MinorVersion_CMHG #define Module_MinorVersion_CMHG
#define Module_Date_CMHG 20 Dec 2021 #define Module_Date_CMHG 18 Jul 2022
#define Module_MajorVersion "2.25" #define Module_MajorVersion "2.26"
#define Module_Version 225 #define Module_Version 226
#define Module_MinorVersion "" #define Module_MinorVersion ""
#define Module_Date "20 Dec 2021" #define Module_Date "18 Jul 2022"
#define Module_ApplicationDate "20-Dec-21" #define Module_ApplicationDate "18-Jul-22"
#define Module_ComponentName "mbedTLS" #define Module_ComponentName "mbedTLS"
#define Module_FullVersion "2.25" #define Module_FullVersion "2.26"
#define Module_HelpVersion "2.25 (20 Dec 2021)" #define Module_HelpVersion "2.26 (18 Jul 2022)"
#define Module_LibraryVersionInfo "2:25" #define Module_LibraryVersionInfo "2:26"
...@@ -1106,7 +1106,7 @@ typedef unsigned char mbedtls_be128[16]; ...@@ -1106,7 +1106,7 @@ typedef unsigned char mbedtls_be128[16];
* *
* This function multiplies a field element by x in the polynomial field * This function multiplies a field element by x in the polynomial field
* representation. It uses 64-bit word operations to gain speed but compensates * representation. It uses 64-bit word operations to gain speed but compensates
* for machine endianess and hence works correctly on both big and little * for machine endianness and hence works correctly on both big and little
* endian machines. * endian machines.
*/ */
static void mbedtls_gf128mul_x_ble( unsigned char r[16], static void mbedtls_gf128mul_x_ble( unsigned char r[16],
...@@ -1206,7 +1206,7 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, ...@@ -1206,7 +1206,7 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
unsigned char *prev_output = output - 16; unsigned char *prev_output = output - 16;
/* Copy ciphertext bytes from the previous block to our output for each /* Copy ciphertext bytes from the previous block to our output for each
* byte of cyphertext we won't steal. At the same time, copy the * byte of ciphertext we won't steal. At the same time, copy the
* remainder of the input for this final round (since the loop bounds * remainder of the input for this final round (since the loop bounds
* are the same). */ * are the same). */
for( i = 0; i < leftover; i++ ) for( i = 0; i < leftover; i++ )
......
...@@ -133,6 +133,11 @@ int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedt ...@@ -133,6 +133,11 @@ int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedt
// //
len = mbedtls_mpi_size( X ); len = mbedtls_mpi_size( X );
/* DER represents 0 with a sign bit (0=nonnegative) and 7 value bits, not
* as 0 digits. We need to end up with 020100, not with 0200. */
if( len == 0 )
len = 1;
if( *p < start || (size_t)( *p - start ) < len ) if( *p < start || (size_t)( *p - start ) < len )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
...@@ -472,7 +477,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( ...@@ -472,7 +477,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
cur->val.len = val_len; cur->val.len = val_len;
} }
if( val != NULL ) if( val != NULL && val_len != 0 )
memcpy( cur->val.p, val, val_len ); memcpy( cur->val.p, val, val_len );
return( cur ); return( cur );
......
...@@ -1829,7 +1829,7 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_ ...@@ -1829,7 +1829,7 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_
/* /*
* handle trivial cases * handle trivial cases
*/ */
if( b == 1 ) if( b == 1 || A->n == 0 )
{ {
*r = 0; *r = 0;
return( 0 ); return( 0 );
...@@ -2317,7 +2317,7 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B ...@@ -2317,7 +2317,7 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
* TA-TB is even so the division by 2 has an integer result. * TA-TB is even so the division by 2 has an integer result.
* Invariant (I) is preserved since any odd divisor of both TA and TB * Invariant (I) is preserved since any odd divisor of both TA and TB
* also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2 * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
* also divides TB, and any odd divisior of both TB and |TA-TB|/2 also * also divides TB, and any odd divisor of both TB and |TA-TB|/2 also
* divides TA. * divides TA.
*/ */
if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 ) if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
......
...@@ -386,6 +386,12 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, ...@@ -386,6 +386,12 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CHACHA20_C) #if defined(MBEDTLS_CHACHA20_C)
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
{ {
/* Even though the actual_iv_size is overwritten with a correct value
* of 12 from the cipher info, return an error to indicate that
* the input iv_len is wrong. */
if( iv_len != 12 )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx, if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
iv, iv,
0U ) ) /* Initial counter value */ 0U ) ) /* Initial counter value */
...@@ -393,6 +399,11 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, ...@@ -393,6 +399,11 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
} }
} }
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 &&
iv_len != 12 )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#endif
#endif #endif
if ( actual_iv_size != 0 ) if ( actual_iv_size != 0 )
......
...@@ -489,6 +489,12 @@ int mbedtls_ct_hmac( mbedtls_md_context_t *ctx, ...@@ -489,6 +489,12 @@ int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) ); MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) ); MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
/* Fill the hash buffer in advance with something that is
* not a valid hash (barring an attack on the hash and
* deliberately-crafted input), in case the caller doesn't
* check the return status properly. */
memset( output, '!', hash_size );
/* For each possible length, compute the hash up to that point */ /* For each possible length, compute the hash up to that point */
for( offset = min_data_len; offset <= max_data_len; offset++ ) for( offset = min_data_len; offset <= max_data_len; offset++ )
{ {
...@@ -533,6 +539,13 @@ cleanup: ...@@ -533,6 +539,13 @@ cleanup:
* about whether the assignment was made or not. * about whether the assignment was made or not.
* (Leaking information about the respective sizes of X and Y is ok however.) * (Leaking information about the respective sizes of X and Y is ok however.)
*/ */
#if defined(_MSC_VER) && defined(_M_ARM64) && (_MSC_FULL_VER < 193131103)
/*
* MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:
* https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989
*/
__declspec(noinline)
#endif
int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X,
const mbedtls_mpi *Y, const mbedtls_mpi *Y,
unsigned char assign ) unsigned char assign )
...@@ -562,7 +575,7 @@ cleanup: ...@@ -562,7 +575,7 @@ cleanup:
/* /*
* Conditionally swap X and Y, without leaking information * Conditionally swap X and Y, without leaking information
* about whether the swap was made or not. * about whether the swap was made or not.
* Here it is not ok to simply swap the pointers, which whould lead to * Here it is not ok to simply swap the pointers, which would lead to
* different memory access patterns when X and Y are used afterwards. * different memory access patterns when X and Y are used afterwards.
*/ */
int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X,
......
...@@ -828,7 +828,7 @@ static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, ...@@ -828,7 +828,7 @@ static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
return( 1 ); \ return( 1 ); \
} }
#define SELF_TEST_OUPUT_DISCARD_LENGTH 64 #define SELF_TEST_OUTPUT_DISCARD_LENGTH 64
/* /*
* Checkup routine * Checkup routine
...@@ -854,7 +854,7 @@ int mbedtls_ctr_drbg_self_test( int verbose ) ...@@ -854,7 +854,7 @@ int mbedtls_ctr_drbg_self_test( int verbose )
(void *) entropy_source_pr, (void *) entropy_source_pr,
pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE ) ); pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_pr ) ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_pr ) ) );
CHK( memcmp( buf, result_pr, sizeof( result_pr ) ) ); CHK( memcmp( buf, result_pr, sizeof( result_pr ) ) );
...@@ -879,7 +879,7 @@ int mbedtls_ctr_drbg_self_test( int verbose ) ...@@ -879,7 +879,7 @@ int mbedtls_ctr_drbg_self_test( int verbose )
(void *) entropy_source_nopr, (void *) entropy_source_nopr,
pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE ) ); pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) ); CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_nopr ) ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_nopr ) ) );
CHK( memcmp( buf, result_nopr, sizeof( result_nopr ) ) ); CHK( memcmp( buf, result_nopr, sizeof( result_nopr ) ) );
......
...@@ -399,7 +399,7 @@ static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx, ...@@ -399,7 +399,7 @@ static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx,
} }
/* /*
* Read the ServerKeyExhange parameters (RFC 4492) * Read the ServerKeyExchange parameters (RFC 4492)
* struct { * struct {
* ECParameters curve_params; * ECParameters curve_params;
* ECPoint public; * ECPoint public;
......
...@@ -435,7 +435,7 @@ cleanup: ...@@ -435,7 +435,7 @@ cleanup:
/* /*
* Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
* Ouputs: verified peer public keys Xa, Xb * Outputs: verified peer public keys Xa, Xb
*/ */
static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info, static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
const mbedtls_ecp_group *grp, const mbedtls_ecp_group *grp,
......
...@@ -1307,7 +1307,7 @@ cleanup: ...@@ -1307,7 +1307,7 @@ cleanup:
* For curves in short Weierstrass form, we do all the internal operations in * For curves in short Weierstrass form, we do all the internal operations in
* Jacobian coordinates. * Jacobian coordinates.
* *
* For multiplication, we'll use a comb method with coutermeasueres against * For multiplication, we'll use a comb method with countermeasures against
* SPA, hence timing attacks. * SPA, hence timing attacks.
*/ */
...@@ -2251,7 +2251,7 @@ static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp, ...@@ -2251,7 +2251,7 @@ static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp,
* This function is mainly responsible for administrative work: * This function is mainly responsible for administrative work:
* - managing the restart context if enabled * - managing the restart context if enabled
* - managing the table of precomputed points (passed between the below two * - managing the table of precomputed points (passed between the below two
* functions): allocation, computation, ownership tranfer, freeing. * functions): allocation, computation, ownership transfer, freeing.
* *
* It delegates the actual arithmetic work to: * It delegates the actual arithmetic work to:
* ecp_precompute_comb() and ecp_mul_comb_with_precomp() * ecp_precompute_comb() and ecp_mul_comb_with_precomp()
...@@ -2422,7 +2422,7 @@ cleanup: ...@@ -2422,7 +2422,7 @@ cleanup:
/* /*
* For Montgomery curves, we do all the internal arithmetic in projective * For Montgomery curves, we do all the internal arithmetic in projective
* coordinates. Import/export of points uses only the x coordinates, which is * coordinates. Import/export of points uses only the x coordinates, which is
* internaly represented as X / Z. * internally represented as X / Z.
* *
* For scalar multiplication, we'll use a Montgomery ladder. * For scalar multiplication, we'll use a Montgomery ladder.
*/ */
...@@ -2592,7 +2592,7 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, ...@@ -2592,7 +2592,7 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) );
mbedtls_mpi_free( &R->Y ); mbedtls_mpi_free( &R->Y );
/* RP.X might be sligtly larger than P, so reduce it */ /* RP.X might be slightly larger than P, so reduce it */
MOD_ADD( RP.X ); MOD_ADD( RP.X );
/* Randomize coordinates of the starting point */ /* Randomize coordinates of the starting point */
......
...@@ -755,6 +755,8 @@ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ) ...@@ -755,6 +755,8 @@ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
ECP_VALIDATE_RET( grp != NULL ); ECP_VALIDATE_RET( grp != NULL );
mbedtls_ecp_group_free( grp ); mbedtls_ecp_group_free( grp );
mbedtls_ecp_group_init( grp );
grp->id = id; grp->id = id;
switch( id ) switch( id )
......
...@@ -555,8 +555,8 @@ static void *buffer_alloc_calloc_mutexed( size_t n, size_t size ) ...@@ -555,8 +555,8 @@ static void *buffer_alloc_calloc_mutexed( size_t n, size_t size )
static void buffer_alloc_free_mutexed( void *ptr ) static void buffer_alloc_free_mutexed( void *ptr )
{ {
/* We have to good option here, but corrupting the heap seems /* We have no good option here, but corrupting the heap seems
* worse than loosing memory. */ * worse than losing memory. */
if( mbedtls_mutex_lock( &heap.mutex ) ) if( mbedtls_mutex_lock( &heap.mutex ) )
return; return;
buffer_alloc_free( ptr ); buffer_alloc_free( ptr );
......
...@@ -474,7 +474,7 @@ static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *g ...@@ -474,7 +474,7 @@ static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *g
} }
/* /*
* grp may already be initilialized; if so, make sure IDs match * grp may already be initialized; if so, make sure IDs match
*/ */
if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id ) if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id )
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
...@@ -807,7 +807,7 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, ...@@ -807,7 +807,7 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
goto cleanup; goto cleanup;
#else #else
/* Verify existance of the CRT params */ /* Verify existence of the CRT params */
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ) ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 )
...@@ -1463,10 +1463,16 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, ...@@ -1463,10 +1463,16 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
{ {
p = pem.buf; p = pem.buf;
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
{
mbedtls_pem_free( &pem );
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
}
if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
{
mbedtls_pem_free( &pem );
return( ret ); return( ret );
}
if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 ) if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 )
mbedtls_pk_free( ctx ); mbedtls_pk_free( ctx );
......
...@@ -987,7 +987,7 @@ static psa_status_t psa_get_and_lock_key_slot_with_policy( ...@@ -987,7 +987,7 @@ static psa_status_t psa_get_and_lock_key_slot_with_policy(
goto error; goto error;
} }
/* Enforce that the usage policy permits the requested algortihm. */ /* Enforce that the usage policy permits the requested algorithm. */
if( alg != 0 ) if( alg != 0 )
{ {
status = psa_key_policy_permits( &slot->attr.policy, status = psa_key_policy_permits( &slot->attr.policy,
...@@ -2371,6 +2371,20 @@ static psa_status_t psa_mac_finalize_alg_and_key_validation( ...@@ -2371,6 +2371,20 @@ static psa_status_t psa_mac_finalize_alg_and_key_validation(
return( PSA_ERROR_INVALID_ARGUMENT ); return( PSA_ERROR_INVALID_ARGUMENT );
} }
if( *mac_size > PSA_MAC_MAX_SIZE )
{
/* PSA_MAC_LENGTH returns the correct length even for a MAC algorithm
* that is disabled in the compile-time configuration. The result can
* therefore be larger than PSA_MAC_MAX_SIZE, which does take the
* configuration into account. In this case, force a return of
* PSA_ERROR_NOT_SUPPORTED here. Otherwise psa_mac_verify(), or
* psa_mac_compute(mac_size=PSA_MAC_MAX_SIZE), would return
* PSA_ERROR_BUFFER_TOO_SMALL for an unsupported algorithm whose MAC size
* is larger than PSA_MAC_MAX_SIZE, which is misleading and which breaks
* systematically generated tests. */
return( PSA_ERROR_NOT_SUPPORTED );
}
return( PSA_SUCCESS ); return( PSA_SUCCESS );
} }
...@@ -3345,6 +3359,8 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, ...@@ -3345,6 +3359,8 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
operation->iv_set = 0; operation->iv_set = 0;
if( alg == PSA_ALG_ECB_NO_PADDING ) if( alg == PSA_ALG_ECB_NO_PADDING )
operation->iv_required = 0; operation->iv_required = 0;
else if( slot->attr.type == PSA_KEY_TYPE_ARC4 )
operation->iv_required = 0;
else else
operation->iv_required = 1; operation->iv_required = 1;
operation->default_iv_length = PSA_CIPHER_IV_LENGTH( slot->attr.type, alg ); operation->default_iv_length = PSA_CIPHER_IV_LENGTH( slot->attr.type, alg );
...@@ -4353,50 +4369,75 @@ psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attribut ...@@ -4353,50 +4369,75 @@ psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attribut
/****************************************************************/ /****************************************************************/
#if defined(AT_LEAST_ONE_BUILTIN_KDF) #if defined(AT_LEAST_ONE_BUILTIN_KDF)
static psa_status_t psa_key_derivation_setup_kdf( static int is_kdf_alg_supported( psa_algorithm_t kdf_alg )
psa_key_derivation_operation_t *operation,
psa_algorithm_t kdf_alg )
{ {
int is_kdf_alg_supported;
/* Make sure that operation->ctx is properly zero-initialised. (Macro
* initialisers for this union leave some bytes unspecified.) */
memset( &operation->ctx, 0, sizeof( operation->ctx ) );
/* Make sure that kdf_alg is a supported key derivation algorithm. */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
if( PSA_ALG_IS_HKDF( kdf_alg ) ) if( PSA_ALG_IS_HKDF( kdf_alg ) )
is_kdf_alg_supported = 1; return( 1 );
else
#endif #endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ) if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
is_kdf_alg_supported = 1; return( 1 );
else
#endif #endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
is_kdf_alg_supported = 1; return( 1 );
else
#endif #endif
is_kdf_alg_supported = 0; return( 0 );
}
static psa_status_t psa_hash_try_support( psa_algorithm_t alg )
{
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
psa_status_t status = psa_hash_setup( &operation, alg );
psa_hash_abort( &operation );
return( status );
}
static psa_status_t psa_key_derivation_setup_kdf(
psa_key_derivation_operation_t *operation,
psa_algorithm_t kdf_alg )
{
/* Make sure that operation->ctx is properly zero-initialised. (Macro
* initialisers for this union leave some bytes unspecified.) */
memset( &operation->ctx, 0, sizeof( operation->ctx ) );
/* Make sure that kdf_alg is a supported key derivation algorithm. */
if( ! is_kdf_alg_supported( kdf_alg ) )
return( PSA_ERROR_NOT_SUPPORTED );
/* All currently supported key derivation algorithms are based on a
* hash algorithm. */
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
size_t hash_size = PSA_HASH_LENGTH( hash_alg );
if( hash_size == 0 )
return( PSA_ERROR_NOT_SUPPORTED );
if( is_kdf_alg_supported ) /* Make sure that hash_alg is a supported hash algorithm. Otherwise
* we might fail later, which is somewhat unfriendly and potentially
* risk-prone. */
psa_status_t status = psa_hash_try_support( hash_alg );
if( status != PSA_SUCCESS )
return( status );
if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) &&
! ( hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384 ) )
{ {
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg ); return( PSA_ERROR_NOT_SUPPORTED );
size_t hash_size = PSA_HASH_LENGTH( hash_alg );
if( hash_size == 0 )
return( PSA_ERROR_NOT_SUPPORTED );
if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) &&
! ( hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384 ) )
{
return( PSA_ERROR_NOT_SUPPORTED );
}
operation->capacity = 255 * hash_size;
return( PSA_SUCCESS );
} }
operation->capacity = 255 * hash_size;
return( PSA_SUCCESS );
}
static psa_status_t psa_key_agreement_try_support( psa_algorithm_t alg )
{
#if defined(PSA_WANT_ALG_ECDH)
if( alg == PSA_ALG_ECDH )
return( PSA_SUCCESS );
#endif
(void) alg;
return( PSA_ERROR_NOT_SUPPORTED ); return( PSA_ERROR_NOT_SUPPORTED );
} }
#endif /* AT_LEAST_ONE_BUILTIN_KDF */ #endif /* AT_LEAST_ONE_BUILTIN_KDF */
...@@ -4415,6 +4456,10 @@ psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation ...@@ -4415,6 +4456,10 @@ psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation
{ {
#if defined(AT_LEAST_ONE_BUILTIN_KDF) #if defined(AT_LEAST_ONE_BUILTIN_KDF)
psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ); psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( alg );
status = psa_key_agreement_try_support( ka_alg );
if( status != PSA_SUCCESS )
return( status );
status = psa_key_derivation_setup_kdf( operation, kdf_alg ); status = psa_key_derivation_setup_kdf( operation, kdf_alg );
#else #else
return( PSA_ERROR_NOT_SUPPORTED ); return( PSA_ERROR_NOT_SUPPORTED );
...@@ -4974,6 +5019,22 @@ psa_status_t psa_raw_key_agreement( psa_algorithm_t alg, ...@@ -4974,6 +5019,22 @@ psa_status_t psa_raw_key_agreement( psa_algorithm_t alg,
if( status != PSA_SUCCESS ) if( status != PSA_SUCCESS )
goto exit; goto exit;