Add and splice in signature verification through driver
Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
This commit is contained in:
parent
7a2505788c
commit
55ae2176ab
8 changed files with 352 additions and 19 deletions
|
@ -3754,29 +3754,21 @@ psa_status_t psa_verify_hash( psa_key_handle_t handle,
|
|||
{
|
||||
psa_key_slot_t *slot;
|
||||
psa_status_t status;
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
|
||||
status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY_HASH, alg );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
|
||||
{
|
||||
if( drv->asymmetric == NULL ||
|
||||
drv->asymmetric->p_verify == NULL )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
return( drv->asymmetric->p_verify( drv_context,
|
||||
slot->data.se.slot_number,
|
||||
/* Try any of the available accelerators first */
|
||||
status = psa_driver_wrapper_verify_hash( slot,
|
||||
alg,
|
||||
hash, hash_length,
|
||||
signature, signature_length ) );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
hash,
|
||||
hash_length,
|
||||
signature,
|
||||
signature_length );
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return status;
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
|
||||
{
|
||||
|
|
|
@ -135,4 +135,101 @@ psa_status_t psa_driver_wrapper_sign_hash( psa_key_slot_t *slot,
|
|||
#endif /* MBEDTLS_PSA_CRYPTO_DRIVER_PRESENT */
|
||||
}
|
||||
|
||||
psa_status_t psa_driver_wrapper_verify_hash( psa_key_slot_t *slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length )
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_DRIVER_PRESENT)
|
||||
/* Try dynamically-registered SE interface first */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
|
||||
if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
|
||||
{
|
||||
if( drv->asymmetric == NULL ||
|
||||
drv->asymmetric->p_verify == NULL )
|
||||
{
|
||||
/* Key is defined in SE, but we have no way to exercise it */
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
return( drv->asymmetric->p_verify( drv_context,
|
||||
slot->data.se.slot_number,
|
||||
alg,
|
||||
hash, hash_length,
|
||||
signature, signature_length ) );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
|
||||
/* Then try accelerator API */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime);
|
||||
psa_key_attributes_t attributes = {
|
||||
.core = slot->attr
|
||||
};
|
||||
|
||||
switch( location )
|
||||
{
|
||||
case PSA_KEY_LOCATION_LOCAL_STORAGE:
|
||||
/* Key is stored in the slot in export representation, so
|
||||
* cycle through all known transparent accelerators */
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
status = test_transparent_signature_verify_hash( &attributes,
|
||||
slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
alg,
|
||||
hash,
|
||||
hash_length,
|
||||
signature,
|
||||
signature_length );
|
||||
/* Declared with fallback == true */
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return status;
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
/* Fell through, meaning no accelerator supports this operation */
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
/* Add cases for opaque driver here */
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
case MBEDTLS_PSA_CRYPTO_TEST_DRIVER_LIFETIME:
|
||||
return( test_opaque_signature_verify_hash( &attributes,
|
||||
slot->data.key.data,
|
||||
slot->data.key.bytes,
|
||||
alg,
|
||||
hash,
|
||||
hash_length,
|
||||
signature,
|
||||
signature_length ) );
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
default:
|
||||
/* Key is declared with a lifetime not known to us */
|
||||
return status;
|
||||
}
|
||||
#else /* MBEDTLS_PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
#else /* MBEDTLS_PSA_CRYPTO_DRIVER_PRESENT */
|
||||
(void)slot;
|
||||
(void)alg;
|
||||
(void)hash;
|
||||
(void)hash_length;
|
||||
(void)signature;
|
||||
(void)signature_length;
|
||||
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_DRIVER_PRESENT */
|
||||
}
|
||||
|
||||
psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes,
|
||||
psa_key_slot_t *slot )
|
||||
{
|
||||
(void) attributes;
|
||||
(void) slot;
|
||||
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* End of automatically generated file. */
|
||||
|
|
|
@ -35,6 +35,16 @@ psa_status_t psa_driver_wrapper_sign_hash( psa_key_slot_t *slot,
|
|||
size_t signature_size,
|
||||
size_t *signature_length );
|
||||
|
||||
psa_status_t psa_driver_wrapper_verify_hash( psa_key_slot_t *slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length );
|
||||
|
||||
psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes,
|
||||
psa_key_slot_t *slot );
|
||||
|
||||
#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */
|
||||
|
||||
/* End of automatically generated file. */
|
||||
|
|
|
@ -37,6 +37,9 @@ extern size_t test_driver_forced_output_length;
|
|||
extern psa_status_t test_transparent_signature_sign_hash_status;
|
||||
extern unsigned long test_transparent_signature_sign_hash_hit;
|
||||
|
||||
extern psa_status_t test_transparent_signature_verify_hash_status;
|
||||
extern unsigned long test_transparent_signature_verify_hash_hit;
|
||||
|
||||
psa_status_t test_transparent_signature_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key, size_t key_length,
|
||||
|
@ -51,5 +54,19 @@ psa_status_t test_opaque_signature_sign_hash(
|
|||
const uint8_t *hash, size_t hash_length,
|
||||
uint8_t *signature, size_t signature_size, size_t *signature_length );
|
||||
|
||||
psa_status_t test_transparent_signature_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key, size_t key_length,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash, size_t hash_length,
|
||||
const uint8_t *signature, size_t signature_length );
|
||||
|
||||
psa_status_t test_opaque_signature_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key, size_t key_length,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash, size_t hash_length,
|
||||
const uint8_t *signature, size_t signature_length );
|
||||
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H */
|
||||
|
|
|
@ -1657,7 +1657,7 @@ component_test_se_default () {
|
|||
}
|
||||
|
||||
component_test_psa_crypto_drivers () {
|
||||
msg "build: MBEDTLS_PSA_CRYPTO_DRIVERS, signature"
|
||||
msg "build: MBEDTLS_PSA_CRYPTO_DRIVERS w/ driver hooks"
|
||||
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
|
||||
scripts/config.py set MBEDTLS_TEST_HOOKS
|
||||
# Need to include the test driver header path in order to build
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
|
||||
#include "test/random.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* If non-null, on success, copy this to the output. */
|
||||
|
@ -43,6 +45,9 @@ size_t test_driver_forced_output_length = 0;
|
|||
psa_status_t test_transparent_signature_sign_hash_status = PSA_ERROR_NOT_SUPPORTED;
|
||||
unsigned long test_transparent_signature_sign_hash_hit = 0;
|
||||
|
||||
psa_status_t test_transparent_signature_verify_hash_status = PSA_ERROR_NOT_SUPPORTED;
|
||||
unsigned long test_transparent_signature_verify_hash_hit = 0;
|
||||
|
||||
psa_status_t test_transparent_signature_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key, size_t key_length,
|
||||
|
@ -168,4 +173,129 @@ psa_status_t test_opaque_signature_sign_hash(
|
|||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
psa_status_t test_transparent_signature_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key, size_t key_length,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash, size_t hash_length,
|
||||
const uint8_t *signature, size_t signature_length )
|
||||
{
|
||||
++test_transparent_signature_verify_hash_hit;
|
||||
|
||||
if( test_transparent_signature_verify_hash_status != PSA_SUCCESS )
|
||||
return( test_transparent_signature_verify_hash_status );
|
||||
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
|
||||
defined(MBEDTLS_SHA256_C)
|
||||
if( alg != PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ) )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
mbedtls_ecp_group_id grp_id;
|
||||
switch( psa_get_key_type( attributes ) )
|
||||
{
|
||||
case PSA_ECC_CURVE_SECP_R1:
|
||||
switch( psa_get_key_bits( attributes ) )
|
||||
{
|
||||
case 256:
|
||||
grp_id = MBEDTLS_ECP_DP_SECP256R1;
|
||||
break;
|
||||
case 384:
|
||||
grp_id = MBEDTLS_ECP_DP_SECP384R1;
|
||||
break;
|
||||
case 521:
|
||||
grp_id = MBEDTLS_ECP_DP_SECP521R1;
|
||||
break;
|
||||
default:
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
/* Beyond this point, the driver is actually doing the work of
|
||||
* calculating the signature. */
|
||||
|
||||
status = PSA_ERROR_GENERIC_ERROR;
|
||||
int ret = 0;
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_mpi_init( &r );
|
||||
mbedtls_mpi_init( &s );
|
||||
mbedtls_ecp_keypair ecp;
|
||||
mbedtls_ecp_keypair_init( &ecp );
|
||||
mbedtls_test_rnd_pseudo_info rnd_info;
|
||||
memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
|
||||
size_t curve_bytes = PSA_BITS_TO_BYTES( ecp.grp.pbits );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ecp.grp, grp_id ) );
|
||||
|
||||
/* Code adapted from psa_ecdsa_verify() in psa_crypto.c. */
|
||||
if( signature_length < 2 * curve_bytes )
|
||||
{
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
|
||||
signature,
|
||||
curve_bytes ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
|
||||
signature + curve_bytes,
|
||||
curve_bytes ) );
|
||||
|
||||
if( PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( attributes ) ) )
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &ecp.grp, &ecp.Q,
|
||||
key, key_length ) );
|
||||
else
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ecp.d, key, key_length ) );
|
||||
MBEDTLS_MPI_CHK(
|
||||
mbedtls_ecp_mul( &ecp.grp, &ecp.Q, &ecp.d, &ecp.grp.G,
|
||||
&mbedtls_test_rnd_pseudo_rand,
|
||||
&rnd_info ) );
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecdsa_verify( &ecp.grp, hash, hash_length,
|
||||
&ecp.Q, &r, &s ) );
|
||||
cleanup:
|
||||
/* There's no easy way to translate the error code except through a
|
||||
* library function that's not exported. Use a debugger. */
|
||||
if( ret == 0 )
|
||||
status = PSA_SUCCESS;
|
||||
mbedtls_mpi_free( &r );
|
||||
mbedtls_mpi_free( &s );
|
||||
mbedtls_ecp_keypair_free( &ecp );
|
||||
#else /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
|
||||
defined(MBEDTLS_SHA256_C) */
|
||||
(void) attributes;
|
||||
(void) key;
|
||||
(void) key_length;
|
||||
(void) alg;
|
||||
(void) hash;
|
||||
(void) hash_length;
|
||||
#endif /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
|
||||
defined(MBEDTLS_SHA256_C) */
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
psa_status_t test_opaque_signature_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key, size_t key_length,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash, size_t hash_length,
|
||||
const uint8_t *signature, size_t signature_length )
|
||||
{
|
||||
(void) attributes;
|
||||
(void) key;
|
||||
(void) key_length;
|
||||
(void) alg;
|
||||
(void) hash;
|
||||
(void) hash_length;
|
||||
(void) signature;
|
||||
(void) signature_length;
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && MBEDTLS_TEST_HOOKS */
|
||||
|
|
|
@ -9,3 +9,21 @@ ecdsa_sign:PSA_ERROR_GENERIC_ERROR:0:PSA_ERROR_GENERIC_ERROR
|
|||
|
||||
sign_hash through transparent driver: fake
|
||||
ecdsa_sign:PSA_SUCCESS:1:PSA_SUCCESS
|
||||
|
||||
verify_hash using private key through transparent driver: calculate in driver
|
||||
ecdsa_verify:PSA_SUCCESS:0:PSA_SUCCESS
|
||||
|
||||
verify_hash using private key through transparent driver: fallback
|
||||
ecdsa_verify:PSA_ERROR_NOT_SUPPORTED:0:PSA_SUCCESS
|
||||
|
||||
verify_hash using private key through transparent driver: error
|
||||
ecdsa_verify:PSA_ERROR_GENERIC_ERROR:0:PSA_ERROR_GENERIC_ERROR
|
||||
|
||||
verify_hash using public key through transparent driver: calculate in driver
|
||||
ecdsa_verify:PSA_SUCCESS:1:PSA_SUCCESS
|
||||
|
||||
verify_hash using public key through transparent driver: fallback
|
||||
ecdsa_verify:PSA_ERROR_NOT_SUPPORTED:1:PSA_SUCCESS
|
||||
|
||||
verify_hash through transparent driver: error
|
||||
ecdsa_verify:PSA_ERROR_GENERIC_ERROR:1:PSA_ERROR_GENERIC_ERROR
|
||||
|
|
|
@ -25,6 +25,17 @@ uint8_t test_signature_hash_32_with_secp256r1[64] = {
|
|||
0x3c, 0x24, 0x12, 0x53, 0x4b, 0xb4, 0xa1, 0x9b,
|
||||
0x3a, 0x78, 0x11, 0x74, 0x2f, 0x49, 0xf5, 0x0f,
|
||||
};
|
||||
uint8_t test_secp256r1_public_key_data[65] = {
|
||||
0x04,
|
||||
0xde, 0xa5, 0xe4, 0x5d, 0x0e, 0xa3, 0x7f, 0xc5,
|
||||
0x66, 0x23, 0x2a, 0x50, 0x8f, 0x4a, 0xd2, 0x0e,
|
||||
0xa1, 0x3d, 0x47, 0xe4, 0xbf, 0x5f, 0xa4, 0xd5,
|
||||
0x4a, 0x57, 0xa0, 0xba, 0x01, 0x20, 0x42, 0x08,
|
||||
0x70, 0x97, 0x49, 0x6e, 0xfc, 0x58, 0x3f, 0xed,
|
||||
0x8b, 0x24, 0xa5, 0xb9, 0xbe, 0x9a, 0x51, 0xde,
|
||||
0x06, 0x3f, 0x5a, 0x00, 0xa8, 0xb6, 0x98, 0xa1,
|
||||
0x6f, 0xd7, 0xf2, 0x9b, 0x54, 0x85, 0xf3, 0x20
|
||||
};
|
||||
|
||||
uint8_t test_fake_output[] = "INJECTED OUTPUT";
|
||||
|
||||
|
@ -102,3 +113,61 @@ exit:
|
|||
test_driver_forced_output_length = 0;
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C */
|
||||
void ecdsa_verify( int force_status_arg,
|
||||
int register_public_key,
|
||||
int expected_status_arg )
|
||||
{
|
||||
psa_status_t force_status = force_status_arg;
|
||||
psa_status_t expected_status = expected_status_arg;
|
||||
psa_key_handle_t handle = 0;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t alg = PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 );
|
||||
const uint8_t *expected_output;
|
||||
size_t expected_output_length;
|
||||
psa_status_t actual_status;
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
if( register_public_key )
|
||||
{
|
||||
psa_set_key_type( &attributes,
|
||||
PSA_KEY_TYPE_ECC_PUBLIC_KEY( PSA_ECC_CURVE_SECP_R1 ) );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
|
||||
psa_set_key_algorithm( &attributes, alg );
|
||||
psa_import_key( &attributes,
|
||||
test_secp256r1_public_key_data, sizeof( test_secp256r1_public_key_data ),
|
||||
&handle );
|
||||
}
|
||||
else
|
||||
{
|
||||
psa_set_key_type( &attributes,
|
||||
PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP_R1 ) );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
|
||||
psa_set_key_algorithm( &attributes, alg );
|
||||
psa_import_key( &attributes,
|
||||
test_secp256r1_key_data, sizeof( test_secp256r1_key_data ),
|
||||
&handle );
|
||||
}
|
||||
|
||||
test_transparent_signature_verify_hash_hit = 0;
|
||||
test_transparent_signature_verify_hash_status = force_status;
|
||||
|
||||
expected_output = test_signature_hash_32_with_secp256r1;
|
||||
expected_output_length = sizeof( test_signature_hash_32_with_secp256r1 );
|
||||
|
||||
actual_status = psa_verify_hash( handle, alg,
|
||||
test_hash_32, sizeof( test_hash_32 ),
|
||||
expected_output, expected_output_length );
|
||||
TEST_EQUAL( actual_status, expected_status );
|
||||
TEST_EQUAL( test_transparent_signature_verify_hash_hit, 1 );
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes( &attributes );
|
||||
psa_destroy_key( handle );
|
||||
PSA_DONE( );
|
||||
test_transparent_signature_sign_hash_status = PSA_ERROR_NOT_SUPPORTED;
|
||||
test_driver_forced_output = NULL;
|
||||
test_driver_forced_output_length = 0;
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
Loading…
Reference in a new issue