Skip to content

Commit

Permalink
Merge pull request #5635 from gilles-peskine-arm/psa-test-op-fail
Browse files Browse the repository at this point in the history
PSA: systematically test operation failure
  • Loading branch information
gilles-peskine-arm authored Apr 15, 2022
2 parents 63ed7cb + ebfee6e commit 09dc05b
Show file tree
Hide file tree
Showing 12 changed files with 955 additions and 70 deletions.
4 changes: 4 additions & 0 deletions ChangeLog.d/ccm_star_no_tag.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Bugfix
* Declare or use PSA_WANT_ALG_CCM_STAR_NO_TAG following the general
pattern for PSA_WANT_xxx symbols. Previously you had to specify
PSA_WANT_ALG_CCM for PSA_ALG_CCM_STAR_NO_TAG.
12 changes: 11 additions & 1 deletion include/mbedtls/config_psa.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ extern "C" {
#define PSA_WANT_ALG_ECDSA_ANY PSA_WANT_ALG_ECDSA
#endif

#if defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) && !defined(PSA_WANT_ALG_CCM)
#define PSA_WANT_ALG_CCM PSA_WANT_ALG_CCM_STAR_NO_TAG
#elif !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) && defined(PSA_WANT_ALG_CCM)
#define PSA_WANT_ALG_CCM_STAR_NO_TAG PSA_WANT_ALG_CCM
#endif

#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW) && !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW
#elif !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW) && defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
Expand Down Expand Up @@ -384,7 +390,8 @@ extern "C" {
#endif
#endif /* PSA_WANT_ALG_XTS */

#if defined(PSA_WANT_ALG_ECB_NO_PADDING)
#if defined(PSA_WANT_ALG_ECB_NO_PADDING) && \
!defined(MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING)
#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1
#endif

Expand All @@ -411,6 +418,7 @@ extern "C" {
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
#define MBEDTLS_PSA_BUILTIN_ALG_CCM 1
#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
#define MBEDTLS_CCM_C
#endif
#endif /* PSA_WANT_ALG_CCM */
Expand Down Expand Up @@ -545,7 +553,9 @@ extern "C" {

#if defined(MBEDTLS_CCM_C)
#define MBEDTLS_PSA_BUILTIN_ALG_CCM 1
#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
#define PSA_WANT_ALG_CCM 1
#define PSA_WANT_ALG_CCM_STAR_NO_TAG 1
#endif /* MBEDTLS_CCM_C */

#if defined(MBEDTLS_CMAC_C)
Expand Down
103 changes: 73 additions & 30 deletions library/psa_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -2333,6 +2333,20 @@ static psa_status_t psa_mac_finalize_alg_and_key_validation(
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 );
}

Expand Down Expand Up @@ -5019,50 +5033,75 @@ psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attribut
/****************************************************************/

#if defined(AT_LEAST_ONE_BUILTIN_KDF)
static psa_status_t psa_key_derivation_setup_kdf(
psa_key_derivation_operation_t *operation,
psa_algorithm_t kdf_alg )
static int is_kdf_alg_supported( 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( PSA_ALG_IS_HKDF( kdf_alg ) )
is_kdf_alg_supported = 1;
else
return( 1 );
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
is_kdf_alg_supported = 1;
else
return( 1 );
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
is_kdf_alg_supported = 1;
else
return( 1 );
#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 );
}

if( is_kdf_alg_supported )
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 );

/* 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 );
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 );
return( PSA_ERROR_NOT_SUPPORTED );
}

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 );
}
#endif /* AT_LEAST_ONE_BUILTIN_KDF */
Expand All @@ -5081,6 +5120,10 @@ psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation
{
#if defined(AT_LEAST_ONE_BUILTIN_KDF)
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 );
#else
return( PSA_ERROR_NOT_SUPPORTED );
Expand Down
36 changes: 36 additions & 0 deletions library/psa_crypto_cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,39 +47,61 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
{
switch( alg )
{
#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
case PSA_ALG_STREAM_CIPHER:
mode = MBEDTLS_MODE_STREAM;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
case PSA_ALG_CTR:
mode = MBEDTLS_MODE_CTR;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
case PSA_ALG_CFB:
mode = MBEDTLS_MODE_CFB;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
case PSA_ALG_OFB:
mode = MBEDTLS_MODE_OFB;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
case PSA_ALG_ECB_NO_PADDING:
mode = MBEDTLS_MODE_ECB;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
case PSA_ALG_CBC_NO_PADDING:
mode = MBEDTLS_MODE_CBC;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
case PSA_ALG_CBC_PKCS7:
mode = MBEDTLS_MODE_CBC;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
case PSA_ALG_CCM_STAR_NO_TAG:
mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
mode = MBEDTLS_MODE_CCM;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
mode = MBEDTLS_MODE_GCM;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
mode = MBEDTLS_MODE_CHACHAPOLY;
break;
#endif
default:
return( NULL );
}
Expand All @@ -91,12 +113,17 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(

switch( key_type )
{
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
case PSA_KEY_TYPE_AES:
cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
case PSA_KEY_TYPE_ARIA:
cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
case PSA_KEY_TYPE_DES:
/* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
* and 192 for three-key Triple-DES. */
Expand All @@ -110,12 +137,17 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
if( key_bits == 128 )
key_bits = 192;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
case PSA_KEY_TYPE_CAMELLIA:
cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
break;
#endif
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
case PSA_KEY_TYPE_CHACHA20:
cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
break;
#endif
default:
return( NULL );
}
Expand Down Expand Up @@ -239,6 +271,7 @@ psa_status_t mbedtls_psa_cipher_set_iv(
iv, iv_length ) ) );
}

#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
/** Process input for which the algorithm is set to ECB mode.
*
* This requires manual processing, since the PSA API is defined as being
Expand Down Expand Up @@ -342,6 +375,7 @@ static psa_status_t psa_cipher_update_ecb(
exit:
return( status );
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */

psa_status_t mbedtls_psa_cipher_update(
mbedtls_psa_cipher_operation_t *operation,
Expand Down Expand Up @@ -369,6 +403,7 @@ psa_status_t mbedtls_psa_cipher_update(
if( output_size < expected_output_size )
return( PSA_ERROR_BUFFER_TOO_SMALL );

#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
if( operation->alg == PSA_ALG_ECB_NO_PADDING )
{
/* mbedtls_cipher_update has an API inconsistency: it will only
Expand All @@ -381,6 +416,7 @@ psa_status_t mbedtls_psa_cipher_update(
output_length );
}
else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
{
status = mbedtls_to_psa_error(
mbedtls_cipher_update( &operation->ctx.cipher, input,
Expand Down
Loading

0 comments on commit 09dc05b

Please sign in to comment.