mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-23 19:15:41 +01:00
87a5e565f4
This commit starts a migration to a new interface for key creation. Today, the application allocates a handle, then fills its metadata, and finally injects key material. The new interface fills metadata into a temporary structure, and a handle is allocated at the same time it gets filled with both metadata and key material. This commit was obtained by moving the declaration of the old-style functions to crypto_extra.h and renaming them with the to_handle suffix, adding declarations for the new-style functions in crypto.h under their new name, and running perl -i -pe 's/\bpsa_(import|copy|generator_import|generate)_key\b/$&_to_handle/g' library/*.c tests/suites/*.function programs/psa/*.c perl -i -pe 's/\bpsa_get_key_lifetime\b/$&_from_handle/g' library/*.c tests/suites/*.function programs/psa/*.c Many functions that are specific to the old interface, and which will not remain under the same name with the new interface, are still in crypto.h for now. All functional tests should still pass. The documentation may have some broken links.
696 lines
25 KiB
Plaintext
696 lines
25 KiB
Plaintext
/* BEGIN_HEADER */
|
|
#include <stdint.h>
|
|
|
|
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
|
|
#include "spm/psa_defs.h"
|
|
#endif
|
|
#include "psa/crypto.h"
|
|
|
|
#include "psa_crypto_storage.h"
|
|
|
|
typedef enum
|
|
{
|
|
CLOSE_BY_CLOSE,
|
|
CLOSE_BY_DESTROY,
|
|
CLOSE_BY_SHUTDOWN,
|
|
} close_method_t;
|
|
|
|
typedef enum
|
|
{
|
|
KEEP_OPEN,
|
|
CLOSE_BEFORE,
|
|
CLOSE_AFTER,
|
|
} reopen_policy_t;
|
|
|
|
/* All test functions that create persistent keys must call
|
|
* `TEST_MAX_KEY_ID( key_id )` before creating a persistent key with this
|
|
* identifier, and must call psa_purge_key_storage() in their cleanup
|
|
* code. */
|
|
|
|
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
|
/* There is no API to purge all keys. For this test suite, require that
|
|
* all key IDs be less than a certain maximum, or a well-known value
|
|
* which corresponds to a file that does not contain a key. */
|
|
#define MAX_KEY_ID_FOR_TEST 32
|
|
#define KEY_ID_IS_WELL_KNOWN( key_id ) \
|
|
( ( key_id ) == PSA_CRYPTO_ITS_RANDOM_SEED_UID )
|
|
#define TEST_MAX_KEY_ID( key_id ) \
|
|
TEST_ASSERT( ( key_id ) <= MAX_KEY_ID_FOR_TEST || \
|
|
KEY_ID_IS_WELL_KNOWN( key_id ) )
|
|
void psa_purge_key_storage( void )
|
|
{
|
|
psa_key_id_t i;
|
|
/* The tests may have potentially created key ids from 1 to
|
|
* MAX_KEY_ID_FOR_TEST. In addition, run the destroy function on key id
|
|
* 0, which file-based storage uses as a temporary file. */
|
|
for( i = 0; i <= MAX_KEY_ID_FOR_TEST; i++ )
|
|
psa_destroy_persistent_key( i );
|
|
}
|
|
#else
|
|
#define TEST_MAX_KEY_ID( key_id ) ( (void) ( key_id ) )
|
|
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
|
|
|
static int psa_key_policy_equal( psa_key_policy_t *p1,
|
|
psa_key_policy_t *p2 )
|
|
{
|
|
return( psa_key_policy_get_usage( p1 ) == psa_key_policy_get_usage( p2 ) &&
|
|
psa_key_policy_get_algorithm( p1 ) == psa_key_policy_get_algorithm( p2 ) );
|
|
}
|
|
|
|
/* END_HEADER */
|
|
|
|
/* BEGIN_DEPENDENCIES
|
|
* depends_on:MBEDTLS_PSA_CRYPTO_C
|
|
* END_DEPENDENCIES
|
|
*/
|
|
|
|
/* BEGIN_CASE */
|
|
void transient_slot_lifecycle( int alg_arg, int usage_arg,
|
|
int type_arg, data_t *key_data,
|
|
int close_method_arg )
|
|
{
|
|
psa_algorithm_t alg = alg_arg;
|
|
psa_key_usage_t usage_flags = usage_arg;
|
|
psa_key_type_t type = type_arg;
|
|
close_method_t close_method = close_method_arg;
|
|
psa_key_type_t read_type;
|
|
psa_key_handle_t handle = 0;
|
|
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
|
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
|
|
/* Get a handle and import a key. */
|
|
PSA_ASSERT( psa_allocate_key( &handle ) );
|
|
TEST_ASSERT( handle != 0 );
|
|
psa_key_policy_set_usage( &policy, usage_flags, alg );
|
|
PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
|
|
PSA_ASSERT( psa_import_key_to_handle( handle, type, key_data->x, key_data->len ) );
|
|
PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) );
|
|
TEST_EQUAL( read_type, type );
|
|
|
|
/* Do something that invalidates the handle. */
|
|
switch( close_method )
|
|
{
|
|
case CLOSE_BY_CLOSE:
|
|
PSA_ASSERT( psa_close_key( handle ) );
|
|
break;
|
|
case CLOSE_BY_DESTROY:
|
|
PSA_ASSERT( psa_destroy_key( handle ) );
|
|
break;
|
|
case CLOSE_BY_SHUTDOWN:
|
|
mbedtls_psa_crypto_free( );
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
break;
|
|
}
|
|
/* Test that the handle is now invalid. */
|
|
TEST_EQUAL( psa_get_key_information( handle, &read_type, NULL ),
|
|
PSA_ERROR_INVALID_HANDLE );
|
|
TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
|
void persistent_slot_lifecycle( int lifetime_arg, int id_arg,
|
|
int alg_arg, int usage_arg,
|
|
int type_arg, data_t *key_data,
|
|
int close_method_arg )
|
|
{
|
|
psa_key_lifetime_t lifetime = lifetime_arg;
|
|
psa_key_id_t id = id_arg;
|
|
psa_algorithm_t alg = alg_arg;
|
|
psa_key_usage_t usage_flags = usage_arg;
|
|
psa_key_type_t type = type_arg;
|
|
close_method_t close_method = close_method_arg;
|
|
psa_key_type_t read_type;
|
|
psa_key_handle_t handle = 0;
|
|
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
|
|
|
TEST_MAX_KEY_ID( id );
|
|
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
|
|
/* Get a handle and import a key. */
|
|
PSA_ASSERT( psa_create_key( lifetime, id, &handle ) );
|
|
TEST_ASSERT( handle != 0 );
|
|
psa_key_policy_set_usage( &policy, usage_flags, alg );
|
|
PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
|
|
PSA_ASSERT( psa_import_key_to_handle( handle, type, key_data->x, key_data->len ) );
|
|
PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) );
|
|
TEST_EQUAL( read_type, type );
|
|
|
|
/* Close the key and reopen it. */
|
|
PSA_ASSERT( psa_close_key( handle ) );
|
|
PSA_ASSERT( psa_open_key( lifetime, id, &handle ) );
|
|
PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) );
|
|
TEST_EQUAL( read_type, type );
|
|
|
|
/* Do something that invalidates the handle. */
|
|
switch( close_method )
|
|
{
|
|
case CLOSE_BY_CLOSE:
|
|
PSA_ASSERT( psa_close_key( handle ) );
|
|
break;
|
|
case CLOSE_BY_DESTROY:
|
|
PSA_ASSERT( psa_destroy_key( handle ) );
|
|
break;
|
|
case CLOSE_BY_SHUTDOWN:
|
|
mbedtls_psa_crypto_free( );
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
break;
|
|
}
|
|
/* Test that the handle is now invalid. */
|
|
TEST_EQUAL( psa_get_key_information( handle, &read_type, NULL ),
|
|
PSA_ERROR_INVALID_HANDLE );
|
|
TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
|
|
|
|
/* Try to reopen the key. If we destroyed it, check that it doesn't
|
|
* exist, otherwise check that it still exists. */
|
|
switch( close_method )
|
|
{
|
|
case CLOSE_BY_CLOSE:
|
|
case CLOSE_BY_SHUTDOWN:
|
|
PSA_ASSERT( psa_open_key( lifetime, id, &handle ) );
|
|
PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) );
|
|
TEST_EQUAL( read_type, type );
|
|
break;
|
|
case CLOSE_BY_DESTROY:
|
|
TEST_EQUAL( psa_open_key( lifetime, id, &handle ),
|
|
PSA_ERROR_DOES_NOT_EXIST );
|
|
break;
|
|
}
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
psa_purge_key_storage( );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
|
void create_existent( int lifetime_arg, int id_arg,
|
|
int reopen_policy_arg )
|
|
{
|
|
psa_key_lifetime_t lifetime = lifetime_arg;
|
|
psa_key_id_t id = id_arg;
|
|
psa_key_handle_t handle1 = 0, handle2 = 0;
|
|
psa_key_policy_t policy1 = PSA_KEY_POLICY_INIT;
|
|
psa_key_policy_t read_policy = PSA_KEY_POLICY_INIT;
|
|
psa_key_type_t type1 = PSA_KEY_TYPE_RAW_DATA;
|
|
psa_key_type_t read_type;
|
|
const uint8_t material1[16] = "test material #1";
|
|
size_t bits1 = PSA_BYTES_TO_BITS( sizeof( material1 ) );
|
|
size_t read_bits;
|
|
uint8_t reexported[sizeof( material1 )];
|
|
size_t reexported_length;
|
|
reopen_policy_t reopen_policy = reopen_policy_arg;
|
|
|
|
TEST_MAX_KEY_ID( id );
|
|
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
|
|
/* Create a key. */
|
|
PSA_ASSERT( psa_create_key( lifetime, id, &handle1 ) );
|
|
TEST_ASSERT( handle1 != 0 );
|
|
psa_key_policy_set_usage( &policy1, PSA_KEY_USAGE_EXPORT, 0 );
|
|
PSA_ASSERT( psa_set_key_policy( handle1, &policy1 ) );
|
|
PSA_ASSERT( psa_import_key_to_handle( handle1, type1,
|
|
material1, sizeof( material1 ) ) );
|
|
|
|
if( reopen_policy == CLOSE_BEFORE )
|
|
PSA_ASSERT( psa_close_key( handle1 ) );
|
|
|
|
/* Attempt to create a new key in the same slot. */
|
|
TEST_EQUAL( psa_create_key( lifetime, id, &handle2 ),
|
|
PSA_ERROR_ALREADY_EXISTS );
|
|
TEST_EQUAL( handle2, 0 );
|
|
|
|
if( reopen_policy == CLOSE_AFTER )
|
|
PSA_ASSERT( psa_close_key( handle1 ) );
|
|
if( reopen_policy == CLOSE_BEFORE || reopen_policy == CLOSE_AFTER )
|
|
PSA_ASSERT( psa_open_key( lifetime, id, &handle1 ) );
|
|
|
|
/* Check that the original key hasn't changed. */
|
|
PSA_ASSERT( psa_get_key_policy( handle1, &read_policy ) );
|
|
TEST_ASSERT( psa_key_policy_equal( &read_policy, &policy1 ) );
|
|
PSA_ASSERT( psa_get_key_information( handle1, &read_type, &read_bits ) );
|
|
TEST_EQUAL( read_type, type1 );
|
|
TEST_EQUAL( read_bits, bits1 );
|
|
PSA_ASSERT( psa_export_key( handle1,
|
|
reexported, sizeof( reexported ),
|
|
&reexported_length ) );
|
|
ASSERT_COMPARE( material1, sizeof( material1 ),
|
|
reexported, reexported_length );
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
psa_purge_key_storage( );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void open_fail( int lifetime_arg, int id_arg,
|
|
int expected_status_arg )
|
|
{
|
|
psa_key_lifetime_t lifetime = lifetime_arg;
|
|
psa_key_id_t id = id_arg;
|
|
psa_status_t expected_status = expected_status_arg;
|
|
psa_key_handle_t handle = 0xdead;
|
|
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
|
|
TEST_EQUAL( psa_open_key( lifetime, id, &handle ), expected_status );
|
|
TEST_EQUAL( handle, 0 );
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void create_fail( int lifetime_arg, int id_arg,
|
|
int expected_status_arg )
|
|
{
|
|
psa_key_lifetime_t lifetime = lifetime_arg;
|
|
psa_key_id_t id = id_arg;
|
|
psa_status_t expected_status = expected_status_arg;
|
|
psa_key_handle_t handle = 0xdead;
|
|
|
|
TEST_MAX_KEY_ID( id );
|
|
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
|
|
TEST_EQUAL( psa_create_key( lifetime, id, &handle ),
|
|
expected_status );
|
|
TEST_EQUAL( handle, 0 );
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
|
psa_purge_key_storage( );
|
|
#endif
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void copy_across_lifetimes( int source_lifetime_arg, int source_id_arg,
|
|
int source_usage_arg, int source_alg_arg,
|
|
int type_arg, data_t *material,
|
|
int target_lifetime_arg, int target_id_arg,
|
|
int target_usage_arg, int target_alg_arg,
|
|
int expected_usage_arg, int expected_alg_arg )
|
|
{
|
|
psa_key_lifetime_t source_lifetime = source_lifetime_arg;
|
|
psa_key_id_t source_id = source_id_arg;
|
|
psa_key_usage_t source_usage = source_usage_arg;
|
|
psa_algorithm_t source_alg = source_alg_arg;
|
|
psa_key_handle_t source_handle = 0;
|
|
psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
|
|
psa_key_type_t source_type = type_arg;
|
|
size_t source_bits;
|
|
psa_key_lifetime_t target_lifetime = target_lifetime_arg;
|
|
psa_key_id_t target_id = target_id_arg;
|
|
psa_key_usage_t target_usage = target_usage_arg;
|
|
psa_algorithm_t target_alg = target_alg_arg;
|
|
psa_key_handle_t target_handle = 0;
|
|
psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
|
|
psa_key_type_t target_type;
|
|
size_t target_bits;
|
|
psa_key_usage_t expected_usage = expected_usage_arg;
|
|
psa_algorithm_t expected_alg = expected_alg_arg;
|
|
uint8_t *export_buffer = NULL;
|
|
|
|
TEST_MAX_KEY_ID( source_id );
|
|
TEST_MAX_KEY_ID( target_id );
|
|
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
|
|
/* Populate the source slot. */
|
|
if( source_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
|
PSA_ASSERT( psa_allocate_key( &source_handle ) );
|
|
else
|
|
PSA_ASSERT( psa_create_key( source_lifetime, source_id,
|
|
&source_handle ) );
|
|
psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
|
|
PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
|
|
PSA_ASSERT( psa_import_key_to_handle( source_handle, source_type,
|
|
material->x, material->len ) );
|
|
PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
|
|
|
|
/* Prepare the target slot. */
|
|
if( target_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
|
PSA_ASSERT( psa_allocate_key( &target_handle ) );
|
|
else
|
|
PSA_ASSERT( psa_create_key( target_lifetime, target_id,
|
|
&target_handle ) );
|
|
psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
|
|
PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
|
|
target_policy = psa_key_policy_init();
|
|
|
|
/* Copy the key. */
|
|
PSA_ASSERT( psa_copy_key_to_handle( source_handle, target_handle, NULL ) );
|
|
|
|
/* Destroy the source to ensure that this doesn't affect the target. */
|
|
PSA_ASSERT( psa_destroy_key( source_handle ) );
|
|
|
|
/* If the target key is persistent, restart the system to make
|
|
* sure that the material is still alive. */
|
|
if( target_lifetime != PSA_KEY_LIFETIME_VOLATILE )
|
|
{
|
|
mbedtls_psa_crypto_free( );
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
PSA_ASSERT( psa_open_key( target_lifetime, target_id,
|
|
&target_handle ) );
|
|
}
|
|
|
|
/* Test that the target slot has the expected content. */
|
|
PSA_ASSERT( psa_get_key_information( target_handle,
|
|
&target_type, &target_bits ) );
|
|
TEST_EQUAL( source_type, target_type );
|
|
TEST_EQUAL( source_bits, target_bits );
|
|
PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
|
|
TEST_EQUAL( expected_usage, psa_key_policy_get_usage( &target_policy ) );
|
|
TEST_EQUAL( expected_alg, psa_key_policy_get_algorithm( &target_policy ) );
|
|
if( expected_usage & PSA_KEY_USAGE_EXPORT )
|
|
{
|
|
size_t length;
|
|
ASSERT_ALLOC( export_buffer, material->len );
|
|
PSA_ASSERT( psa_export_key( target_handle, export_buffer,
|
|
material->len, &length ) );
|
|
ASSERT_COMPARE( material->x, material->len,
|
|
export_buffer, length );
|
|
}
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
mbedtls_free( export_buffer );
|
|
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
|
psa_purge_key_storage( );
|
|
#endif
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void copy_from_empty( int source_lifetime_arg, int source_id_arg,
|
|
int source_usage_arg, int source_alg_arg,
|
|
int target_lifetime_arg, int target_id_arg,
|
|
int target_usage_arg, int target_alg_arg )
|
|
{
|
|
psa_key_lifetime_t source_lifetime = source_lifetime_arg;
|
|
psa_key_id_t source_id = source_id_arg;
|
|
psa_key_usage_t source_usage = source_usage_arg;
|
|
psa_algorithm_t source_alg = source_alg_arg;
|
|
psa_key_handle_t source_handle = 0;
|
|
psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
|
|
psa_key_lifetime_t target_lifetime = target_lifetime_arg;
|
|
psa_key_id_t target_id = target_id_arg;
|
|
psa_key_usage_t target_usage = target_usage_arg;
|
|
psa_algorithm_t target_alg = target_alg_arg;
|
|
psa_key_handle_t target_handle = 0;
|
|
psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
|
|
psa_key_policy_t got_policy;
|
|
|
|
TEST_MAX_KEY_ID( source_id );
|
|
TEST_MAX_KEY_ID( target_id );
|
|
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
|
|
/* Prepare the source slot. */
|
|
if( source_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
|
PSA_ASSERT( psa_allocate_key( &source_handle ) );
|
|
else
|
|
PSA_ASSERT( psa_create_key( source_lifetime, source_id,
|
|
&source_handle ) );
|
|
psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
|
|
PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
|
|
|
|
/* Prepare the target slot. */
|
|
if( target_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
|
PSA_ASSERT( psa_allocate_key( &target_handle ) );
|
|
else
|
|
PSA_ASSERT( psa_create_key( target_lifetime, target_id,
|
|
&target_handle ) );
|
|
psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
|
|
PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
|
|
|
|
/* Copy the key. */
|
|
TEST_EQUAL( psa_copy_key_to_handle( source_handle, target_handle, NULL ),
|
|
PSA_ERROR_DOES_NOT_EXIST );
|
|
|
|
/* Test that the slots are unaffected. */
|
|
PSA_ASSERT( psa_get_key_policy( source_handle, &got_policy ) );
|
|
TEST_EQUAL( source_usage, psa_key_policy_get_usage( &got_policy ) );
|
|
TEST_EQUAL( source_alg, psa_key_policy_get_algorithm( &got_policy ) );
|
|
PSA_ASSERT( psa_get_key_policy( target_handle, &got_policy ) );
|
|
TEST_EQUAL( target_usage, psa_key_policy_get_usage( &got_policy ) );
|
|
TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &got_policy ) );
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
|
psa_purge_key_storage( );
|
|
#endif
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void copy_to_occupied( int source_lifetime_arg, int source_id_arg,
|
|
int source_usage_arg, int source_alg_arg,
|
|
int source_type_arg, data_t *source_material,
|
|
int target_lifetime_arg, int target_id_arg,
|
|
int target_usage_arg, int target_alg_arg,
|
|
int target_type_arg, data_t *target_material )
|
|
{
|
|
psa_key_lifetime_t source_lifetime = source_lifetime_arg;
|
|
psa_key_id_t source_id = source_id_arg;
|
|
psa_key_usage_t source_usage = source_usage_arg;
|
|
psa_algorithm_t source_alg = source_alg_arg;
|
|
psa_key_handle_t source_handle = 0;
|
|
psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
|
|
psa_key_type_t source_type = source_type_arg;
|
|
size_t source_bits;
|
|
psa_key_lifetime_t target_lifetime = target_lifetime_arg;
|
|
psa_key_id_t target_id = target_id_arg;
|
|
psa_key_usage_t target_usage = target_usage_arg;
|
|
psa_algorithm_t target_alg = target_alg_arg;
|
|
psa_key_handle_t target_handle = 0;
|
|
psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
|
|
psa_key_type_t target_type = target_type_arg;
|
|
size_t target_bits;
|
|
psa_key_policy_t got_policy;
|
|
psa_key_type_t got_type;
|
|
size_t got_bits;
|
|
uint8_t *export_buffer = NULL;
|
|
|
|
TEST_MAX_KEY_ID( source_id );
|
|
TEST_MAX_KEY_ID( target_id );
|
|
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
|
|
/* Populate the source slot. */
|
|
if( source_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
|
PSA_ASSERT( psa_allocate_key( &source_handle ) );
|
|
else
|
|
PSA_ASSERT( psa_create_key( source_lifetime, source_id,
|
|
&source_handle ) );
|
|
psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
|
|
PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
|
|
PSA_ASSERT( psa_import_key_to_handle( source_handle, source_type,
|
|
source_material->x, source_material->len ) );
|
|
PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
|
|
|
|
/* Populate the target slot. */
|
|
if( target_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
|
PSA_ASSERT( psa_allocate_key( &target_handle ) );
|
|
else
|
|
PSA_ASSERT( psa_create_key( target_lifetime, target_id,
|
|
&target_handle ) );
|
|
psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
|
|
PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
|
|
PSA_ASSERT( psa_import_key_to_handle( target_handle, target_type,
|
|
target_material->x, target_material->len ) );
|
|
PSA_ASSERT( psa_get_key_information( target_handle, NULL, &target_bits ) );
|
|
|
|
/* Copy the key. */
|
|
TEST_EQUAL( psa_copy_key_to_handle( source_handle, target_handle, NULL ),
|
|
PSA_ERROR_ALREADY_EXISTS );
|
|
|
|
/* Test that the target slot is unaffected. */
|
|
PSA_ASSERT( psa_get_key_information( target_handle,
|
|
&got_type, &got_bits ) );
|
|
TEST_EQUAL( target_type, got_type );
|
|
TEST_EQUAL( target_bits, got_bits );
|
|
PSA_ASSERT( psa_get_key_policy( target_handle, &got_policy ) );
|
|
TEST_EQUAL( target_usage, psa_key_policy_get_usage( &got_policy ) );
|
|
TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &got_policy ) );
|
|
if( target_usage & PSA_KEY_USAGE_EXPORT )
|
|
{
|
|
size_t length;
|
|
ASSERT_ALLOC( export_buffer, target_material->len );
|
|
PSA_ASSERT( psa_export_key( target_handle, export_buffer,
|
|
target_material->len, &length ) );
|
|
ASSERT_COMPARE( target_material->x, target_material->len,
|
|
export_buffer, length );
|
|
}
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
mbedtls_free( export_buffer );
|
|
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
|
psa_purge_key_storage( );
|
|
#endif
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void copy_to_same( int lifetime_arg, int id_arg,
|
|
int usage_arg, int alg_arg,
|
|
int type_arg, data_t *material )
|
|
{
|
|
psa_key_lifetime_t lifetime = lifetime_arg;
|
|
psa_key_id_t id = id_arg;
|
|
psa_key_usage_t usage = usage_arg;
|
|
psa_algorithm_t alg = alg_arg;
|
|
psa_key_handle_t handle = 0;
|
|
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
|
psa_key_type_t type = type_arg;
|
|
size_t bits;
|
|
psa_key_policy_t got_policy;
|
|
psa_key_type_t got_type;
|
|
size_t got_bits;
|
|
uint8_t *export_buffer = NULL;
|
|
|
|
TEST_MAX_KEY_ID( id );
|
|
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
|
|
/* Populate the slot. */
|
|
if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
|
PSA_ASSERT( psa_allocate_key( &handle ) );
|
|
else
|
|
PSA_ASSERT( psa_create_key( lifetime, id,
|
|
&handle ) );
|
|
psa_key_policy_set_usage( &policy, usage, alg );
|
|
PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
|
|
PSA_ASSERT( psa_import_key_to_handle( handle, type,
|
|
material->x, material->len ) );
|
|
PSA_ASSERT( psa_get_key_information( handle, NULL, &bits ) );
|
|
|
|
/* Copy the key. */
|
|
TEST_EQUAL( psa_copy_key_to_handle( handle, handle, NULL ),
|
|
PSA_ERROR_ALREADY_EXISTS );
|
|
|
|
/* Test that the slot is unaffected. */
|
|
PSA_ASSERT( psa_get_key_information( handle,
|
|
&got_type, &got_bits ) );
|
|
TEST_EQUAL( type, got_type );
|
|
TEST_EQUAL( bits, got_bits );
|
|
PSA_ASSERT( psa_get_key_policy( handle, &got_policy ) );
|
|
TEST_EQUAL( usage, psa_key_policy_get_usage( &got_policy ) );
|
|
TEST_EQUAL( alg, psa_key_policy_get_algorithm( &got_policy ) );
|
|
if( usage & PSA_KEY_USAGE_EXPORT )
|
|
{
|
|
size_t length;
|
|
ASSERT_ALLOC( export_buffer, material->len );
|
|
PSA_ASSERT( psa_export_key( handle, export_buffer,
|
|
material->len, &length ) );
|
|
ASSERT_COMPARE( material->x, material->len,
|
|
export_buffer, length );
|
|
}
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
mbedtls_free( export_buffer );
|
|
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
|
psa_purge_key_storage( );
|
|
#endif
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void invalid_handle( )
|
|
{
|
|
psa_key_handle_t handle1 = 0;
|
|
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
|
psa_key_type_t read_type;
|
|
size_t read_bits;
|
|
uint8_t material[1] = "a";
|
|
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
|
|
/* Allocate a handle and store a key in it. */
|
|
PSA_ASSERT( psa_allocate_key( &handle1 ) );
|
|
TEST_ASSERT( handle1 != 0 );
|
|
psa_key_policy_set_usage( &policy, 0, 0 );
|
|
PSA_ASSERT( psa_set_key_policy( handle1, &policy ) );
|
|
PSA_ASSERT( psa_import_key_to_handle( handle1, PSA_KEY_TYPE_RAW_DATA,
|
|
material, sizeof( material ) ) );
|
|
|
|
/* Attempt to close and destroy some invalid handles. */
|
|
TEST_EQUAL( psa_close_key( 0 ), PSA_ERROR_INVALID_HANDLE );
|
|
TEST_EQUAL( psa_close_key( handle1 - 1 ), PSA_ERROR_INVALID_HANDLE );
|
|
TEST_EQUAL( psa_close_key( handle1 + 1 ), PSA_ERROR_INVALID_HANDLE );
|
|
TEST_EQUAL( psa_destroy_key( 0 ), PSA_ERROR_INVALID_HANDLE );
|
|
TEST_EQUAL( psa_destroy_key( handle1 - 1 ), PSA_ERROR_INVALID_HANDLE );
|
|
TEST_EQUAL( psa_destroy_key( handle1 + 1 ), PSA_ERROR_INVALID_HANDLE );
|
|
|
|
/* After all this, check that the original handle is intact. */
|
|
PSA_ASSERT( psa_get_key_information( handle1, &read_type, &read_bits ) );
|
|
TEST_EQUAL( read_type, PSA_KEY_TYPE_RAW_DATA );
|
|
TEST_EQUAL( read_bits, PSA_BYTES_TO_BITS( sizeof( material ) ) );
|
|
PSA_ASSERT( psa_close_key( handle1 ) );
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void many_transient_handles( int max_handles_arg )
|
|
{
|
|
psa_key_handle_t *handles = NULL;
|
|
size_t max_handles = max_handles_arg;
|
|
size_t i, j;
|
|
psa_status_t status;
|
|
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
|
uint8_t exported[sizeof( size_t )];
|
|
size_t exported_length;
|
|
|
|
ASSERT_ALLOC( handles, max_handles );
|
|
PSA_ASSERT( psa_crypto_init( ) );
|
|
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 );
|
|
|
|
for( i = 0; i < max_handles; i++ )
|
|
{
|
|
status = psa_allocate_key( &handles[i] );
|
|
if( status == PSA_ERROR_INSUFFICIENT_MEMORY )
|
|
break;
|
|
PSA_ASSERT( status );
|
|
TEST_ASSERT( handles[i] != 0 );
|
|
for( j = 0; j < i; j++ )
|
|
TEST_ASSERT( handles[i] != handles[j] );
|
|
PSA_ASSERT( psa_set_key_policy( handles[i], &policy ) );
|
|
PSA_ASSERT( psa_import_key_to_handle( handles[i], PSA_KEY_TYPE_RAW_DATA,
|
|
(uint8_t *) &i, sizeof( i ) ) );
|
|
}
|
|
max_handles = i;
|
|
|
|
for( i = 1; i < max_handles; i++ )
|
|
{
|
|
PSA_ASSERT( psa_close_key( handles[i - 1] ) );
|
|
PSA_ASSERT( psa_export_key( handles[i],
|
|
exported, sizeof( exported ),
|
|
&exported_length ) );
|
|
ASSERT_COMPARE( exported, exported_length,
|
|
(uint8_t *) &i, sizeof( i ) );
|
|
}
|
|
PSA_ASSERT( psa_close_key( handles[i - 1] ) );
|
|
|
|
exit:
|
|
mbedtls_psa_crypto_free( );
|
|
mbedtls_free( handles );
|
|
}
|
|
/* END_CASE */
|
|
|