Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
psa_crypto_storage.c
00001 /* 00002 * PSA persistent key storage 00003 */ 00004 /* Copyright (C) 2018, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 #if defined(MBEDTLS_CONFIG_FILE) 00023 #include MBEDTLS_CONFIG_FILE 00024 #else 00025 #include "mbedtls/config.h" 00026 #endif 00027 00028 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) 00029 00030 #include <stdlib.h> 00031 #include <string.h> 00032 00033 #include "psa_crypto_service_integration.h" 00034 #include "psa/crypto.h" 00035 #include "psa_crypto_storage.h" 00036 #include "mbedtls/platform_util.h" 00037 00038 #if defined(MBEDTLS_PSA_ITS_FILE_C) 00039 #include "psa_crypto_its.h" 00040 #else /* Native ITS implementation */ 00041 #include "psa/error.h" 00042 #include "psa/internal_trusted_storage.h" 00043 #endif 00044 00045 #if defined(MBEDTLS_PLATFORM_C) 00046 #include "mbedtls/platform.h" 00047 #else 00048 #include <stdlib.h> 00049 #define mbedtls_calloc calloc 00050 #define mbedtls_free free 00051 #endif 00052 00053 00054 00055 /****************************************************************/ 00056 /* Key storage */ 00057 /****************************************************************/ 00058 00059 /* Determine a file name (ITS file identifier) for the given key file 00060 * identifier. The file name must be distinct from any file that is used 00061 * for a purpose other than storing a key. Currently, the only such file 00062 * is the random seed file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID 00063 * and whose value is 0xFFFFFF52. */ 00064 static psa_storage_uid_t psa_its_identifier_of_slot( psa_key_file_id_t file_id ) 00065 { 00066 #if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER) && \ 00067 defined(PSA_CRYPTO_SECURE) 00068 /* Encode the owner in the upper 32 bits. This means that if 00069 * owner values are nonzero (as they are on a PSA platform), 00070 * no key file will ever have a value less than 0x100000000, so 00071 * the whole range 0..0xffffffff is available for non-key files. */ 00072 uint32_t unsigned_owner = (uint32_t) file_id.owner; 00073 return( (uint64_t) unsigned_owner << 32 | file_id.key_id ); 00074 #else 00075 /* Use the key id directly as a file name. 00076 * psa_is_key_file_id_valid() in psa_crypto_slot_management.c 00077 * is responsible for ensuring that key identifiers do not have a 00078 * value that is reserved for non-key files. */ 00079 return( file_id ); 00080 #endif 00081 } 00082 00083 /** 00084 * \brief Load persistent data for the given key slot number. 00085 * 00086 * This function reads data from a storage backend and returns the data in a 00087 * buffer. 00088 * 00089 * \param key Persistent identifier of the key to be loaded. This 00090 * should be an occupied storage location. 00091 * \param[out] data Buffer where the data is to be written. 00092 * \param data_size Size of the \c data buffer in bytes. 00093 * 00094 * \retval PSA_SUCCESS 00095 * \retval PSA_ERROR_STORAGE_FAILURE 00096 * \retval PSA_ERROR_DOES_NOT_EXIST 00097 */ 00098 static psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key, 00099 uint8_t *data, 00100 size_t data_size ) 00101 { 00102 psa_status_t status; 00103 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key ); 00104 struct psa_storage_info_t data_identifier_info; 00105 size_t data_length = 0; 00106 00107 status = psa_its_get_info( data_identifier, &data_identifier_info ); 00108 if( status != PSA_SUCCESS ) 00109 return( status ); 00110 00111 status = psa_its_get( data_identifier, 0, (uint32_t) data_size, data, &data_length ); 00112 if( data_size != data_length ) 00113 return( PSA_ERROR_STORAGE_FAILURE ); 00114 00115 return( status ); 00116 } 00117 00118 int psa_is_key_present_in_storage( const psa_key_file_id_t key ) 00119 { 00120 psa_status_t ret; 00121 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key ); 00122 struct psa_storage_info_t data_identifier_info; 00123 00124 ret = psa_its_get_info( data_identifier, &data_identifier_info ); 00125 00126 if( ret == PSA_ERROR_DOES_NOT_EXIST ) 00127 return( 0 ); 00128 return( 1 ); 00129 } 00130 00131 /** 00132 * \brief Store persistent data for the given key slot number. 00133 * 00134 * This function stores the given data buffer to a persistent storage. 00135 * 00136 * \param key Persistent identifier of the key to be stored. This 00137 * should be an unoccupied storage location. 00138 * \param[in] data Buffer containing the data to be stored. 00139 * \param data_length The number of bytes 00140 * that make up the data. 00141 * 00142 * \retval PSA_SUCCESS 00143 * \retval PSA_ERROR_INSUFFICIENT_STORAGE 00144 * \retval PSA_ERROR_STORAGE_FAILURE 00145 * \retval PSA_ERROR_ALREADY_EXISTS 00146 */ 00147 static psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key, 00148 const uint8_t *data, 00149 size_t data_length ) 00150 { 00151 psa_status_t status; 00152 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key ); 00153 struct psa_storage_info_t data_identifier_info; 00154 00155 if( psa_is_key_present_in_storage( key ) == 1 ) 00156 return( PSA_ERROR_ALREADY_EXISTS ); 00157 00158 status = psa_its_set( data_identifier, (uint32_t) data_length, data, 0 ); 00159 if( status != PSA_SUCCESS ) 00160 { 00161 return( PSA_ERROR_STORAGE_FAILURE ); 00162 } 00163 00164 status = psa_its_get_info( data_identifier, &data_identifier_info ); 00165 if( status != PSA_SUCCESS ) 00166 { 00167 goto exit; 00168 } 00169 00170 if( data_identifier_info.size != data_length ) 00171 { 00172 status = PSA_ERROR_STORAGE_FAILURE; 00173 goto exit; 00174 } 00175 00176 exit: 00177 if( status != PSA_SUCCESS ) 00178 psa_its_remove( data_identifier ); 00179 return( status ); 00180 } 00181 00182 psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key ) 00183 { 00184 psa_status_t ret; 00185 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key ); 00186 struct psa_storage_info_t data_identifier_info; 00187 00188 ret = psa_its_get_info( data_identifier, &data_identifier_info ); 00189 if( ret == PSA_ERROR_DOES_NOT_EXIST ) 00190 return( PSA_SUCCESS ); 00191 00192 if( psa_its_remove( data_identifier ) != PSA_SUCCESS ) 00193 return( PSA_ERROR_STORAGE_FAILURE ); 00194 00195 ret = psa_its_get_info( data_identifier, &data_identifier_info ); 00196 if( ret != PSA_ERROR_DOES_NOT_EXIST ) 00197 return( PSA_ERROR_STORAGE_FAILURE ); 00198 00199 return( PSA_SUCCESS ); 00200 } 00201 00202 /** 00203 * \brief Get data length for given key slot number. 00204 * 00205 * \param key Persistent identifier whose stored data length 00206 * is to be obtained. 00207 * \param[out] data_length The number of bytes that make up the data. 00208 * 00209 * \retval PSA_SUCCESS 00210 * \retval PSA_ERROR_STORAGE_FAILURE 00211 */ 00212 static psa_status_t psa_crypto_storage_get_data_length( 00213 const psa_key_file_id_t key, 00214 size_t *data_length ) 00215 { 00216 psa_status_t status; 00217 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key ); 00218 struct psa_storage_info_t data_identifier_info; 00219 00220 status = psa_its_get_info( data_identifier, &data_identifier_info ); 00221 if( status != PSA_SUCCESS ) 00222 return( status ); 00223 00224 *data_length = (size_t) data_identifier_info.size; 00225 00226 return( PSA_SUCCESS ); 00227 } 00228 00229 /* 00230 * 32-bit integer manipulation macros (little endian) 00231 */ 00232 #ifndef GET_UINT32_LE 00233 #define GET_UINT32_LE( n, b, i ) \ 00234 { \ 00235 (n) = ( (uint32_t) (b)[(i) ] ) \ 00236 | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 00237 | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 00238 | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 00239 } 00240 #endif 00241 00242 #ifndef PUT_UINT32_LE 00243 #define PUT_UINT32_LE( n, b, i ) \ 00244 { \ 00245 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ 00246 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ 00247 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ 00248 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ 00249 } 00250 #endif 00251 00252 /** 00253 * Persistent key storage magic header. 00254 */ 00255 #define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY" 00256 #define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ( sizeof( PSA_KEY_STORAGE_MAGIC_HEADER ) ) 00257 00258 typedef struct { 00259 uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH]; 00260 uint8_t version[4]; 00261 uint8_t lifetime[sizeof( psa_key_lifetime_t )]; 00262 uint8_t type[sizeof( psa_key_type_t )]; 00263 uint8_t policy[sizeof( psa_key_policy_t )]; 00264 uint8_t data_len[4]; 00265 uint8_t key_data[]; 00266 } psa_persistent_key_storage_format; 00267 00268 void psa_format_key_data_for_storage( const uint8_t *data, 00269 const size_t data_length, 00270 const psa_core_key_attributes_t *attr, 00271 uint8_t *storage_data ) 00272 { 00273 psa_persistent_key_storage_format *storage_format = 00274 (psa_persistent_key_storage_format *) storage_data; 00275 00276 memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ); 00277 PUT_UINT32_LE( 0, storage_format->version, 0 ); 00278 PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 ); 00279 PUT_UINT32_LE( attr->type, storage_format->type, 0 ); 00280 PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 ); 00281 PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) ); 00282 PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) ); 00283 PUT_UINT32_LE( data_length, storage_format->data_len, 0 ); 00284 memcpy( storage_format->key_data, data, data_length ); 00285 } 00286 00287 static psa_status_t check_magic_header( const uint8_t *data ) 00288 { 00289 if( memcmp( data, PSA_KEY_STORAGE_MAGIC_HEADER, 00290 PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ) != 0 ) 00291 return( PSA_ERROR_STORAGE_FAILURE ); 00292 return( PSA_SUCCESS ); 00293 } 00294 00295 psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data, 00296 size_t storage_data_length, 00297 uint8_t **key_data, 00298 size_t *key_data_length, 00299 psa_core_key_attributes_t *attr ) 00300 { 00301 psa_status_t status; 00302 const psa_persistent_key_storage_format *storage_format = 00303 (const psa_persistent_key_storage_format *)storage_data; 00304 uint32_t version; 00305 00306 if( storage_data_length < sizeof(*storage_format) ) 00307 return( PSA_ERROR_STORAGE_FAILURE ); 00308 00309 status = check_magic_header( storage_data ); 00310 if( status != PSA_SUCCESS ) 00311 return( status ); 00312 00313 GET_UINT32_LE( version, storage_format->version, 0 ); 00314 if( version != 0 ) 00315 return( PSA_ERROR_STORAGE_FAILURE ); 00316 00317 GET_UINT32_LE( *key_data_length, storage_format->data_len, 0 ); 00318 if( *key_data_length > ( storage_data_length - sizeof(*storage_format) ) || 00319 *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE ) 00320 return( PSA_ERROR_STORAGE_FAILURE ); 00321 00322 if( *key_data_length == 0 ) 00323 { 00324 *key_data = NULL; 00325 } 00326 else 00327 { 00328 *key_data = mbedtls_calloc( 1, *key_data_length ); 00329 if( *key_data == NULL ) 00330 return( PSA_ERROR_INSUFFICIENT_MEMORY ); 00331 memcpy( *key_data, storage_format->key_data, *key_data_length ); 00332 } 00333 00334 GET_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 ); 00335 GET_UINT32_LE( attr->type, storage_format->type, 0 ); 00336 GET_UINT32_LE( attr->policy.usage, storage_format->policy, 0 ); 00337 GET_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) ); 00338 GET_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) ); 00339 00340 return( PSA_SUCCESS ); 00341 } 00342 00343 psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr, 00344 const uint8_t *data, 00345 const size_t data_length ) 00346 { 00347 size_t storage_data_length; 00348 uint8_t *storage_data; 00349 psa_status_t status; 00350 00351 if( data_length > PSA_CRYPTO_MAX_STORAGE_SIZE ) 00352 return PSA_ERROR_INSUFFICIENT_STORAGE; 00353 storage_data_length = data_length + sizeof( psa_persistent_key_storage_format ); 00354 00355 storage_data = mbedtls_calloc( 1, storage_data_length ); 00356 if( storage_data == NULL ) 00357 return( PSA_ERROR_INSUFFICIENT_MEMORY ); 00358 00359 psa_format_key_data_for_storage( data, data_length, attr, storage_data ); 00360 00361 status = psa_crypto_storage_store( attr->id, 00362 storage_data, storage_data_length ); 00363 00364 mbedtls_free( storage_data ); 00365 00366 return( status ); 00367 } 00368 00369 void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length ) 00370 { 00371 if( key_data != NULL ) 00372 { 00373 mbedtls_platform_zeroize( key_data, key_data_length ); 00374 } 00375 mbedtls_free( key_data ); 00376 } 00377 00378 psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr, 00379 uint8_t **data, 00380 size_t *data_length ) 00381 { 00382 psa_status_t status = PSA_SUCCESS; 00383 uint8_t *loaded_data; 00384 size_t storage_data_length = 0; 00385 psa_key_id_t key = attr->id; 00386 00387 status = psa_crypto_storage_get_data_length( key, &storage_data_length ); 00388 if( status != PSA_SUCCESS ) 00389 return( status ); 00390 00391 loaded_data = mbedtls_calloc( 1, storage_data_length ); 00392 00393 if( loaded_data == NULL ) 00394 return( PSA_ERROR_INSUFFICIENT_MEMORY ); 00395 00396 status = psa_crypto_storage_load( key, loaded_data, storage_data_length ); 00397 if( status != PSA_SUCCESS ) 00398 goto exit; 00399 00400 status = psa_parse_key_data_from_storage( loaded_data, storage_data_length, 00401 data, data_length, attr ); 00402 00403 exit: 00404 mbedtls_free( loaded_data ); 00405 return( status ); 00406 } 00407 00408 00409 00410 /****************************************************************/ 00411 /* Transactions */ 00412 /****************************************************************/ 00413 00414 #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) 00415 00416 psa_crypto_transaction_t psa_crypto_transaction; 00417 00418 psa_status_t psa_crypto_save_transaction( void ) 00419 { 00420 struct psa_storage_info_t p_info; 00421 psa_status_t status; 00422 status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info ); 00423 if( status == PSA_SUCCESS ) 00424 { 00425 /* This shouldn't happen: we're trying to start a transaction while 00426 * there is still a transaction that hasn't been replayed. */ 00427 return( PSA_ERROR_CORRUPTION_DETECTED ); 00428 } 00429 else if( status != PSA_ERROR_DOES_NOT_EXIST ) 00430 return( status ); 00431 return( psa_its_set( PSA_CRYPTO_ITS_TRANSACTION_UID, 00432 sizeof( psa_crypto_transaction ), 00433 &psa_crypto_transaction, 00434 0 ) ); 00435 } 00436 00437 psa_status_t psa_crypto_load_transaction( void ) 00438 { 00439 psa_status_t status; 00440 size_t length; 00441 status = psa_its_get( PSA_CRYPTO_ITS_TRANSACTION_UID, 0, 00442 sizeof( psa_crypto_transaction ), 00443 &psa_crypto_transaction, &length ); 00444 if( status != PSA_SUCCESS ) 00445 return( status ); 00446 if( length != sizeof( psa_crypto_transaction ) ) 00447 return( PSA_ERROR_STORAGE_FAILURE ); 00448 return( PSA_SUCCESS ); 00449 } 00450 00451 psa_status_t psa_crypto_stop_transaction( void ) 00452 { 00453 psa_status_t status = psa_its_remove( PSA_CRYPTO_ITS_TRANSACTION_UID ); 00454 /* Whether or not updating the storage succeeded, the transaction is 00455 * finished now. It's too late to go back, so zero out the in-memory 00456 * data. */ 00457 memset( &psa_crypto_transaction, 0, sizeof( psa_crypto_transaction ) ); 00458 return( status ); 00459 } 00460 00461 #endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */ 00462 00463 00464 00465 /****************************************************************/ 00466 /* Random generator state */ 00467 /****************************************************************/ 00468 00469 #if defined(MBEDTLS_PSA_INJECT_ENTROPY) 00470 psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed, 00471 size_t seed_size ) 00472 { 00473 psa_status_t status; 00474 struct psa_storage_info_t p_info; 00475 00476 status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info ); 00477 00478 if( PSA_ERROR_DOES_NOT_EXIST == status ) /* No seed exists */ 00479 { 00480 status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 ); 00481 } 00482 else if( PSA_SUCCESS == status ) 00483 { 00484 /* You should not be here. Seed needs to be injected only once */ 00485 status = PSA_ERROR_NOT_PERMITTED; 00486 } 00487 return( status ); 00488 } 00489 #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ 00490 00491 00492 00493 /****************************************************************/ 00494 /* The end */ 00495 /****************************************************************/ 00496 00497 #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
Generated on Tue Jul 12 2022 13:54:45 by
