/* BEGIN_HEADER */ #include "test/psa_crypto_helpers.h" #include "test/drivers/test_driver.h" /* END_HEADER */ /* BEGIN_DEPENDENCIES * depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_CRYPTO_DRIVERS:PSA_CRYPTO_DRIVER_TEST * END_DEPENDENCIES */ /* BEGIN_CASE depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C */ void ecdsa_sign( int force_status_arg, data_t *key_input, data_t *data_input, data_t *expected_output, int fake_output, 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 ); uint8_t signature[64]; size_t signature_length = 0xdeadbeef; psa_status_t actual_status; test_driver_signature_sign_hooks = test_driver_signature_hooks_init(); PSA_ASSERT( psa_crypto_init( ) ); 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_SIGN_HASH ); psa_set_key_algorithm( &attributes, alg ); psa_import_key( &attributes, key_input->x, key_input->len, &handle ); test_driver_signature_sign_hooks.forced_status = force_status; if( fake_output == 1 ) { test_driver_signature_sign_hooks.forced_output = expected_output->x; test_driver_signature_sign_hooks.forced_output_length = expected_output->len; } actual_status = psa_sign_hash( handle, alg, data_input->x, data_input->len, signature, sizeof( signature ), &signature_length ); TEST_EQUAL( actual_status, expected_status ); if( expected_status == PSA_SUCCESS ) { ASSERT_COMPARE( signature, signature_length, expected_output->x, expected_output->len ); } TEST_EQUAL( test_driver_signature_sign_hooks.hits, 1 ); exit: psa_reset_key_attributes( &attributes ); psa_destroy_key( handle ); PSA_DONE( ); test_driver_signature_sign_hooks = test_driver_signature_hooks_init(); } /* 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, data_t *key_input, data_t *data_input, data_t *signature_input, 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 ); psa_status_t actual_status; test_driver_signature_verify_hooks = test_driver_signature_hooks_init(); 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, key_input->x, key_input->len, &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, key_input->x, key_input->len, &handle ); } test_driver_signature_verify_hooks.forced_status = force_status; actual_status = psa_verify_hash( handle, alg, data_input->x, data_input->len, signature_input->x, signature_input->len ); TEST_EQUAL( actual_status, expected_status ); TEST_EQUAL( test_driver_signature_verify_hooks.hits, 1 ); exit: psa_reset_key_attributes( &attributes ); psa_destroy_key( handle ); PSA_DONE( ); test_driver_signature_verify_hooks = test_driver_signature_hooks_init(); } /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED */ void generate_key( int force_status_arg, data_t *fake_output, 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_ECDSA( PSA_ALG_SHA_256 ); const uint8_t *expected_output = NULL; size_t expected_output_length = 0; psa_status_t actual_status; uint8_t actual_output[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(256)] = {0}; size_t actual_output_length; test_driver_keygen_hooks = test_driver_keygen_hooks_init(); psa_set_key_type( &attributes, PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP_R1 ) ); psa_set_key_bits( &attributes, 256 ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT ); psa_set_key_algorithm( &attributes, alg ); if( fake_output->len > 0 ) { expected_output = test_driver_keygen_hooks.forced_output = fake_output->x; expected_output_length = test_driver_keygen_hooks.forced_output_length = fake_output->len; } test_driver_keygen_hooks.hits = 0; test_driver_keygen_hooks.forced_status = force_status; PSA_ASSERT( psa_crypto_init( ) ); actual_status = psa_generate_key( &attributes, &handle ); TEST_EQUAL( test_driver_keygen_hooks.hits, 1 ); TEST_EQUAL( actual_status, expected_status ); if( actual_status == PSA_SUCCESS ) { psa_export_key( handle, actual_output, sizeof(actual_output), &actual_output_length ); if( fake_output->len > 0 ) { ASSERT_COMPARE( actual_output, actual_output_length, expected_output, expected_output_length ); } else { size_t zeroes = 0; for( size_t i = 0; i < sizeof(actual_output); i++ ) { if( actual_output[i] == 0) zeroes++; } TEST_ASSERT( zeroes != sizeof(actual_output) ); } } exit: psa_reset_key_attributes( &attributes ); psa_destroy_key( handle ); PSA_DONE( ); test_driver_keygen_hooks = test_driver_keygen_hooks_init(); } /* END_CASE */ /* BEGIN_CASE */ void cipher_encrypt( int alg_arg, int key_type_arg, data_t *key, data_t *iv, data_t *input, data_t *expected_output, int expected_status_arg ) { psa_key_handle_t handle = 0; psa_status_t status; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; unsigned char *output = NULL; size_t output_buffer_size = 0; size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; test_driver_cipher_hooks = test_driver_cipher_hooks_init(); PSA_ASSERT( psa_crypto_init( ) ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT ); psa_set_key_algorithm( &attributes, alg ); psa_set_key_type( &attributes, key_type ); PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) ); PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; output_buffer_size = ( (size_t) input->len + PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) ); ASSERT_ALLOC( output, output_buffer_size ); PSA_ASSERT( psa_cipher_update( &operation, input->x, input->len, output, output_buffer_size, &function_output_length ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; total_output_length += function_output_length; status = psa_cipher_finish( &operation, output + total_output_length, output_buffer_size - total_output_length, &function_output_length ); /* Finish will have called abort as well, so expecting two hits here */ TEST_EQUAL( test_driver_cipher_hooks.hits, 2 ); test_driver_cipher_hooks.hits = 0; total_output_length += function_output_length; TEST_EQUAL( status, expected_status ); if( expected_status == PSA_SUCCESS ) { PSA_ASSERT( psa_cipher_abort( &operation ) ); // driver function should've been called as part of the finish() core routine TEST_EQUAL( test_driver_cipher_hooks.hits, 0 ); ASSERT_COMPARE( expected_output->x, expected_output->len, output, total_output_length ); } exit: psa_cipher_abort( &operation ); mbedtls_free( output ); psa_destroy_key( handle ); PSA_DONE( ); test_driver_cipher_hooks = test_driver_cipher_hooks_init(); } /* END_CASE */ /* BEGIN_CASE */ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, data_t *key, data_t *iv, data_t *input, int first_part_size_arg, int output1_length_arg, int output2_length_arg, data_t *expected_output ) { psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; size_t first_part_size = first_part_size_arg; size_t output1_length = output1_length_arg; size_t output2_length = output2_length_arg; unsigned char *output = NULL; size_t output_buffer_size = 0; size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; test_driver_cipher_hooks = test_driver_cipher_hooks_init(); PSA_ASSERT( psa_crypto_init( ) ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT ); psa_set_key_algorithm( &attributes, alg ); psa_set_key_type( &attributes, key_type ); PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) ); PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; output_buffer_size = ( (size_t) input->len + PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) ); ASSERT_ALLOC( output, output_buffer_size ); TEST_ASSERT( first_part_size <= input->len ); PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size, output, output_buffer_size, &function_output_length ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; TEST_ASSERT( function_output_length == output1_length ); total_output_length += function_output_length; PSA_ASSERT( psa_cipher_update( &operation, input->x + first_part_size, input->len - first_part_size, output + total_output_length, output_buffer_size - total_output_length, &function_output_length ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; TEST_ASSERT( function_output_length == output2_length ); total_output_length += function_output_length; PSA_ASSERT( psa_cipher_finish( &operation, output + total_output_length, output_buffer_size - total_output_length, &function_output_length ) ); /* Finish will have called abort as well, so expecting two hits here */ TEST_EQUAL( test_driver_cipher_hooks.hits, 2 ); test_driver_cipher_hooks.hits = 0 ; total_output_length += function_output_length; PSA_ASSERT( psa_cipher_abort( &operation ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 0 ); ASSERT_COMPARE( expected_output->x, expected_output->len, output, total_output_length ); exit: psa_cipher_abort( &operation ); mbedtls_free( output ); psa_destroy_key( handle ); PSA_DONE( ); test_driver_cipher_hooks = test_driver_cipher_hooks_init(); } /* END_CASE */ /* BEGIN_CASE */ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, data_t *key, data_t *iv, data_t *input, int first_part_size_arg, int output1_length_arg, int output2_length_arg, data_t *expected_output ) { psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; size_t first_part_size = first_part_size_arg; size_t output1_length = output1_length_arg; size_t output2_length = output2_length_arg; unsigned char *output = NULL; size_t output_buffer_size = 0; size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; test_driver_cipher_hooks = test_driver_cipher_hooks_init(); PSA_ASSERT( psa_crypto_init( ) ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT ); psa_set_key_algorithm( &attributes, alg ); psa_set_key_type( &attributes, key_type ); PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) ); PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; output_buffer_size = ( (size_t) input->len + PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) ); ASSERT_ALLOC( output, output_buffer_size ); TEST_ASSERT( first_part_size <= input->len ); PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size, output, output_buffer_size, &function_output_length ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; TEST_ASSERT( function_output_length == output1_length ); total_output_length += function_output_length; PSA_ASSERT( psa_cipher_update( &operation, input->x + first_part_size, input->len - first_part_size, output + total_output_length, output_buffer_size - total_output_length, &function_output_length ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; TEST_ASSERT( function_output_length == output2_length ); total_output_length += function_output_length; PSA_ASSERT( psa_cipher_finish( &operation, output + total_output_length, output_buffer_size - total_output_length, &function_output_length ) ); /* Finish will have called abort as well, so expecting two hits here */ TEST_EQUAL( test_driver_cipher_hooks.hits, 2 ); test_driver_cipher_hooks.hits = 0; total_output_length += function_output_length; PSA_ASSERT( psa_cipher_abort( &operation ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 0 ); ASSERT_COMPARE( expected_output->x, expected_output->len, output, total_output_length ); exit: psa_cipher_abort( &operation ); mbedtls_free( output ); psa_destroy_key( handle ); PSA_DONE( ); test_driver_cipher_hooks = test_driver_cipher_hooks_init(); } /* END_CASE */ /* BEGIN_CASE */ void cipher_decrypt( int alg_arg, int key_type_arg, data_t *key, data_t *iv, data_t *input, data_t *expected_output, int expected_status_arg ) { psa_key_handle_t handle = 0; psa_status_t status; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; unsigned char *output = NULL; size_t output_buffer_size = 0; size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; test_driver_cipher_hooks = test_driver_cipher_hooks_init(); PSA_ASSERT( psa_crypto_init( ) ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT ); psa_set_key_algorithm( &attributes, alg ); psa_set_key_type( &attributes, key_type ); PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) ); PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; output_buffer_size = ( (size_t) input->len + PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) ); ASSERT_ALLOC( output, output_buffer_size ); PSA_ASSERT( psa_cipher_update( &operation, input->x, input->len, output, output_buffer_size, &function_output_length ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 1 ); test_driver_cipher_hooks.hits = 0; total_output_length += function_output_length; status = psa_cipher_finish( &operation, output + total_output_length, output_buffer_size - total_output_length, &function_output_length ); /* Finish will have called abort as well, so expecting two hits here */ TEST_EQUAL( test_driver_cipher_hooks.hits, 2 ); test_driver_cipher_hooks.hits = 0; total_output_length += function_output_length; TEST_EQUAL( status, expected_status ); if( expected_status == PSA_SUCCESS ) { PSA_ASSERT( psa_cipher_abort( &operation ) ); TEST_EQUAL( test_driver_cipher_hooks.hits, 0 ); ASSERT_COMPARE( expected_output->x, expected_output->len, output, total_output_length ); } exit: psa_cipher_abort( &operation ); mbedtls_free( output ); psa_destroy_key( handle ); PSA_DONE( ); test_driver_cipher_hooks = test_driver_cipher_hooks_init(); } /* END_CASE */