Skip to content

Commit

Permalink
Merge pull request Mbed-TLS#5521 from AndrzejKurek/rsa-pss-use-psa
Browse files Browse the repository at this point in the history
Make RSA-PSS verification use PSA with MBEDTLS_USE_PSA_CRYPTO
  • Loading branch information
mpg authored Feb 21, 2022
2 parents 436b726 + d70fa0e commit e3a2dd7
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 31 deletions.
97 changes: 81 additions & 16 deletions library/pk.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,22 +347,93 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
if( ! mbedtls_pk_can_do( ctx, type ) )
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );

if( type == MBEDTLS_PK_RSASSA_PSS )
if( type != MBEDTLS_PK_RSASSA_PSS )
{
/* General case: no options */
if( options != NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );

return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
}

#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_pk_rsassa_pss_options *pss_opts;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_pk_rsassa_pss_options *pss_opts;

#if SIZE_MAX > UINT_MAX
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#endif /* SIZE_MAX > UINT_MAX */

if( options == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( options == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );

pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;

pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( pss_opts->mgf1_hash_id == md_alg &&
( (size_t) pss_opts->expected_salt_len == hash_len ||
pss_opts->expected_salt_len == MBEDTLS_RSA_SALT_LEN_ANY ) )
{
/* see RSA_PUB_DER_MAX_BYTES in pkwrite.c */
unsigned char buf[ 38 + 2 * MBEDTLS_MPI_MAX_SIZE ];
unsigned char *p;
int key_len;
size_t signature_length;
psa_status_t status = PSA_ERROR_DATA_CORRUPT;
psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT;

psa_algorithm_t psa_md_alg = mbedtls_psa_translate_md( md_alg );
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t psa_sig_alg =
( pss_opts->expected_salt_len == MBEDTLS_RSA_SALT_LEN_ANY ?
PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg) :
PSA_ALG_RSA_PSS(psa_md_alg) );
p = buf + sizeof( buf );
key_len = mbedtls_pk_write_pubkey( &p, buf, ctx );

if( key_len < 0 )
return( key_len );

psa_set_key_type( &attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY );
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
psa_set_key_algorithm( &attributes, psa_sig_alg );

status = psa_import_key( &attributes,
buf + sizeof( buf ) - key_len, key_len,
&key_id );
if( status != PSA_SUCCESS )
{
psa_destroy_key( key_id );
return( mbedtls_psa_err_translate_pk( status ) );
}

/* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH
* on a valid signature with trailing data in a buffer, but
* mbedtls_psa_rsa_verify_hash requires the sig_len to be exact,
* so for this reason the passed sig_len is overwritten. Smaller
* signature lengths should not be accepted for verification. */
signature_length = sig_len > mbedtls_pk_get_len( ctx ) ?
mbedtls_pk_get_len( ctx ) : sig_len;
status = psa_verify_hash( key_id, psa_sig_alg, hash,
hash_len, sig, signature_length );
destruction_status = psa_destroy_key( key_id );

if( status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len( ctx ) )
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );

if( status == PSA_ERROR_INVALID_SIGNATURE )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED );

if( status == PSA_SUCCESS )
status = destruction_status;

return( mbedtls_psa_err_translate_pk( status ) );
}
else
#endif
{
if( sig_len < mbedtls_pk_get_len( ctx ) )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED );

Expand All @@ -378,16 +449,10 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );

return( 0 );
}
#else
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
}

/* General case: no options */
if( options != NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );

return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
}

/*
Expand Down
Loading

0 comments on commit e3a2dd7

Please sign in to comment.