Skip to content

Commit 4747d19

Browse files
Implement atomic-creation psa_import_key
Implement the new, attribute-based psa_import_key and some basic functions to access psa_key_attributes_t. Replace psa_import_key_to_handle by psa_import_key in a few test functions. This commit does not handle persistence attributes yet.
1 parent 87a5e56 commit 4747d19

File tree

4 files changed

+240
-44
lines changed

4 files changed

+240
-44
lines changed

include/psa/crypto.h

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,39 @@ psa_status_t psa_crypto_init(void);
109109
*/
110110
typedef struct psa_key_attributes_s psa_key_attributes_t;
111111

112+
static void psa_make_key_persistent(psa_key_attributes_t *attributes,
113+
psa_key_id_t id,
114+
psa_key_lifetime_t lifetime);
115+
116+
static psa_key_id_t psa_get_key_id(const psa_key_attributes_t *attributes);
117+
118+
static psa_key_lifetime_t psa_get_key_lifetime(
119+
const psa_key_attributes_t *attributes);
120+
121+
static void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
122+
psa_key_usage_t usage_flags);
123+
124+
static psa_key_usage_t psa_get_key_usage_flags(
125+
const psa_key_attributes_t *attributes);
126+
127+
static void psa_set_key_algorithm(psa_key_attributes_t *attributes,
128+
psa_algorithm_t alg);
129+
130+
static psa_algorithm_t psa_get_key_algorithm(
131+
const psa_key_attributes_t *attributes);
132+
133+
static void psa_set_key_type(psa_key_attributes_t *attributes,
134+
psa_key_type_t type);
135+
136+
static psa_key_type_t psa_get_key_type(const psa_key_attributes_t *attributes);
137+
138+
static size_t psa_get_key_bits(const psa_key_attributes_t *attributes);
139+
140+
psa_status_t psa_get_key_attributes(psa_key_handle_t handle,
141+
psa_key_attributes_t *attributes);
142+
143+
psa_status_t psa_reset_key_attributes(psa_key_attributes_t *attributes);
144+
112145
/**@}*/
113146

114147
/** \defgroup policy Key policies
@@ -380,7 +413,6 @@ psa_status_t psa_close_key(psa_key_handle_t handle);
380413
*/
381414
psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
382415
psa_key_handle_t *handle,
383-
psa_key_type_t type,
384416
const uint8_t *data,
385417
size_t data_length);
386418

@@ -2970,7 +3002,6 @@ psa_status_t psa_generator_read(psa_crypto_generator_t *generator,
29703002
*/
29713003
psa_status_t psa_generator_import_key(const psa_key_attributes_t *attributes,
29723004
psa_key_handle_t *handle,
2973-
psa_key_type_t type,
29743005
size_t bits,
29753006
psa_crypto_generator_t *generator);
29763007

@@ -3363,7 +3394,6 @@ typedef struct {
33633394
*/
33643395
psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
33653396
psa_key_handle_t *handle,
3366-
psa_key_type_t type,
33673397
size_t bits,
33683398
const void *extra,
33693399
size_t extra_size);

include/psa/crypto_struct.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,4 +260,56 @@ static inline struct psa_key_policy_s psa_key_policy_init( void )
260260
return( v );
261261
}
262262

263+
struct psa_key_attributes_s
264+
{
265+
psa_key_id_t id;
266+
psa_key_lifetime_t lifetime;
267+
psa_key_policy_t policy;
268+
psa_key_type_t type;
269+
size_t bits;
270+
};
271+
272+
#define PSA_KEY_ATTRIBUTES_INIT {0, 0, {0, 0}, 0, 0}
273+
static inline struct psa_key_attributes_s psa_key_attributes_init( void )
274+
{
275+
const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT;
276+
return( v );
277+
}
278+
279+
static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
280+
psa_key_usage_t usage_flags)
281+
{
282+
attributes->policy.usage = usage_flags;
283+
}
284+
285+
static inline psa_key_usage_t psa_get_key_usage_flags(
286+
const psa_key_attributes_t *attributes)
287+
{
288+
return( attributes->policy.usage );
289+
}
290+
291+
static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
292+
psa_algorithm_t alg)
293+
{
294+
attributes->policy.alg = alg;
295+
}
296+
297+
static inline psa_algorithm_t psa_get_key_algorithm(
298+
const psa_key_attributes_t *attributes)
299+
{
300+
return( attributes->policy.alg );
301+
}
302+
303+
static inline void psa_set_key_type(psa_key_attributes_t *attributes,
304+
psa_key_type_t type)
305+
{
306+
attributes->type = type;
307+
}
308+
309+
static inline psa_key_type_t psa_get_key_type(
310+
const psa_key_attributes_t *attributes)
311+
{
312+
return( attributes->type );
313+
}
314+
263315
#endif /* PSA_CRYPTO_STRUCT_H */

library/psa_crypto.c

Lines changed: 135 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,140 @@ static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t *slot,
12121212
}
12131213
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
12141214

1215+
static psa_status_t psa_set_key_policy_internal(
1216+
psa_key_slot_t *slot,
1217+
const psa_key_policy_t *policy )
1218+
{
1219+
if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
1220+
PSA_KEY_USAGE_ENCRYPT |
1221+
PSA_KEY_USAGE_DECRYPT |
1222+
PSA_KEY_USAGE_SIGN |
1223+
PSA_KEY_USAGE_VERIFY |
1224+
PSA_KEY_USAGE_DERIVE ) ) != 0 )
1225+
return( PSA_ERROR_INVALID_ARGUMENT );
1226+
1227+
slot->policy = *policy;
1228+
return( PSA_SUCCESS );
1229+
}
1230+
1231+
/** Prepare a key slot to receive key material.
1232+
*
1233+
* This function allocates a key slot and sets its metadata.
1234+
*
1235+
* If this function fails, call psa_fail_key_creation().
1236+
*
1237+
* \param attributes Key attributes for the new key.
1238+
* \param handle On success, the allocated handle.
1239+
* \param p_slot On success, a pointer to the prepared slot.
1240+
*/
1241+
static psa_status_t psa_start_key_creation(
1242+
const psa_key_attributes_t *attributes,
1243+
psa_key_handle_t *handle,
1244+
psa_key_slot_t **p_slot )
1245+
{
1246+
psa_status_t status;
1247+
psa_key_slot_t *slot;
1248+
1249+
status = psa_allocate_key( handle );
1250+
if( status != PSA_SUCCESS )
1251+
return( status );
1252+
status = psa_get_key_slot( *handle, p_slot );
1253+
if( status != PSA_SUCCESS )
1254+
return( status );
1255+
slot = *p_slot;
1256+
1257+
status = psa_set_key_policy_internal( slot, &attributes->policy );
1258+
if( status != PSA_SUCCESS )
1259+
return( status );
1260+
slot->lifetime = attributes->lifetime;
1261+
if( attributes->lifetime != PSA_KEY_LIFETIME_VOLATILE )
1262+
slot->persistent_storage_id = attributes->id;
1263+
slot->type = attributes->type;
1264+
1265+
return( status );
1266+
}
1267+
1268+
/** Finalize the creation of a key once its key material has been set.
1269+
*
1270+
* This entails writing the key to persistent storage.
1271+
*
1272+
* If this function fails, call psa_fail_key_creation().
1273+
*
1274+
* \param slot Pointer to the slot with key material.
1275+
*/
1276+
static psa_status_t psa_finish_key_creation( psa_key_slot_t *slot )
1277+
{
1278+
psa_status_t status = PSA_SUCCESS;
1279+
1280+
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
1281+
if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
1282+
{
1283+
uint8_t *buffer = NULL;
1284+
size_t buffer_size = 0;
1285+
size_t length;
1286+
1287+
buffer_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type,
1288+
psa_get_key_bits( slot ) );
1289+
buffer = mbedtls_calloc( 1, buffer_size );
1290+
if( buffer == NULL && buffer_size != 0 )
1291+
return( PSA_ERROR_INSUFFICIENT_MEMORY );
1292+
status = psa_internal_export_key( slot,
1293+
buffer, buffer_size, &length,
1294+
0 );
1295+
1296+
if( status == PSA_SUCCESS )
1297+
{
1298+
status = psa_save_persistent_key( slot->persistent_storage_id,
1299+
slot->type, &slot->policy,
1300+
buffer, length );
1301+
}
1302+
1303+
if( buffer_size != 0 )
1304+
mbedtls_platform_zeroize( buffer, buffer_size );
1305+
mbedtls_free( buffer );
1306+
}
1307+
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1308+
1309+
return( status );
1310+
}
1311+
1312+
/** Abort the creation of a key.
1313+
*
1314+
* You may call this function after calling psa_start_key_creation(),
1315+
* or after psa_finish_key_creation() fails. In other circumstances, this
1316+
* function may not clean up persistent storage.
1317+
*
1318+
* \param slot Pointer to the slot with key material.
1319+
*/
1320+
static void psa_fail_key_creation( psa_key_slot_t *slot )
1321+
{
1322+
if( slot == NULL )
1323+
return;
1324+
psa_wipe_key_slot( slot );
1325+
}
1326+
1327+
psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
1328+
psa_key_handle_t *handle,
1329+
const uint8_t *data,
1330+
size_t data_length )
1331+
{
1332+
psa_status_t status;
1333+
psa_key_slot_t *slot = NULL;
1334+
status = psa_start_key_creation( attributes, handle, &slot );
1335+
if( status == PSA_SUCCESS )
1336+
{
1337+
status = psa_import_key_into_slot( slot, data, data_length );
1338+
}
1339+
if( status == PSA_SUCCESS )
1340+
status = psa_finish_key_creation( slot );
1341+
if( status != PSA_SUCCESS )
1342+
{
1343+
psa_fail_key_creation( slot );
1344+
*handle = 0;
1345+
}
1346+
return( status );
1347+
}
1348+
12151349
static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
12161350
psa_key_handle_t target )
12171351
{
@@ -3240,17 +3374,7 @@ psa_status_t psa_set_key_policy( psa_key_handle_t handle,
32403374
if( status != PSA_SUCCESS )
32413375
return( status );
32423376

3243-
if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
3244-
PSA_KEY_USAGE_ENCRYPT |
3245-
PSA_KEY_USAGE_DECRYPT |
3246-
PSA_KEY_USAGE_SIGN |
3247-
PSA_KEY_USAGE_VERIFY |
3248-
PSA_KEY_USAGE_DERIVE ) ) != 0 )
3249-
return( PSA_ERROR_INVALID_ARGUMENT );
3250-
3251-
slot->policy = *policy;
3252-
3253-
return( PSA_SUCCESS );
3377+
return( psa_set_key_policy_internal( slot, policy ) );
32543378
}
32553379

32563380
psa_status_t psa_get_key_policy( psa_key_handle_t handle,

tests/suites/test_suite_psa_crypto.function

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,14 +1111,15 @@ void static_checks( )
11111111
/* BEGIN_CASE */
11121112
void import( data_t *data, int type, int expected_status_arg )
11131113
{
1114+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
11141115
psa_key_handle_t handle = 0;
11151116
psa_status_t expected_status = expected_status_arg;
11161117
psa_status_t status;
11171118

11181119
PSA_ASSERT( psa_crypto_init( ) );
11191120

1120-
PSA_ASSERT( psa_allocate_key( &handle ) );
1121-
status = psa_import_key_to_handle( handle, type, data->x, data->len );
1121+
psa_set_key_type( &attributes, type );
1122+
status = psa_import_key( &attributes, &handle, data->x, data->len );
11221123
TEST_EQUAL( status, expected_status );
11231124
if( status == PSA_SUCCESS )
11241125
PSA_ASSERT( psa_destroy_key( handle ) );
@@ -1226,24 +1227,20 @@ void import_export( data_t *data,
12261227
size_t reexported_length;
12271228
psa_key_type_t got_type;
12281229
size_t got_bits;
1229-
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
1230+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
12301231

12311232
export_size = (ptrdiff_t) data->len + export_size_delta;
12321233
ASSERT_ALLOC( exported, export_size );
12331234
if( ! canonical_input )
12341235
ASSERT_ALLOC( reexported, export_size );
12351236
PSA_ASSERT( psa_crypto_init( ) );
12361237

1237-
PSA_ASSERT( psa_allocate_key( &handle ) );
1238-
psa_key_policy_set_usage( &policy, usage_arg, alg );
1239-
PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
1240-
1241-
TEST_EQUAL( psa_get_key_information( handle, NULL, NULL ),
1242-
PSA_ERROR_DOES_NOT_EXIST );
1238+
psa_set_key_usage_flags( &attributes, usage_arg );
1239+
psa_set_key_algorithm( &attributes, alg );
1240+
psa_set_key_type( &attributes, type );
12431241

12441242
/* Import the key */
1245-
PSA_ASSERT( psa_import_key_to_handle( handle, type,
1246-
data->x, data->len ) );
1243+
PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
12471244

12481245
/* Test the key information */
12491246
PSA_ASSERT( psa_get_key_information( handle,
@@ -1280,12 +1277,8 @@ void import_export( data_t *data,
12801277
else
12811278
{
12821279
psa_key_handle_t handle2;
1283-
PSA_ASSERT( psa_allocate_key( &handle2 ) );
1284-
PSA_ASSERT( psa_set_key_policy( handle2, &policy ) );
1285-
1286-
PSA_ASSERT( psa_import_key_to_handle( handle2, type,
1287-
exported,
1288-
exported_length ) );
1280+
PSA_ASSERT( psa_import_key( &attributes, &handle2,
1281+
exported, exported_length ) );
12891282
PSA_ASSERT( psa_export_key( handle2,
12901283
reexported,
12911284
export_size,
@@ -1525,17 +1518,16 @@ void import_export_public_key( data_t *data,
15251518
unsigned char *exported = NULL;
15261519
size_t export_size = expected_public_key->len + export_size_delta;
15271520
size_t exported_length = INVALID_EXPORT_LENGTH;
1528-
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
1521+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
15291522

15301523
PSA_ASSERT( psa_crypto_init( ) );
15311524

1532-
PSA_ASSERT( psa_allocate_key( &handle ) );
1533-
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
1534-
PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
1525+
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
1526+
psa_set_key_algorithm( &attributes, alg );
1527+
psa_set_key_type( &attributes, type );
15351528

15361529
/* Import the key */
1537-
PSA_ASSERT( psa_import_key_to_handle( handle, type,
1538-
data->x, data->len ) );
1530+
PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
15391531

15401532
/* Export the public key */
15411533
ASSERT_ALLOC( exported, export_size );
@@ -1572,20 +1564,18 @@ void import_and_exercise_key( data_t *data,
15721564
size_t bits = bits_arg;
15731565
psa_algorithm_t alg = alg_arg;
15741566
psa_key_usage_t usage = usage_to_exercise( type, alg );
1575-
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
1567+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
15761568
psa_key_type_t got_type;
15771569
size_t got_bits;
1578-
psa_status_t status;
15791570

15801571
PSA_ASSERT( psa_crypto_init( ) );
15811572

1582-
PSA_ASSERT( psa_allocate_key( &handle ) );
1583-
psa_key_policy_set_usage( &policy, usage, alg );
1584-
PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
1573+
psa_set_key_usage_flags( &attributes, usage );
1574+
psa_set_key_algorithm( &attributes, alg );
1575+
psa_set_key_type( &attributes, type );
15851576

15861577
/* Import the key */
1587-
status = psa_import_key_to_handle( handle, type, data->x, data->len );
1588-
PSA_ASSERT( status );
1578+
PSA_ASSERT( psa_import_key( &attributes, &handle, data->x, data->len ) );
15891579

15901580
/* Test the key information */
15911581
PSA_ASSERT( psa_get_key_information( handle,

0 commit comments

Comments
 (0)