Skip to content

Commit 72f40c6

Browse files
authored
Merge pull request #59 from gilles-peskine-arm/psa-its-64_bit_internal_key_id
Support key file IDs encoding the key owner
2 parents 5483461 + 572f067 commit 72f40c6

12 files changed

+147
-35
lines changed

include/mbedtls/config.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,21 @@
11561156
*/
11571157
//#define MBEDTLS_PSA_HAS_ITS_IO
11581158

1159+
/* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
1160+
*
1161+
* In PSA key storage, encode the owner of the key.
1162+
*
1163+
* This is only meaningful when building the library as part of a
1164+
* multi-client service. When you activate this option, you must provide
1165+
* an implementation of the type psa_key_owner_id_t and a translation
1166+
* from psa_key_file_id_t to file name in all the storage backends that
1167+
* you wish to support.
1168+
*
1169+
* Note that this option is meant for internal use only and may be removed
1170+
* without notice.
1171+
*/
1172+
//#define MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
1173+
11591174
/**
11601175
* \def MBEDTLS_MEMORY_DEBUG
11611176
*

include/psa/crypto_platform.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,53 @@
4949
/* Integral type representing a key handle. */
5050
typedef uint16_t psa_key_handle_t;
5151

52+
/* This implementation distinguishes *application key identifiers*, which
53+
* are the key identifiers specified by the application, from
54+
* *key file identifiers*, which are the key identifiers that the library
55+
* sees internally. The two types can be different if there is a remote
56+
* call layer between the application and the library which supports
57+
* multiple client applications that do not have access to each others'
58+
* keys. The point of having different types is that the key file
59+
* identifier may encode not only the key identifier specified by the
60+
* application, but also the the identity of the application.
61+
*
62+
* Note that this is an internal concept of the library and the remote
63+
* call layer. The application itself never sees anything other than
64+
* #psa_app_key_id_t with its standard definition.
65+
*/
66+
67+
/* The application key identifier is always what the application sees as
68+
* #psa_key_id_t. */
69+
typedef uint32_t psa_app_key_id_t;
70+
71+
#if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER)
72+
73+
#if defined(PSA_CRYPTO_SECURE)
74+
/* Building for the PSA Crypto service on a PSA platform. */
75+
/* A key owner is a PSA partition identifier. */
76+
typedef int32_t psa_key_owner_id_t;
77+
#endif
78+
79+
typedef struct
80+
{
81+
uint32_t key_id;
82+
psa_key_owner_id_t owner;
83+
} psa_key_file_id_t;
84+
#define PSA_KEY_FILE_GET_KEY_ID( file_id ) ( ( file_id ).key_id )
85+
86+
/* Since crypto.h is used as part of the PSA Cryptography API specification,
87+
* it must use standard types for things like the argument of psa_open_key().
88+
* If it wasn't for that constraint, psa_open_key() would take a
89+
* `psa_key_file_id_t` argument. As a workaround, make `psa_key_id_t` an
90+
* alias for `psa_key_file_id_t` when building for a multi-client service. */
91+
typedef psa_key_file_id_t psa_key_id_t;
92+
93+
#else /* !MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */
94+
95+
/* By default, a key file identifier is just the application key identifier. */
96+
typedef psa_app_key_id_t psa_key_file_id_t;
97+
#define PSA_KEY_FILE_GET_KEY_ID( id ) ( id )
98+
99+
#endif /* !MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */
100+
52101
#endif /* PSA_CRYPTO_PLATFORM_H */

include/psa/crypto_types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,14 @@ typedef uint32_t psa_key_lifetime_t;
9090

9191
/** Encoding of identifiers of persistent keys.
9292
*/
93+
/* Implementation-specific quirk: The Mbed Crypto library can be built as
94+
* part of a multi-client service that exposes the PSA Crypto API in each
95+
* client and encodes the client identity in the key id argument of functions
96+
* such as psa_open_key(). In this build configuration, we define
97+
* psa_key_id_t in crypto_platform.h instead of here. */
98+
#if !defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER)
9399
typedef uint32_t psa_key_id_t;
100+
#endif
94101

95102
/**@}*/
96103

library/psa_crypto_core.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ typedef struct
4141
psa_key_type_t type;
4242
psa_key_policy_t policy;
4343
psa_key_lifetime_t lifetime;
44-
psa_key_id_t persistent_storage_id;
44+
psa_key_file_id_t persistent_storage_id;
4545
unsigned allocated : 1;
4646
union
4747
{

library/psa_crypto_slot_management.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,30 @@ static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot )
168168
psa_free_persistent_key_data( key_data, key_data_length );
169169
return( status );
170170
}
171+
172+
/** Check whether a key identifier is acceptable.
173+
*
174+
* For backward compatibility, key identifiers that were valid in a
175+
* past released version must remain valid, unless a migration path
176+
* is provided.
177+
*
178+
* \param file_id The key identifier to check.
179+
*
180+
* \return 1 if \p file_id is acceptable, otherwise 0.
181+
*/
182+
static int psa_is_key_id_valid( psa_key_file_id_t file_id )
183+
{
184+
psa_app_key_id_t key_id = PSA_KEY_FILE_GET_KEY_ID( file_id );
185+
/* Reject id=0 because by general library conventions, 0 is an invalid
186+
* value wherever possible. */
187+
if( key_id == 0 )
188+
return( 0 );
189+
/* Reject high values because the file names are reserved for the
190+
* library's internal use. */
191+
if( key_id > PSA_MAX_PERSISTENT_KEY_IDENTIFIER )
192+
return( 0 );
193+
return( 1 );
194+
}
171195
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
172196

173197
/** Declare a slot as persistent and load it from storage.
@@ -189,19 +213,13 @@ static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot )
189213
* \retval #PSA_ERROR_STORAGE_FAILURE
190214
*/
191215
static psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle,
192-
psa_key_id_t id )
216+
psa_key_file_id_t id )
193217
{
194218
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
195219
psa_key_slot_t *slot;
196220
psa_status_t status;
197221

198-
/* Reject id=0 because by general library conventions, 0 is an invalid
199-
* value wherever possible. */
200-
if( id == 0 )
201-
return( PSA_ERROR_INVALID_ARGUMENT );
202-
/* Reject high values because the file names are reserved for the
203-
* library's internal use. */
204-
if( id >= PSA_MAX_PERSISTENT_KEY_IDENTIFIER )
222+
if( ! psa_is_key_id_valid( id ) )
205223
return( PSA_ERROR_INVALID_ARGUMENT );
206224

207225
status = psa_get_key_slot( handle, &slot );
@@ -222,7 +240,7 @@ static psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle,
222240
}
223241

224242
static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime,
225-
psa_key_id_t id,
243+
psa_key_file_id_t id,
226244
psa_key_handle_t *handle,
227245
psa_status_t wanted_load_status )
228246
{
@@ -247,14 +265,14 @@ static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime,
247265
}
248266

249267
psa_status_t psa_open_key( psa_key_lifetime_t lifetime,
250-
psa_key_id_t id,
268+
psa_key_file_id_t id,
251269
psa_key_handle_t *handle )
252270
{
253271
return( persistent_key_setup( lifetime, id, handle, PSA_SUCCESS ) );
254272
}
255273

256274
psa_status_t psa_create_key( psa_key_lifetime_t lifetime,
257-
psa_key_id_t id,
275+
psa_key_file_id_t id,
258276
psa_key_handle_t *handle )
259277
{
260278
psa_status_t status;

library/psa_crypto_storage.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
149149
return( PSA_SUCCESS );
150150
}
151151

152-
psa_status_t psa_save_persistent_key( const psa_key_id_t key,
152+
psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
153153
const psa_key_type_t type,
154154
const psa_key_policy_t *policy,
155155
const uint8_t *data,
@@ -187,7 +187,7 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length )
187187
mbedtls_free( key_data );
188188
}
189189

190-
psa_status_t psa_load_persistent_key( psa_key_id_t key,
190+
psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
191191
psa_key_type_t *type,
192192
psa_key_policy_t *policy,
193193
uint8_t **data,

library/psa_crypto_storage.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ extern "C" {
5959
* This limitation will probably become moot when we implement client
6060
* separation for key storage.
6161
*/
62-
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xffff0000
62+
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xfffeffff
6363

6464
/**
6565
* \brief Format key data and metadata and save to a location for given key
@@ -86,7 +86,7 @@ extern "C" {
8686
* \retval PSA_ERROR_STORAGE_FAILURE
8787
* \retval PSA_ERROR_ALREADY_EXISTS
8888
*/
89-
psa_status_t psa_save_persistent_key( const psa_key_id_t key,
89+
psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
9090
const psa_key_type_t type,
9191
const psa_key_policy_t *policy,
9292
const uint8_t *data,
@@ -117,7 +117,7 @@ psa_status_t psa_save_persistent_key( const psa_key_id_t key,
117117
* \retval PSA_ERROR_STORAGE_FAILURE
118118
* \retval PSA_ERROR_DOES_NOT_EXIST
119119
*/
120-
psa_status_t psa_load_persistent_key( psa_key_id_t key,
120+
psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
121121
psa_key_type_t *type,
122122
psa_key_policy_t *policy,
123123
uint8_t **data,
@@ -134,7 +134,7 @@ psa_status_t psa_load_persistent_key( psa_key_id_t key,
134134
* or the key did not exist.
135135
* \retval PSA_ERROR_STORAGE_FAILURE
136136
*/
137-
psa_status_t psa_destroy_persistent_key( const psa_key_id_t key );
137+
psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key );
138138

139139
/**
140140
* \brief Free the temporary buffer allocated by psa_load_persistent_key().

library/psa_crypto_storage_backend.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ extern "C" {
5656
* \retval PSA_ERROR_STORAGE_FAILURE
5757
* \retval PSA_ERROR_DOES_NOT_EXIST
5858
*/
59-
psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
59+
psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key, uint8_t *data,
6060
size_t data_size );
6161

6262
/**
@@ -75,7 +75,7 @@ psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
7575
* \retval PSA_ERROR_STORAGE_FAILURE
7676
* \retval PSA_ERROR_ALREADY_EXISTS
7777
*/
78-
psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
78+
psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key,
7979
const uint8_t *data,
8080
size_t data_length );
8181

@@ -92,7 +92,7 @@ psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
9292
* \retval 1
9393
* Persistent data present for slot number
9494
*/
95-
int psa_is_key_present_in_storage( const psa_key_id_t key );
95+
int psa_is_key_present_in_storage( const psa_key_file_id_t key );
9696

9797
/**
9898
* \brief Get data length for given key slot number.
@@ -104,7 +104,7 @@ int psa_is_key_present_in_storage( const psa_key_id_t key );
104104
* \retval PSA_SUCCESS
105105
* \retval PSA_ERROR_STORAGE_FAILURE
106106
*/
107-
psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key,
107+
psa_status_t psa_crypto_storage_get_data_length( const psa_key_file_id_t key,
108108
size_t *data_length );
109109

110110

library/psa_crypto_storage_file.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949

5050
enum { MAX_LOCATION_LEN = sizeof(CRYPTO_STORAGE_FILE_LOCATION) + 40 };
5151

52-
static void key_id_to_location( const psa_key_id_t key,
52+
static void key_id_to_location( const psa_key_file_id_t key,
5353
char *location,
5454
size_t location_size )
5555
{
@@ -58,7 +58,7 @@ static void key_id_to_location( const psa_key_id_t key,
5858
(unsigned long) key );
5959
}
6060

61-
psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
61+
psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key, uint8_t *data,
6262
size_t data_size )
6363
{
6464
psa_status_t status = PSA_SUCCESS;
@@ -83,7 +83,7 @@ psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
8383
return( status );
8484
}
8585

86-
int psa_is_key_present_in_storage( const psa_key_id_t key )
86+
int psa_is_key_present_in_storage( const psa_key_file_id_t key )
8787
{
8888
char slot_location[MAX_LOCATION_LEN];
8989
FILE *file;
@@ -101,7 +101,7 @@ int psa_is_key_present_in_storage( const psa_key_id_t key )
101101
return( 1 );
102102
}
103103

104-
psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
104+
psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key,
105105
const uint8_t *data,
106106
size_t data_length )
107107
{
@@ -156,7 +156,7 @@ psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
156156
return( status );
157157
}
158158

159-
psa_status_t psa_destroy_persistent_key( const psa_key_id_t key )
159+
psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key )
160160
{
161161
FILE *file;
162162
char slot_location[MAX_LOCATION_LEN];
@@ -175,7 +175,7 @@ psa_status_t psa_destroy_persistent_key( const psa_key_id_t key )
175175
return( PSA_SUCCESS );
176176
}
177177

178-
psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key,
178+
psa_status_t psa_crypto_storage_get_data_length( const psa_key_file_id_t key,
179179
size_t *data_length )
180180
{
181181
psa_status_t status = PSA_SUCCESS;

library/psa_crypto_storage_its.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,31 @@
3737
#include "mbedtls/platform.h"
3838
#endif
3939

40-
static psa_storage_uid_t psa_its_identifier_of_slot( psa_key_id_t key )
40+
/* Determine a file name (ITS file identifier) for the given key file
41+
* identifier. The file name must be distinct from any file that is used
42+
* for a purpose other than storing a key. Currently, the only such file
43+
* is the random seed file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID
44+
* and whose value is 0xFFFFFF52. */
45+
static psa_storage_uid_t psa_its_identifier_of_slot( psa_key_file_id_t file_id )
4146
{
42-
return( key );
47+
#if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER) && \
48+
defined(PSA_CRYPTO_SECURE)
49+
/* Encode the owner in the upper 32 bits. This means that if
50+
* owner values are nonzero (as they are on a PSA platform),
51+
* no key file will ever have a value less than 0x100000000, so
52+
* the whole range 0..0xffffffff is available for non-key files. */
53+
uint32_t unsigned_owner = (uint32_t) file_id.owner;
54+
return( (uint64_t) unsigned_owner << 32 | file_id.key_id );
55+
#else
56+
/* Use the key id directly as a file name.
57+
* psa_is_key_file_id_valid() in psa_crypto_slot_management.c
58+
* is responsible for ensuring that key identifiers do not have a
59+
* value that is reserved for non-key files. */
60+
return( file_id );
61+
#endif
4362
}
4463

45-
psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
64+
psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key, uint8_t *data,
4665
size_t data_size )
4766
{
4867
psa_status_t status;
@@ -58,7 +77,7 @@ psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
5877
return( status );
5978
}
6079

61-
int psa_is_key_present_in_storage( const psa_key_id_t key )
80+
int psa_is_key_present_in_storage( const psa_key_file_id_t key )
6281
{
6382
psa_status_t ret;
6483
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
@@ -71,7 +90,7 @@ int psa_is_key_present_in_storage( const psa_key_id_t key )
7190
return( 1 );
7291
}
7392

74-
psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
93+
psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key,
7594
const uint8_t *data,
7695
size_t data_length )
7796
{
@@ -106,7 +125,7 @@ psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
106125
return( status );
107126
}
108127

109-
psa_status_t psa_destroy_persistent_key( const psa_key_id_t key )
128+
psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key )
110129
{
111130
psa_status_t ret;
112131
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
@@ -126,7 +145,7 @@ psa_status_t psa_destroy_persistent_key( const psa_key_id_t key )
126145
return( PSA_SUCCESS );
127146
}
128147

129-
psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key,
148+
psa_status_t psa_crypto_storage_get_data_length( const psa_key_file_id_t key,
130149
size_t *data_length )
131150
{
132151
psa_status_t status;

0 commit comments

Comments
 (0)