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_slot_management.c
00001 /* 00002 * PSA crypto layer on top of Mbed TLS crypto 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.h" 00024 #else 00025 #include MBEDTLS_CONFIG_FILE 00026 #endif 00027 00028 #if defined(MBEDTLS_PSA_CRYPTO_C) 00029 00030 #include "psa_crypto_service_integration.h" 00031 #include "psa/crypto.h" 00032 00033 #include "psa_crypto_core.h" 00034 #include "psa_crypto_slot_management.h" 00035 #include "psa_crypto_storage.h" 00036 #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 00037 #include "psa_crypto_se.h" 00038 #endif 00039 00040 #include <stdlib.h> 00041 #include <string.h> 00042 #if defined(MBEDTLS_PLATFORM_C) 00043 #include "mbedtls/platform.h" 00044 #else 00045 #define mbedtls_calloc calloc 00046 #define mbedtls_free free 00047 #endif 00048 00049 #define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) ) 00050 00051 typedef struct 00052 { 00053 psa_key_slot_t key_slots[PSA_KEY_SLOT_COUNT]; 00054 unsigned key_slots_initialized : 1; 00055 } psa_global_data_t; 00056 00057 static psa_global_data_t global_data; 00058 00059 /* Access a key slot at the given handle. The handle of a key slot is 00060 * the index of the slot in the global slot array, plus one so that handles 00061 * start at 1 and not 0. */ 00062 psa_status_t psa_get_key_slot( psa_key_handle_t handle, 00063 psa_key_slot_t **p_slot ) 00064 { 00065 psa_key_slot_t *slot = NULL; 00066 00067 if( ! global_data.key_slots_initialized ) 00068 return( PSA_ERROR_BAD_STATE ); 00069 00070 /* 0 is not a valid handle under any circumstance. This 00071 * implementation provides slots number 1 to N where N is the 00072 * number of available slots. */ 00073 if( handle == 0 || handle > ARRAY_LENGTH( global_data.key_slots ) ) 00074 return( PSA_ERROR_INVALID_HANDLE ); 00075 slot = &global_data.key_slots[handle - 1]; 00076 00077 /* If the slot isn't occupied, the handle is invalid. */ 00078 if( ! psa_is_key_slot_occupied( slot ) ) 00079 return( PSA_ERROR_INVALID_HANDLE ); 00080 00081 *p_slot = slot; 00082 return( PSA_SUCCESS ); 00083 } 00084 00085 psa_status_t psa_initialize_key_slots( void ) 00086 { 00087 /* Nothing to do: program startup and psa_wipe_all_key_slots() both 00088 * guarantee that the key slots are initialized to all-zero, which 00089 * means that all the key slots are in a valid, empty state. */ 00090 global_data.key_slots_initialized = 1; 00091 return( PSA_SUCCESS ); 00092 } 00093 00094 void psa_wipe_all_key_slots( void ) 00095 { 00096 psa_key_handle_t key; 00097 for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ ) 00098 { 00099 psa_key_slot_t *slot = &global_data.key_slots[key - 1]; 00100 (void) psa_wipe_key_slot( slot ); 00101 } 00102 global_data.key_slots_initialized = 0; 00103 } 00104 00105 psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle, 00106 psa_key_slot_t **p_slot ) 00107 { 00108 if( ! global_data.key_slots_initialized ) 00109 return( PSA_ERROR_BAD_STATE ); 00110 00111 for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) ) 00112 { 00113 *p_slot = &global_data.key_slots[*handle - 1]; 00114 if( ! psa_is_key_slot_occupied( *p_slot ) ) 00115 return( PSA_SUCCESS ); 00116 } 00117 *p_slot = NULL; 00118 return( PSA_ERROR_INSUFFICIENT_MEMORY ); 00119 } 00120 00121 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) 00122 static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *slot ) 00123 { 00124 psa_status_t status = PSA_SUCCESS; 00125 uint8_t *key_data = NULL; 00126 size_t key_data_length = 0; 00127 00128 status = psa_load_persistent_key( &slot->attr, 00129 &key_data, &key_data_length ); 00130 if( status != PSA_SUCCESS ) 00131 goto exit; 00132 00133 #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 00134 if( psa_key_lifetime_is_external( slot->attr.lifetime ) ) 00135 { 00136 psa_se_key_data_storage_t *data; 00137 if( key_data_length != sizeof( *data ) ) 00138 { 00139 status = PSA_ERROR_STORAGE_FAILURE; 00140 goto exit; 00141 } 00142 data = (psa_se_key_data_storage_t *) key_data; 00143 memcpy( &slot->data.se.slot_number, &data->slot_number, 00144 sizeof( slot->data.se.slot_number ) ); 00145 memcpy( &slot->attr.bits, &data->bits, 00146 sizeof( slot->attr.bits ) ); 00147 } 00148 else 00149 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 00150 { 00151 status = psa_import_key_into_slot( slot, key_data, key_data_length ); 00152 } 00153 00154 exit: 00155 psa_free_persistent_key_data( key_data, key_data_length ); 00156 return( status ); 00157 } 00158 00159 /** Check whether a key identifier is acceptable. 00160 * 00161 * For backward compatibility, key identifiers that were valid in a 00162 * past released version must remain valid, unless a migration path 00163 * is provided. 00164 * 00165 * \param file_id The key identifier to check. 00166 * \param vendor_ok Nonzero to allow key ids in the vendor range. 00167 * 0 to allow only key ids in the application range. 00168 * 00169 * \return 1 if \p file_id is acceptable, otherwise 0. 00170 */ 00171 static int psa_is_key_id_valid( psa_key_file_id_t file_id, 00172 int vendor_ok ) 00173 { 00174 psa_app_key_id_t key_id = PSA_KEY_FILE_GET_KEY_ID( file_id ); 00175 if( PSA_KEY_ID_USER_MIN <= key_id && key_id <= PSA_KEY_ID_USER_MAX ) 00176 return( 1 ); 00177 else if( vendor_ok && 00178 PSA_KEY_ID_VENDOR_MIN <= key_id && 00179 key_id <= PSA_KEY_ID_VENDOR_MAX ) 00180 return( 1 ); 00181 else 00182 return( 0 ); 00183 } 00184 #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ 00185 00186 psa_status_t psa_validate_persistent_key_parameters( 00187 psa_key_lifetime_t lifetime, 00188 psa_key_file_id_t id, 00189 psa_se_drv_table_entry_t **p_drv, 00190 int creating ) 00191 { 00192 if( p_drv != NULL ) 00193 *p_drv = NULL; 00194 #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 00195 if( psa_key_lifetime_is_external( lifetime ) ) 00196 { 00197 *p_drv = psa_get_se_driver_entry( lifetime ); 00198 if( *p_drv == NULL ) 00199 return( PSA_ERROR_INVALID_ARGUMENT ); 00200 } 00201 else 00202 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 00203 if( lifetime != PSA_KEY_LIFETIME_PERSISTENT ) 00204 return( PSA_ERROR_INVALID_ARGUMENT ); 00205 00206 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) 00207 if( ! psa_is_key_id_valid( id, ! creating ) ) 00208 return( PSA_ERROR_INVALID_ARGUMENT ); 00209 return( PSA_SUCCESS ); 00210 00211 #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ 00212 (void) id; 00213 (void) creating; 00214 return( PSA_ERROR_NOT_SUPPORTED ); 00215 #endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */ 00216 } 00217 00218 psa_status_t psa_open_key( psa_key_file_id_t id, psa_key_handle_t *handle ) 00219 { 00220 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) 00221 psa_status_t status; 00222 psa_key_slot_t *slot; 00223 00224 *handle = 0; 00225 00226 status = psa_validate_persistent_key_parameters( 00227 PSA_KEY_LIFETIME_PERSISTENT, id, NULL, 0 ); 00228 if( status != PSA_SUCCESS ) 00229 return( status ); 00230 00231 status = psa_get_empty_key_slot( handle, &slot ); 00232 if( status != PSA_SUCCESS ) 00233 return( status ); 00234 00235 slot->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT; 00236 slot->attr.id = id; 00237 00238 status = psa_load_persistent_key_into_slot( slot ); 00239 if( status != PSA_SUCCESS ) 00240 { 00241 psa_wipe_key_slot( slot ); 00242 *handle = 0; 00243 } 00244 return( status ); 00245 00246 #else /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ 00247 (void) id; 00248 *handle = 0; 00249 return( PSA_ERROR_NOT_SUPPORTED ); 00250 #endif /* !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ 00251 } 00252 00253 psa_status_t psa_close_key( psa_key_handle_t handle ) 00254 { 00255 psa_status_t status; 00256 psa_key_slot_t *slot; 00257 00258 if( handle == 0 ) 00259 return( PSA_SUCCESS ); 00260 00261 status = psa_get_key_slot( handle, &slot ); 00262 if( status != PSA_SUCCESS ) 00263 return( status ); 00264 00265 return( psa_wipe_key_slot( slot ) ); 00266 } 00267 00268 void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats ) 00269 { 00270 psa_key_handle_t key; 00271 memset( stats, 0, sizeof( *stats ) ); 00272 for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ ) 00273 { 00274 const psa_key_slot_t *slot = &global_data.key_slots[key - 1]; 00275 if( ! psa_is_key_slot_occupied( slot ) ) 00276 { 00277 ++stats->empty_slots; 00278 continue; 00279 } 00280 if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE ) 00281 ++stats->volatile_slots; 00282 else if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT ) 00283 { 00284 psa_app_key_id_t id = PSA_KEY_FILE_GET_KEY_ID(slot->attr.id); 00285 ++stats->persistent_slots; 00286 if( id > stats->max_open_internal_key_id ) 00287 stats->max_open_internal_key_id = id; 00288 } 00289 else 00290 { 00291 psa_app_key_id_t id = PSA_KEY_FILE_GET_KEY_ID(slot->attr.id); 00292 ++stats->external_slots; 00293 if( id > stats->max_open_external_key_id ) 00294 stats->max_open_external_key_id = id; 00295 } 00296 } 00297 } 00298 00299 #endif /* MBEDTLS_PSA_CRYPTO_C */
Generated on Tue Jul 12 2022 13:54:45 by
