Skip to content

Commit 1fe90fa

Browse files
authored
Merge pull request #101 from gilles-peskine-arm/psa-key_attributes-verify_attributes
Check unused attributes in import and copy
2 parents d22b6c4 + 4a64464 commit 1fe90fa

File tree

4 files changed

+205
-68
lines changed

4 files changed

+205
-68
lines changed

include/psa/crypto.h

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,10 @@ psa_status_t psa_close_key(psa_key_handle_t handle);
583583
* according to a different format.
584584
*
585585
* \param[in] attributes The attributes for the new key.
586-
* The key size field in \p attributes is
587-
* ignored; the actual key size is determined
588-
* from the \p data buffer.
586+
* The key size is always determined from the
587+
* \p data buffer.
588+
* If the key size in \p attributes is nonzero,
589+
* it must be equal to the size from \p data.
589590
* \param[out] handle On success, a handle to the newly created key.
590591
* \c 0 on failure.
591592
* \param[in] data Buffer containing the key data. The content of this
@@ -612,8 +613,12 @@ psa_status_t psa_close_key(psa_key_handle_t handle);
612613
* The key type or key size is not supported, either by the
613614
* implementation in general or in this particular persistent location.
614615
* \retval #PSA_ERROR_INVALID_ARGUMENT
615-
* The key attributes, as a whole, are invalid,
616-
* or the key data is not correctly formatted.
616+
* The key attributes, as a whole, are invalid.
617+
* \retval #PSA_ERROR_INVALID_ARGUMENT
618+
* The key data is not correctly formatted.
619+
* \retval #PSA_ERROR_INVALID_ARGUMENT
620+
* The size in \p attributes is nonzero and does not match the size
621+
* of the key data.
617622
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
618623
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
619624
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
@@ -859,9 +864,12 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle,
859864
* occupied slot.
860865
* \param[in] attributes The attributes for the new key.
861866
* They are used as follows:
862-
* - The key type, key size and domain parameters
863-
* are ignored. This information is copied
864-
* from the source key.
867+
* - The key type and size may be 0. If either is
868+
* nonzero, it must match the corresponding
869+
* attribute of the source key.
870+
* - If \p attributes contains domain parameters,
871+
* they must match the domain parameters of
872+
* the source key.
865873
* - The key location (the lifetime and, for
866874
* persistent keys, the key identifier) is
867875
* used directly.
@@ -884,6 +892,9 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle,
884892
* \retval #PSA_ERROR_INVALID_ARGUMENT
885893
* The policy constraints on the source and specified in
886894
* \p attributes are incompatible.
895+
* \retval #PSA_ERROR_INVALID_ARGUMENT
896+
* \p attributes specifies a key type, domain parameters or key size
897+
* which does not match the attributes of the source key.
887898
* \retval #PSA_ERROR_NOT_PERMITTED
888899
* The source key is not exportable and its lifetime does not
889900
* allow copying it to the target's lifetime.

library/psa_crypto.c

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,20 +1480,79 @@ static void psa_fail_key_creation( psa_key_slot_t *slot )
14801480
psa_wipe_key_slot( slot );
14811481
}
14821482

1483+
static psa_status_t psa_check_key_slot_attributes(
1484+
const psa_key_slot_t *slot,
1485+
const psa_key_attributes_t *attributes )
1486+
{
1487+
if( attributes->type != 0 )
1488+
{
1489+
if( attributes->type != slot->type )
1490+
return( PSA_ERROR_INVALID_ARGUMENT );
1491+
}
1492+
1493+
if( attributes->domain_parameters_size != 0 )
1494+
{
1495+
#if defined(MBEDTLS_RSA_C)
1496+
if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
1497+
{
1498+
mbedtls_mpi actual, required;
1499+
int ret;
1500+
mbedtls_mpi_init( &actual );
1501+
mbedtls_mpi_init( &required );
1502+
ret = mbedtls_rsa_export( slot->data.rsa,
1503+
NULL, NULL, NULL, NULL, &actual );
1504+
if( ret != 0 )
1505+
goto rsa_exit;
1506+
ret = mbedtls_mpi_read_binary( &required,
1507+
attributes->domain_parameters,
1508+
attributes->domain_parameters_size );
1509+
if( ret != 0 )
1510+
goto rsa_exit;
1511+
if( mbedtls_mpi_cmp_mpi( &actual, &required ) != 0 )
1512+
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1513+
rsa_exit:
1514+
mbedtls_mpi_free( &actual );
1515+
mbedtls_mpi_free( &required );
1516+
if( ret != 0)
1517+
return( mbedtls_to_psa_error( ret ) );
1518+
}
1519+
else
1520+
#endif
1521+
{
1522+
return( PSA_ERROR_INVALID_ARGUMENT );
1523+
}
1524+
}
1525+
1526+
if( attributes->bits != 0 )
1527+
{
1528+
if( attributes->bits != psa_get_key_slot_bits( slot ) )
1529+
return( PSA_ERROR_INVALID_ARGUMENT );
1530+
}
1531+
1532+
return( PSA_SUCCESS );
1533+
}
1534+
14831535
psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
14841536
psa_key_handle_t *handle,
14851537
const uint8_t *data,
14861538
size_t data_length )
14871539
{
14881540
psa_status_t status;
14891541
psa_key_slot_t *slot = NULL;
1542+
14901543
status = psa_start_key_creation( attributes, handle, &slot );
1491-
if( status == PSA_SUCCESS )
1492-
{
1493-
status = psa_import_key_into_slot( slot, data, data_length );
1494-
}
1495-
if( status == PSA_SUCCESS )
1496-
status = psa_finish_key_creation( slot );
1544+
if( status != PSA_SUCCESS )
1545+
goto exit;
1546+
1547+
status = psa_import_key_into_slot( slot, data, data_length );
1548+
if( status != PSA_SUCCESS )
1549+
goto exit;
1550+
status = psa_check_key_slot_attributes( slot, attributes );
1551+
if( status != PSA_SUCCESS )
1552+
goto exit;
1553+
1554+
status = psa_finish_key_creation( slot );
1555+
exit:
14971556
if( status != PSA_SUCCESS )
14981557
{
14991558
psa_fail_key_creation( slot );
@@ -1575,6 +1634,10 @@ psa_status_t psa_copy_key( psa_key_handle_t source_handle,
15751634
if( status != PSA_SUCCESS )
15761635
goto exit;
15771636

1637+
status = psa_check_key_slot_attributes( source_slot, specified_attributes );
1638+
if( status != PSA_SUCCESS )
1639+
goto exit;
1640+
15781641
status = psa_restrict_key_policy( &actual_attributes.policy,
15791642
&source_slot->policy );
15801643
if( status != PSA_SUCCESS )
@@ -1586,10 +1649,11 @@ psa_status_t psa_copy_key( psa_key_handle_t source_handle,
15861649
goto exit;
15871650

15881651
status = psa_copy_key_material( source_slot, target_slot );
1652+
if( status != PSA_SUCCESS )
1653+
goto exit;
15891654

1655+
status = psa_finish_key_creation( target_slot );
15901656
exit:
1591-
if( status == PSA_SUCCESS )
1592-
status = psa_finish_key_creation( target_slot );
15931657
if( status != PSA_SUCCESS )
15941658
{
15951659
psa_fail_key_creation( target_slot );

0 commit comments

Comments
 (0)