Skip to content

Commit 640804b

Browse files
Merge pull request #191 from gilles-peskine-arm/psa-se_driver-key_bits
Secure element keys: save the key size
2 parents adb1c52 + fc321f1 commit 640804b

File tree

5 files changed

+97
-40
lines changed

5 files changed

+97
-40
lines changed

include/psa/crypto_se_driver.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -833,14 +833,18 @@ typedef psa_status_t (*psa_drv_se_allocate_key_t)(
833833
*
834834
* \param[in,out] drv_context The driver context structure.
835835
* \param[in] key_slot Slot where the key will be stored
836-
* This must be a valid slot for a key of the chosen
837-
* type. It must be unoccupied.
836+
* This must be a valid slot for a key of the
837+
* chosen type. It must be unoccupied.
838838
* \param[in] lifetime The required lifetime of the key storage
839839
* \param[in] type Key type (a \c PSA_KEY_TYPE_XXX value)
840840
* \param[in] algorithm Key algorithm (a \c PSA_ALG_XXX value)
841841
* \param[in] usage The allowed uses of the key
842842
* \param[in] p_data Buffer containing the key data
843843
* \param[in] data_length Size of the `data` buffer in bytes
844+
* \param[out] bits On success, the key size in bits. The driver
845+
* must determine this value after parsing the
846+
* key according to the key type.
847+
* This value is not used if the function fails.
844848
*
845849
* \retval #PSA_SUCCESS
846850
* Success.
@@ -852,7 +856,8 @@ typedef psa_status_t (*psa_drv_se_import_key_t)(psa_drv_se_context_t *drv_contex
852856
psa_algorithm_t algorithm,
853857
psa_key_usage_t usage,
854858
const uint8_t *p_data,
855-
size_t data_length);
859+
size_t data_length,
860+
size_t *bits);
856861

857862
/**
858863
* \brief A function that destroys a secure element key and restore the slot to

library/psa_crypto.c

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,11 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle )
10351035
/* Return the size of the key in the given slot, in bits. */
10361036
static size_t psa_get_key_slot_bits( const psa_key_slot_t *slot )
10371037
{
1038+
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1039+
if( psa_get_se_driver( slot->lifetime, NULL, NULL ) )
1040+
return( slot->data.se.bits );
1041+
#endif /* defined(MBEDTLS_PSA_CRYPTO_SE_C) */
1042+
10381043
if( key_type_is_raw_bytes( slot->type ) )
10391044
return( slot->data.raw.bytes * 8 );
10401045
#if defined(MBEDTLS_RSA_C)
@@ -1140,10 +1145,10 @@ static psa_status_t psa_get_rsa_public_exponent(
11401145
}
11411146
#endif /* MBEDTLS_RSA_C */
11421147

1143-
/** Retrieve the readily-accessible attributes of a key in a slot.
1148+
/** Retrieve the generic attributes of a key in a slot.
11441149
*
1145-
* This function does not compute attributes that are not directly
1146-
* stored in the slot, such as the bit size of a transparent key.
1150+
* This function does not retrieve domain parameters, which require
1151+
* additional memory management.
11471152
*/
11481153
static void psa_get_key_slot_attributes( psa_key_slot_t *slot,
11491154
psa_key_attributes_t *attributes )
@@ -1152,6 +1157,7 @@ static void psa_get_key_slot_attributes( psa_key_slot_t *slot,
11521157
attributes->lifetime = slot->lifetime;
11531158
attributes->policy = slot->policy;
11541159
attributes->type = slot->type;
1160+
attributes->bits = psa_get_key_slot_bits( slot );
11551161
}
11561162

11571163
/** Retrieve all the publicly-accessible attributes of a key.
@@ -1164,21 +1170,26 @@ psa_status_t psa_get_key_attributes( psa_key_handle_t handle,
11641170

11651171
psa_reset_key_attributes( attributes );
11661172

1167-
status = psa_get_transparent_key( handle, &slot, 0, 0 );
1173+
status = psa_get_key_from_slot( handle, &slot, 0, 0 );
11681174
if( status != PSA_SUCCESS )
11691175
return( status );
11701176

11711177
psa_get_key_slot_attributes( slot, attributes );
1172-
attributes->bits = psa_get_key_slot_bits( slot );
11731178

11741179
switch( slot->type )
11751180
{
11761181
#if defined(MBEDTLS_RSA_C)
11771182
case PSA_KEY_TYPE_RSA_KEY_PAIR:
11781183
case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
1184+
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1185+
/* TOnogrepDO: reporting the public exponent for opaque keys
1186+
* is not yet implemented. */
1187+
if( psa_get_se_driver( slot->lifetime, NULL, NULL ) )
1188+
break;
1189+
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
11791190
status = psa_get_rsa_public_exponent( slot->data.rsa, attributes );
11801191
break;
1181-
#endif
1192+
#endif /* MBEDTLS_RSA_C */
11821193
default:
11831194
/* Nothing else to do. */
11841195
break;
@@ -1489,6 +1500,10 @@ static psa_status_t psa_start_key_creation(
14891500
(void) psa_crypto_stop_transaction( );
14901501
return( status );
14911502
}
1503+
1504+
/* TOnogrepDO: validate bits. How to do this depends on the key
1505+
* creation method, so setting bits might not belong here. */
1506+
slot->data.se.bits = psa_get_key_bits( attributes );
14921507
}
14931508
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
14941509

@@ -1523,40 +1538,32 @@ static psa_status_t psa_finish_key_creation(
15231538
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
15241539
if( slot->lifetime != PSA_KEY_LIFETIME_VOLATILE )
15251540
{
1526-
uint8_t *buffer = NULL;
1527-
size_t buffer_size = 0;
1528-
size_t length = 0;
1541+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1542+
psa_get_key_slot_attributes( slot, &attributes );
15291543

15301544
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
15311545
if( driver != NULL )
15321546
{
1533-
buffer = (uint8_t*) &slot->data.se.slot_number;
1534-
length = sizeof( slot->data.se.slot_number );
1547+
status = psa_save_persistent_key( &attributes,
1548+
(uint8_t*) &slot->data.se,
1549+
sizeof( slot->data.se ) );
15351550
}
15361551
else
15371552
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
15381553
{
1539-
buffer_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type,
1540-
psa_get_key_slot_bits( slot ) );
1541-
buffer = mbedtls_calloc( 1, buffer_size );
1554+
size_t buffer_size =
1555+
PSA_KEY_EXPORT_MAX_SIZE( slot->type,
1556+
psa_get_key_bits( &attributes ) );
1557+
uint8_t *buffer = mbedtls_calloc( 1, buffer_size );
1558+
size_t length = 0;
15421559
if( buffer == NULL && buffer_size != 0 )
15431560
return( PSA_ERROR_INSUFFICIENT_MEMORY );
15441561
status = psa_internal_export_key( slot,
15451562
buffer, buffer_size, &length,
15461563
0 );
1547-
}
1564+
if( status == PSA_SUCCESS )
1565+
status = psa_save_persistent_key( &attributes, buffer, length );
15481566

1549-
if( status == PSA_SUCCESS )
1550-
{
1551-
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1552-
psa_get_key_slot_attributes( slot, &attributes );
1553-
status = psa_save_persistent_key( &attributes, buffer, length );
1554-
}
1555-
1556-
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1557-
if( driver == NULL )
1558-
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1559-
{
15601567
if( buffer_size != 0 )
15611568
mbedtls_platform_zeroize( buffer, buffer_size );
15621569
mbedtls_free( buffer );
@@ -1696,19 +1703,19 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
16961703
psa_get_se_driver_context( driver ),
16971704
slot->data.se.slot_number,
16981705
slot->lifetime, slot->type, slot->policy.alg, slot->policy.usage,
1699-
data, data_length );
1700-
/* TOnogrepDO: psa_check_key_slot_attributes? */
1706+
data, data_length,
1707+
&slot->data.se.bits );
17011708
}
17021709
else
17031710
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
17041711
{
17051712
status = psa_import_key_into_slot( slot, data, data_length );
17061713
if( status != PSA_SUCCESS )
17071714
goto exit;
1708-
status = psa_check_key_slot_attributes( slot, attributes );
1709-
if( status != PSA_SUCCESS )
1710-
goto exit;
17111715
}
1716+
status = psa_check_key_slot_attributes( slot, attributes );
1717+
if( status != PSA_SUCCESS )
1718+
goto exit;
17121719

17131720
status = psa_finish_key_creation( slot, driver );
17141721
exit:

library/psa_crypto_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ typedef struct
6464
struct se
6565
{
6666
psa_key_slot_number_t slot_number;
67+
size_t bits;
6768
} se;
6869
} data;
6970
} psa_key_slot_t;

library/psa_crypto_slot_management.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,12 @@ static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot )
138138
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
139139
if( psa_key_lifetime_is_external( p_slot->lifetime ) )
140140
{
141-
if( key_data_length != sizeof( p_slot->data.se.slot_number ) )
141+
if( key_data_length != sizeof( p_slot->data.se ) )
142142
{
143143
status = PSA_ERROR_STORAGE_FAILURE;
144144
goto exit;
145145
}
146-
memcpy( &p_slot->data.se.slot_number, key_data,
147-
sizeof( p_slot->data.se.slot_number ) );
146+
memcpy( &p_slot->data.se, key_data, sizeof( p_slot->data.se ) );
148147
}
149148
else
150149
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */

tests/suites/test_suite_psa_crypto_se_driver_hal.function

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ static psa_status_t null_import( psa_drv_se_context_t *context,
6262
psa_algorithm_t algorithm,
6363
psa_key_usage_t usage,
6464
const uint8_t *p_data,
65-
size_t data_length )
65+
size_t data_length,
66+
size_t *bits )
6667
{
6768
(void) context;
6869
(void) slot_number;
@@ -71,7 +72,9 @@ static psa_status_t null_import( psa_drv_se_context_t *context,
7172
(void) algorithm;
7273
(void) usage;
7374
(void) p_data;
74-
(void) data_length;
75+
/* We're supposed to return a key size. Return one that's correct for
76+
* plain data keys. */
77+
*bits = PSA_BYTES_TO_BITS( data_length );
7578
return( PSA_SUCCESS );
7679
}
7780

@@ -110,7 +113,8 @@ static psa_status_t ram_import( psa_drv_se_context_t *context,
110113
psa_algorithm_t algorithm,
111114
psa_key_usage_t usage,
112115
const uint8_t *p_data,
113-
size_t data_length )
116+
size_t data_length,
117+
size_t *bits )
114118
{
115119
(void) context;
116120
DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) );
@@ -119,6 +123,7 @@ static psa_status_t ram_import( psa_drv_se_context_t *context,
119123
ram_slots[slot_number].lifetime = lifetime;
120124
ram_slots[slot_number].type = type;
121125
ram_slots[slot_number].bits = PSA_BYTES_TO_BITS( data_length );
126+
*bits = PSA_BYTES_TO_BITS( data_length );
122127
(void) algorithm;
123128
(void) usage;
124129
memcpy( ram_slots[slot_number].content, p_data, data_length );
@@ -178,6 +183,41 @@ static psa_status_t ram_allocate( psa_drv_se_context_t *context,
178183
/* Other test helper functions */
179184
/****************************************************************/
180185

186+
/* Check that the attributes of a key reported by psa_get_key_attributes()
187+
* are consistent with the attributes used when creating the key. */
188+
static int check_key_attributes(
189+
psa_key_handle_t handle,
190+
const psa_key_attributes_t *reference_attributes )
191+
{
192+
int ok = 0;
193+
psa_key_attributes_t actual_attributes = PSA_KEY_ATTRIBUTES_INIT;
194+
195+
PSA_ASSERT( psa_get_key_attributes( handle, &actual_attributes ) );
196+
197+
TEST_EQUAL( psa_get_key_id( &actual_attributes ),
198+
psa_get_key_id( reference_attributes ) );
199+
TEST_EQUAL( psa_get_key_lifetime( &actual_attributes ),
200+
psa_get_key_lifetime( reference_attributes ) );
201+
TEST_EQUAL( psa_get_key_type( &actual_attributes ),
202+
psa_get_key_type( reference_attributes ) );
203+
TEST_EQUAL( psa_get_key_usage_flags( &actual_attributes ),
204+
psa_get_key_usage_flags( reference_attributes ) );
205+
TEST_EQUAL( psa_get_key_algorithm( &actual_attributes ),
206+
psa_get_key_algorithm( reference_attributes ) );
207+
TEST_EQUAL( psa_get_key_enrollment_algorithm( &actual_attributes ),
208+
psa_get_key_enrollment_algorithm( reference_attributes ) );
209+
if( psa_get_key_bits( reference_attributes ) != 0 )
210+
{
211+
TEST_EQUAL( psa_get_key_bits( &actual_attributes ),
212+
psa_get_key_bits( reference_attributes ) );
213+
}
214+
215+
ok = 1;
216+
217+
exit:
218+
return( ok );
219+
}
220+
181221
/* Check that a function's return status is "smoke-free", i.e. that
182222
* it's an acceptable error code when calling an API function that operates
183223
* on a key with potentially bogus parameters. */
@@ -445,6 +485,11 @@ void key_creation_import_export( int min_slot, int restart )
445485
/* Test that the key was created in the expected slot. */
446486
TEST_ASSERT( ram_slots[min_slot].type == PSA_KEY_TYPE_RAW_DATA );
447487

488+
/* Test the key attributes and the key data. */
489+
psa_set_key_bits( &attributes,
490+
PSA_BYTES_TO_BITS( sizeof( key_material ) ) );
491+
if( ! check_key_attributes( handle, &attributes ) )
492+
goto exit;
448493
PSA_ASSERT( psa_export_key( handle,
449494
exported, sizeof( exported ),
450495
&exported_length ) );

0 commit comments

Comments
 (0)