2018-06-18 18:27:26 +02:00
|
|
|
/* BEGIN_HEADER */
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "psa/crypto.h"
|
|
|
|
#include "psa_crypto_storage.h"
|
|
|
|
#include "psa_crypto_storage_backend.h"
|
|
|
|
#include "mbedtls/md.h"
|
|
|
|
|
|
|
|
#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
|
|
|
|
#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ( sizeof( PSA_KEY_STORAGE_MAGIC_HEADER ) )
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
|
|
|
|
uint8_t version[4];
|
|
|
|
uint8_t type[sizeof( psa_key_type_t )];
|
|
|
|
uint8_t policy[sizeof( psa_key_policy_t )];
|
|
|
|
uint8_t data_len[4];
|
|
|
|
uint8_t key_data[];
|
|
|
|
} psa_persistent_key_storage_format;
|
2018-11-07 17:05:30 +01:00
|
|
|
|
2018-06-18 18:27:26 +02:00
|
|
|
/* END_HEADER */
|
|
|
|
|
|
|
|
/* BEGIN_DEPENDENCIES
|
|
|
|
* depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
|
|
|
* END_DEPENDENCIES
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* BEGIN_CASE */
|
|
|
|
void format_storage_data_check( data_t *key_data,
|
|
|
|
data_t *expected_file_data,
|
|
|
|
int key_type, int key_usage, int key_alg )
|
|
|
|
{
|
|
|
|
uint8_t *file_data;
|
|
|
|
size_t file_data_length;
|
|
|
|
psa_key_policy_t key_policy;
|
|
|
|
|
|
|
|
key_policy.usage = (psa_key_usage_t) key_usage;
|
|
|
|
key_policy.alg = (psa_algorithm_t) key_alg;
|
|
|
|
|
|
|
|
file_data_length = key_data->len + sizeof( psa_persistent_key_storage_format );
|
|
|
|
file_data = mbedtls_calloc( 1, file_data_length );
|
|
|
|
psa_format_key_data_for_storage( key_data->x, key_data->len,
|
|
|
|
(psa_key_type_t) key_type, &key_policy,
|
|
|
|
file_data );
|
|
|
|
|
|
|
|
ASSERT_COMPARE( expected_file_data->x, expected_file_data->len,
|
|
|
|
file_data, file_data_length );
|
|
|
|
mbedtls_free( file_data );
|
|
|
|
}
|
|
|
|
/* END_CASE */
|
|
|
|
|
|
|
|
/* BEGIN_CASE */
|
|
|
|
void parse_storage_data_check( data_t *file_data,
|
|
|
|
data_t *expected_key_data,
|
|
|
|
int expected_key_type,
|
|
|
|
int expected_key_usage,
|
|
|
|
int expected_key_alg,
|
|
|
|
int expected_status )
|
|
|
|
{
|
|
|
|
uint8_t *key_data = NULL;
|
|
|
|
size_t key_data_length = 0;
|
|
|
|
psa_key_type_t key_type = 0;
|
|
|
|
psa_key_policy_t key_policy;
|
|
|
|
psa_status_t status;
|
|
|
|
|
|
|
|
status = psa_parse_key_data_from_storage( file_data->x, file_data->len,
|
|
|
|
&key_data, &key_data_length,
|
|
|
|
&key_type, &key_policy );
|
|
|
|
|
|
|
|
TEST_ASSERT( status == expected_status );
|
|
|
|
if( status != PSA_SUCCESS )
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
TEST_ASSERT( key_type == (psa_key_type_t) expected_key_type );
|
|
|
|
TEST_ASSERT( key_policy.usage == (uint32_t) expected_key_usage );
|
|
|
|
TEST_ASSERT( key_policy.alg == (uint32_t) expected_key_alg );
|
|
|
|
ASSERT_COMPARE( expected_key_data->x, expected_key_data->len,
|
|
|
|
key_data, key_data_length );
|
|
|
|
|
|
|
|
exit:
|
|
|
|
mbedtls_free( key_data );
|
|
|
|
}
|
|
|
|
/* END_CASE */
|
|
|
|
|
|
|
|
|
|
|
|
/* BEGIN_CASE */
|
|
|
|
void save_large_persistent_key( int data_too_large, int expected_status )
|
|
|
|
{
|
|
|
|
psa_key_slot_t slot = 1;
|
|
|
|
uint8_t *data = NULL;
|
|
|
|
size_t data_length = PSA_CRYPTO_MAX_STORAGE_SIZE;
|
|
|
|
|
|
|
|
if( data_too_large )
|
|
|
|
data_length += 1;
|
|
|
|
|
|
|
|
ASSERT_ALLOC( data, data_length );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_set_key_lifetime(
|
|
|
|
slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_import_key( slot, PSA_KEY_TYPE_RAW_DATA,
|
|
|
|
data, data_length ) == expected_status );
|
|
|
|
|
|
|
|
exit:
|
|
|
|
mbedtls_free( data );
|
|
|
|
psa_destroy_persistent_key( slot );
|
|
|
|
mbedtls_psa_crypto_free();
|
|
|
|
}
|
|
|
|
/* END_CASE */
|
|
|
|
|
|
|
|
|
|
|
|
/* BEGIN_CASE */
|
|
|
|
void persistent_key_is_configurable( int slot_arg, int type_arg,
|
|
|
|
data_t *data )
|
|
|
|
{
|
|
|
|
psa_key_policy_t policy;
|
|
|
|
psa_key_lifetime_t lifetime;
|
|
|
|
psa_key_slot_t slot = (psa_key_slot_t) slot_arg;
|
|
|
|
psa_key_type_t type = (psa_key_type_t) type_arg;
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_set_key_lifetime(
|
|
|
|
slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
psa_key_policy_init( &policy );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_import_key( slot, type,
|
|
|
|
data->x, data->len ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_get_key_lifetime( slot, &lifetime ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( lifetime == PSA_KEY_LIFETIME_PERSISTENT );
|
|
|
|
|
|
|
|
exit:
|
|
|
|
psa_destroy_persistent_key( slot );
|
|
|
|
mbedtls_psa_crypto_free();
|
|
|
|
}
|
|
|
|
/* END_CASE */
|
|
|
|
|
|
|
|
/* BEGIN_CASE */
|
|
|
|
void persistent_key_destroy( int slot_arg, int should_store,
|
|
|
|
int first_type_arg, data_t *first_data,
|
|
|
|
int second_type_arg, data_t *second_data )
|
|
|
|
{
|
|
|
|
psa_key_policy_t policy;
|
|
|
|
psa_key_slot_t slot = (psa_key_slot_t) slot_arg;
|
|
|
|
psa_key_type_t first_type = (psa_key_type_t) first_type_arg;
|
|
|
|
psa_key_type_t second_type = (psa_key_type_t) second_type_arg;
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_set_key_lifetime(
|
|
|
|
slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
psa_key_policy_init( &policy );
|
|
|
|
|
|
|
|
if( should_store == 1 )
|
|
|
|
{
|
|
|
|
TEST_ASSERT( psa_import_key(
|
|
|
|
slot, first_type,
|
|
|
|
first_data->x, first_data->len ) == PSA_SUCCESS );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Destroy the key */
|
|
|
|
TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_get_key_information(
|
|
|
|
slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT );
|
|
|
|
|
|
|
|
/* Check key slot storage is removed */
|
|
|
|
TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 );
|
|
|
|
|
|
|
|
/* Check destroying the key again doesn't report failure */
|
|
|
|
TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS );
|
|
|
|
TEST_ASSERT( psa_get_key_information(
|
|
|
|
slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT );
|
|
|
|
|
|
|
|
/* Shutdown and restart */
|
|
|
|
mbedtls_psa_crypto_free();
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
|
|
|
|
|
|
|
|
/* Mark slot as persistent again */
|
|
|
|
TEST_ASSERT( psa_set_key_lifetime(
|
|
|
|
slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
/* Check key slot is empty */
|
|
|
|
TEST_ASSERT( psa_get_key_information(
|
|
|
|
slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT );
|
|
|
|
|
|
|
|
/* Import different key data to ensure slot really was empty */
|
|
|
|
psa_key_policy_init( &policy );
|
|
|
|
|
|
|
|
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT,
|
|
|
|
PSA_ALG_VENDOR_FLAG );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_import_key(
|
|
|
|
slot, second_type,
|
|
|
|
second_data->x, second_data->len ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
exit:
|
|
|
|
psa_destroy_persistent_key( slot );
|
|
|
|
mbedtls_psa_crypto_free();
|
|
|
|
}
|
|
|
|
/* END_CASE */
|
|
|
|
|
|
|
|
/* BEGIN_CASE */
|
|
|
|
void default_volatile_lifetime( int slot_arg, int type_arg, data_t *data )
|
|
|
|
{
|
|
|
|
psa_key_policy_t policy;
|
|
|
|
psa_key_slot_t slot = (psa_key_slot_t) slot_arg;
|
|
|
|
psa_key_type_t type = (psa_key_type_t) type_arg;
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
|
|
|
|
|
|
|
|
psa_key_policy_init( &policy );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_import_key( slot, type,
|
|
|
|
data->x, data->len ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
/* Shutdown and restart */
|
|
|
|
mbedtls_psa_crypto_free();
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
|
|
|
|
|
|
|
|
/* Check key slot is empty */
|
|
|
|
TEST_ASSERT( psa_get_key_information(
|
|
|
|
slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT );
|
|
|
|
|
|
|
|
exit:
|
|
|
|
psa_destroy_persistent_key( slot );
|
|
|
|
mbedtls_psa_crypto_free();
|
|
|
|
}
|
|
|
|
/* END_CASE */
|
|
|
|
|
|
|
|
/* BEGIN_CASE */
|
|
|
|
void persistent_key_import( int slot_arg, int type_arg, data_t *data,
|
|
|
|
int expected_status )
|
|
|
|
{
|
|
|
|
psa_key_policy_t policy;
|
|
|
|
psa_key_lifetime_t lifetime;
|
|
|
|
psa_key_slot_t slot = (psa_key_slot_t) slot_arg;
|
|
|
|
psa_key_type_t type = (psa_key_type_t) type_arg;
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_set_key_lifetime(
|
|
|
|
slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
psa_key_policy_init( &policy );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_import_key( slot, type,
|
|
|
|
data->x, data->len ) == expected_status );
|
|
|
|
|
|
|
|
if( expected_status != PSA_SUCCESS )
|
|
|
|
{
|
|
|
|
TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 );
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_get_key_lifetime( slot, &lifetime ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( lifetime == PSA_KEY_LIFETIME_PERSISTENT );
|
|
|
|
|
|
|
|
exit:
|
|
|
|
psa_destroy_persistent_key( slot );
|
|
|
|
mbedtls_psa_crypto_free();
|
|
|
|
}
|
|
|
|
/* END_CASE */
|
|
|
|
|
|
|
|
/* BEGIN_CASE */
|
|
|
|
void import_export_persistent_key( data_t *data, int type_arg,
|
|
|
|
int expected_bits, int key_not_exist )
|
|
|
|
{
|
|
|
|
psa_key_slot_t slot = 1;
|
|
|
|
psa_key_type_t type = (psa_key_type_t) type_arg;
|
|
|
|
unsigned char *exported = NULL;
|
|
|
|
size_t export_size = data->len;
|
|
|
|
size_t exported_length;
|
|
|
|
psa_key_type_t got_type;
|
|
|
|
size_t got_bits;
|
|
|
|
psa_key_policy_t policy;
|
|
|
|
psa_key_lifetime_t lifetime_get;
|
|
|
|
|
|
|
|
ASSERT_ALLOC( exported, export_size );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_set_key_lifetime(
|
|
|
|
slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
psa_key_policy_init( &policy );
|
|
|
|
|
|
|
|
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT,
|
|
|
|
PSA_ALG_VENDOR_FLAG );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
/* Import the key */
|
|
|
|
TEST_ASSERT( psa_import_key( slot, type,
|
|
|
|
data->x, data->len ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_get_key_lifetime(
|
|
|
|
slot, &lifetime_get ) == PSA_SUCCESS );
|
|
|
|
TEST_ASSERT( lifetime_get == PSA_KEY_LIFETIME_PERSISTENT );
|
|
|
|
|
|
|
|
/* Test the key information */
|
|
|
|
TEST_ASSERT( psa_get_key_information(
|
|
|
|
slot, &got_type, &got_bits ) == PSA_SUCCESS );
|
|
|
|
TEST_ASSERT( got_type == type );
|
|
|
|
TEST_ASSERT( got_bits == (size_t) expected_bits );
|
|
|
|
|
|
|
|
TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 1 );
|
|
|
|
|
|
|
|
if( key_not_exist )
|
|
|
|
{
|
|
|
|
psa_destroy_persistent_key( slot );
|
|
|
|
}
|
|
|
|
/* Export the key */
|
|
|
|
TEST_ASSERT( psa_export_key( slot, exported, export_size,
|
|
|
|
&exported_length ) == PSA_SUCCESS );
|
|
|
|
|
|
|
|
ASSERT_COMPARE( data->x, data->len, exported, exported_length );
|
|
|
|
|
|
|
|
/* Destroy the key */
|
|
|
|
TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS );
|
|
|
|
TEST_ASSERT( psa_get_key_information(
|
|
|
|
slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT );
|
|
|
|
TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 );
|
|
|
|
|
|
|
|
exit:
|
|
|
|
mbedtls_free( exported );
|
|
|
|
psa_destroy_persistent_key( slot );
|
|
|
|
mbedtls_psa_crypto_free( );
|
|
|
|
}
|
|
|
|
/* END_CASE */
|