Add and splice in signature verification through driver
Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
diff --git a/tests/include/drivers/signature.h b/tests/include/drivers/signature.h
index 1607ba5..232ed41 100644
--- a/tests/include/drivers/signature.h
+++ b/tests/include/drivers/signature.h
@@ -37,6 +37,9 @@
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 @@
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 */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 983e121..a3f67be 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1657,7 +1657,7 @@
}
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
diff --git a/tests/src/drivers/signature.c b/tests/src/drivers/signature.c
index 0f006c7..32ebbfd 100644
--- a/tests/src/drivers/signature.c
+++ b/tests/src/drivers/signature.c
@@ -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 @@
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 @@
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 */
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
index fd20b18..2d2c5c4 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
@@ -9,3 +9,21 @@
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
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
index 8c6338c..a954446 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
@@ -25,6 +25,17 @@
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 @@
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 */