@@ -1403,10 +1403,14 @@ psa_status_t psa_export_public_key( psa_key_handle_t handle,
1403
1403
data_length , 1 ) );
1404
1404
}
1405
1405
1406
- static psa_status_t psa_check_key_slot_policy (
1407
- const psa_key_slot_t * slot )
1406
+ /** Validate that a key policy is internally well-formed.
1407
+ *
1408
+ * This function only rejects invalid policies. It does not validate the
1409
+ * consistency of the policy with respect to other attributes of the key
1410
+ * such as the key type.
1411
+ */
1412
+ static psa_status_t psa_validate_key_policy ( const psa_key_policy_t * policy )
1408
1413
{
1409
- const psa_key_policy_t * policy = & slot -> attr .policy ;
1410
1414
if ( ( policy -> usage & ~( PSA_KEY_USAGE_EXPORT |
1411
1415
PSA_KEY_USAGE_COPY |
1412
1416
PSA_KEY_USAGE_ENCRYPT |
@@ -1419,6 +1423,48 @@ static psa_status_t psa_check_key_slot_policy(
1419
1423
return ( PSA_SUCCESS );
1420
1424
}
1421
1425
1426
+ /** Validate the internal consistency of key attributes.
1427
+ *
1428
+ * This function only rejects invalid attribute values. If does not
1429
+ * validate the consistency of the attributes with any key data that may
1430
+ * be involved in the creation of the key.
1431
+ *
1432
+ * Call this function early in the key creation process.
1433
+ *
1434
+ * \param[in] attributes Key attributes for the new key.
1435
+ * \param[out] p_drv On any return, the driver for the key, if any.
1436
+ * NULL for a transparent key.
1437
+ *
1438
+ */
1439
+ static psa_status_t psa_validate_key_attributes (
1440
+ const psa_key_attributes_t * attributes ,
1441
+ psa_se_drv_table_entry_t * * p_drv )
1442
+ {
1443
+ psa_status_t status ;
1444
+
1445
+ if ( attributes -> core .lifetime != PSA_KEY_LIFETIME_VOLATILE )
1446
+ {
1447
+ status = psa_validate_persistent_key_parameters (
1448
+ attributes -> core .lifetime , attributes -> core .id ,
1449
+ p_drv , 1 );
1450
+ if ( status != PSA_SUCCESS )
1451
+ return ( status );
1452
+ }
1453
+
1454
+ status = psa_validate_key_policy ( & attributes -> core .policy );
1455
+ if ( status != PSA_SUCCESS )
1456
+ return ( status );
1457
+
1458
+ /* Refuse to create overly large keys.
1459
+ * Note that this doesn't trigger on import if the attributes don't
1460
+ * explicitly specify a size (so psa_get_key_bits returns 0), so
1461
+ * psa_import_key() needs its own checks. */
1462
+ if ( psa_get_key_bits ( attributes ) > PSA_MAX_KEY_BITS )
1463
+ return ( PSA_ERROR_NOT_SUPPORTED );
1464
+
1465
+ return ( PSA_SUCCESS );
1466
+ }
1467
+
1422
1468
/** Prepare a key slot to receive key material.
1423
1469
*
1424
1470
* This function allocates a key slot and sets its metadata.
@@ -1455,26 +1501,15 @@ static psa_status_t psa_start_key_creation(
1455
1501
1456
1502
* p_drv = NULL ;
1457
1503
1504
+ status = psa_validate_key_attributes ( attributes , p_drv );
1505
+ if ( status != PSA_SUCCESS )
1506
+ return ( status );
1507
+
1458
1508
status = psa_internal_allocate_key_slot ( handle , p_slot );
1459
1509
if ( status != PSA_SUCCESS )
1460
1510
return ( status );
1461
1511
slot = * p_slot ;
1462
1512
1463
- if ( attributes -> core .lifetime != PSA_KEY_LIFETIME_VOLATILE )
1464
- {
1465
- status = psa_validate_persistent_key_parameters ( attributes -> core .lifetime ,
1466
- attributes -> core .id ,
1467
- p_drv , 1 );
1468
- if ( status != PSA_SUCCESS )
1469
- return ( status );
1470
- }
1471
-
1472
- /* Refuse to create overly large keys.
1473
- * Note that this doesn't trigger on import if the attributes don't
1474
- * explicitly specify a size (so psa_get_key_bits returns 0), so
1475
- * psa_import_key() needs its own checks. */
1476
- if ( psa_get_key_bits ( attributes ) > PSA_MAX_KEY_BITS )
1477
- return ( PSA_ERROR_NOT_SUPPORTED );
1478
1513
/* We're storing the declared bit-size of the key. It's up to each
1479
1514
* creation mechanism to verify that this information is correct.
1480
1515
* It's automatically correct for mechanisms that use the bit-size as
@@ -1483,10 +1518,6 @@ static psa_status_t psa_start_key_creation(
1483
1518
1484
1519
slot -> attr = attributes -> core ;
1485
1520
1486
- status = psa_check_key_slot_policy ( slot );
1487
- if ( status != PSA_SUCCESS )
1488
- return ( status );
1489
-
1490
1521
#if defined(MBEDTLS_PSA_CRYPTO_SE_C )
1491
1522
/* For a key in a secure element, we need to do three things:
1492
1523
* create the key file in internal storage, create the
@@ -1647,7 +1678,16 @@ static void psa_fail_key_creation( psa_key_slot_t *slot,
1647
1678
psa_wipe_key_slot ( slot );
1648
1679
}
1649
1680
1650
- static psa_status_t psa_check_key_slot_attributes (
1681
+ /** Validate optional attributes during key creation.
1682
+ *
1683
+ * Some key attributes are optional during key creation. If they are
1684
+ * specified in the attributes structure, check that they are consistent
1685
+ * with the data in the slot.
1686
+ *
1687
+ * This function should be called near the end of key creation, after
1688
+ * the slot in memory is fully populated but before saving persistent data.
1689
+ */
1690
+ static psa_status_t psa_validate_optional_attributes (
1651
1691
const psa_key_slot_t * slot ,
1652
1692
const psa_key_attributes_t * attributes )
1653
1693
{
@@ -1746,7 +1786,7 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
1746
1786
if ( status != PSA_SUCCESS )
1747
1787
goto exit ;
1748
1788
}
1749
- status = psa_check_key_slot_attributes ( slot , attributes );
1789
+ status = psa_validate_optional_attributes ( slot , attributes );
1750
1790
if ( status != PSA_SUCCESS )
1751
1791
goto exit ;
1752
1792
@@ -1801,7 +1841,8 @@ psa_status_t psa_copy_key( psa_key_handle_t source_handle,
1801
1841
if ( status != PSA_SUCCESS )
1802
1842
goto exit ;
1803
1843
1804
- status = psa_check_key_slot_attributes ( source_slot , specified_attributes );
1844
+ status = psa_validate_optional_attributes ( source_slot ,
1845
+ specified_attributes );
1805
1846
if ( status != PSA_SUCCESS )
1806
1847
goto exit ;
1807
1848
0 commit comments