1 /* 2 * PSA crypto layer on top of Mbed TLS crypto 3 */ 4 /* 5 * Copyright The Mbed TLS Contributors 6 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 7 */ 8 9 #ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H 10 #define PSA_CRYPTO_SLOT_MANAGEMENT_H 11 12 #include "psa/crypto.h" 13 #include "psa_crypto_core.h" 14 #include "psa_crypto_se.h" 15 16 /** Range of volatile key identifiers. 17 * 18 * The first #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation 19 * range of key identifiers are reserved for volatile key identifiers. 20 * 21 * If \c id is a a volatile key identifier, #PSA_KEY_ID_VOLATILE_MIN - \c id 22 * indicates the key slot containing the volatile key definition. See 23 * psa_crypto_slot_management.c for details. 24 */ 25 26 /** The minimum value for a volatile key identifier. 27 */ 28 #define PSA_KEY_ID_VOLATILE_MIN PSA_KEY_ID_VENDOR_MIN 29 30 /** The maximum value for a volatile key identifier. 31 */ 32 #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) 33 #define PSA_KEY_ID_VOLATILE_MAX (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1) 34 #else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ 35 #define PSA_KEY_ID_VOLATILE_MAX \ 36 (PSA_KEY_ID_VOLATILE_MIN + MBEDTLS_PSA_KEY_SLOT_COUNT - 1) 37 #endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ 38 39 /** Test whether a key identifier is a volatile key identifier. 40 * 41 * \param key_id Key identifier to test. 42 * 43 * \retval 1 44 * The key identifier is a volatile key identifier. 45 * \retval 0 46 * The key identifier is not a volatile key identifier. 47 */ 48 static inline int psa_key_id_is_volatile(psa_key_id_t key_id) 49 { 50 return (key_id >= PSA_KEY_ID_VOLATILE_MIN) && 51 (key_id <= PSA_KEY_ID_VOLATILE_MAX); 52 } 53 54 /** Get the description of a key given its identifier and lock it. 55 * 56 * The descriptions of volatile keys and loaded persistent keys are stored in 57 * key slots. This function returns a pointer to the key slot containing the 58 * description of a key given its identifier. 59 * 60 * In case of a persistent key, the function loads the description of the key 61 * into a key slot if not already done. 62 * 63 * On success, the returned key slot has been registered for reading. 64 * It is the responsibility of the caller to call psa_unregister_read(slot) 65 * when they have finished reading the contents of the slot. 66 * 67 * On failure, `*p_slot` is set to NULL. This ensures that it is always valid 68 * to call psa_unregister_read on the returned slot. 69 * 70 * \param key Key identifier to query. 71 * \param[out] p_slot On success, `*p_slot` contains a pointer to the 72 * key slot containing the description of the key 73 * identified by \p key. 74 * 75 * \retval #PSA_SUCCESS 76 * \p *p_slot contains a pointer to the key slot containing the 77 * description of the key identified by \p key. 78 * The key slot counter has been incremented. 79 * \retval #PSA_ERROR_BAD_STATE 80 * The library has not been initialized. 81 * \retval #PSA_ERROR_INVALID_HANDLE 82 * \p key is not a valid key identifier. 83 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY 84 * \p key is a persistent key identifier. The implementation does not 85 * have sufficient resources to load the persistent key. This can be 86 * due to a lack of empty key slot, or available memory. 87 * \retval #PSA_ERROR_DOES_NOT_EXIST 88 * There is no key with key identifier \p key. 89 * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription 90 * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription 91 * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription 92 */ 93 psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, 94 psa_key_slot_t **p_slot); 95 96 /** Initialize the key slot structures. 97 * 98 * \retval #PSA_SUCCESS 99 * Currently this function always succeeds. 100 */ 101 psa_status_t psa_initialize_key_slots(void); 102 103 #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) 104 /* Allow test code to customize the key slice length. We use this in tests 105 * that exhaust the key store to reach a full key store in reasonable time 106 * and memory. 107 * 108 * The length of each slice must be between 1 and 109 * (1 << KEY_ID_SLOT_INDEX_WIDTH) inclusive. 110 * 111 * The length for a given slice index must not change while 112 * the key store is initialized. 113 */ 114 extern size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)( 115 size_t slice_idx); 116 117 /* The number of volatile key slices. */ 118 size_t psa_key_slot_volatile_slice_count(void); 119 #endif 120 121 /** Delete all data from key slots in memory. 122 * This function is not thread safe, it wipes every key slot regardless of 123 * state and reader count. It should only be called when no slot is in use. 124 * 125 * This does not affect persistent storage. */ 126 void psa_wipe_all_key_slots(void); 127 128 /** Find a free key slot and reserve it to be filled with a key. 129 * 130 * This function finds a key slot that is free, 131 * sets its state to PSA_SLOT_FILLING and then returns the slot. 132 * 133 * On success, the key slot's state is PSA_SLOT_FILLING. 134 * It is the responsibility of the caller to change the slot's state to 135 * PSA_SLOT_EMPTY/FULL once key creation has finished. 136 * 137 * If multi-threading is enabled, the caller must hold the 138 * global key slot mutex. 139 * 140 * \param[out] volatile_key_id - If null, reserve a cache slot for 141 * a persistent or built-in key. 142 * - If non-null, allocate a slot for 143 * a volatile key. On success, 144 * \p *volatile_key_id is the 145 * identifier corresponding to the 146 * returned slot. It is the caller's 147 * responsibility to set this key identifier 148 * in the attributes. 149 * \param[out] p_slot On success, a pointer to the slot. 150 * 151 * \retval #PSA_SUCCESS \emptydescription 152 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY 153 * There were no free key slots. 154 * When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, there was not 155 * enough memory to allocate more slots. 156 * \retval #PSA_ERROR_BAD_STATE \emptydescription 157 * \retval #PSA_ERROR_CORRUPTION_DETECTED 158 * This function attempted to operate on a key slot which was in an 159 * unexpected state. 160 */ 161 psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, 162 psa_key_slot_t **p_slot); 163 164 #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) 165 /** Return a key slot to the free list. 166 * 167 * Call this function when a slot obtained from psa_reserve_free_key_slot() 168 * is no longer in use. 169 * 170 * If multi-threading is enabled, the caller must hold the 171 * global key slot mutex. 172 * 173 * \param slice_idx The slice containing the slot. 174 * This is `slot->slice_index` when the slot 175 * is obtained from psa_reserve_free_key_slot(). 176 * \param slot The key slot. 177 * 178 * \retval #PSA_SUCCESS \emptydescription 179 * \retval #PSA_ERROR_CORRUPTION_DETECTED 180 * This function attempted to operate on a key slot which was in an 181 * unexpected state. 182 */ 183 psa_status_t psa_free_key_slot(size_t slice_idx, 184 psa_key_slot_t *slot); 185 #endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ 186 187 /** Change the state of a key slot. 188 * 189 * This function changes the state of the key slot from expected_state to 190 * new state. If the state of the slot was not expected_state, the state is 191 * unchanged. 192 * 193 * If multi-threading is enabled, the caller must hold the 194 * global key slot mutex. 195 * 196 * \param[in] slot The key slot. 197 * \param[in] expected_state The current state of the slot. 198 * \param[in] new_state The new state of the slot. 199 * 200 * \retval #PSA_SUCCESS 201 The key slot's state variable is new_state. 202 * \retval #PSA_ERROR_CORRUPTION_DETECTED 203 * The slot's state was not expected_state. 204 */ 205 static inline psa_status_t psa_key_slot_state_transition( 206 psa_key_slot_t *slot, psa_key_slot_state_t expected_state, 207 psa_key_slot_state_t new_state) 208 { 209 if (slot->state != expected_state) { 210 return PSA_ERROR_CORRUPTION_DETECTED; 211 } 212 slot->state = new_state; 213 return PSA_SUCCESS; 214 } 215 216 /** Register as a reader of a key slot. 217 * 218 * This function increments the key slot registered reader counter by one. 219 * If multi-threading is enabled, the caller must hold the 220 * global key slot mutex. 221 * 222 * \param[in] slot The key slot. 223 * 224 * \retval #PSA_SUCCESS 225 The key slot registered reader counter was incremented. 226 * \retval #PSA_ERROR_CORRUPTION_DETECTED 227 * The reader counter already reached its maximum value and was not 228 * increased, or the slot's state was not PSA_SLOT_FULL. 229 */ 230 static inline psa_status_t psa_register_read(psa_key_slot_t *slot) 231 { 232 if ((slot->state != PSA_SLOT_FULL) || 233 (slot->var.occupied.registered_readers >= SIZE_MAX)) { 234 return PSA_ERROR_CORRUPTION_DETECTED; 235 } 236 slot->var.occupied.registered_readers++; 237 238 return PSA_SUCCESS; 239 } 240 241 /** Unregister from reading a key slot. 242 * 243 * This function decrements the key slot registered reader counter by one. 244 * If the state of the slot is PSA_SLOT_PENDING_DELETION, 245 * and there is only one registered reader (the caller), 246 * this function will call psa_wipe_key_slot(). 247 * If multi-threading is enabled, the caller must hold the 248 * global key slot mutex. 249 * 250 * \note To ease the handling of errors in retrieving a key slot 251 * a NULL input pointer is valid, and the function returns 252 * successfully without doing anything in that case. 253 * 254 * \param[in] slot The key slot. 255 * \retval #PSA_SUCCESS 256 * \p slot is NULL or the key slot reader counter has been 257 * decremented (and potentially wiped) successfully. 258 * \retval #PSA_ERROR_CORRUPTION_DETECTED 259 * The slot's state was neither PSA_SLOT_FULL nor 260 * PSA_SLOT_PENDING_DELETION. 261 * Or a wipe was attempted and the slot's state was not 262 * PSA_SLOT_PENDING_DELETION. 263 * Or registered_readers was equal to 0. 264 */ 265 psa_status_t psa_unregister_read(psa_key_slot_t *slot); 266 267 /** Wrap a call to psa_unregister_read in the global key slot mutex. 268 * 269 * If threading is disabled, this simply calls psa_unregister_read. 270 * 271 * \note To ease the handling of errors in retrieving a key slot 272 * a NULL input pointer is valid, and the function returns 273 * successfully without doing anything in that case. 274 * 275 * \param[in] slot The key slot. 276 * \retval #PSA_SUCCESS 277 * \p slot is NULL or the key slot reader counter has been 278 * decremented (and potentially wiped) successfully. 279 * \retval #PSA_ERROR_CORRUPTION_DETECTED 280 * The slot's state was neither PSA_SLOT_FULL nor 281 * PSA_SLOT_PENDING_DELETION. 282 * Or a wipe was attempted and the slot's state was not 283 * PSA_SLOT_PENDING_DELETION. 284 * Or registered_readers was equal to 0. 285 */ 286 psa_status_t psa_unregister_read_under_mutex(psa_key_slot_t *slot); 287 288 /** Test whether a lifetime designates a key in an external cryptoprocessor. 289 * 290 * \param lifetime The lifetime to test. 291 * 292 * \retval 1 293 * The lifetime designates an external key. There should be a 294 * registered driver for this lifetime, otherwise the key cannot 295 * be created or manipulated. 296 * \retval 0 297 * The lifetime designates a key that is volatile or in internal 298 * storage. 299 */ 300 static inline int psa_key_lifetime_is_external(psa_key_lifetime_t lifetime) 301 { 302 return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) 303 != PSA_KEY_LOCATION_LOCAL_STORAGE; 304 } 305 306 /** Validate a key's location. 307 * 308 * This function checks whether the key's attributes point to a location that 309 * is known to the PSA Core, and returns the driver function table if the key 310 * is to be found in an external location. 311 * 312 * \param[in] lifetime The key lifetime attribute. 313 * \param[out] p_drv On success, when a key is located in external 314 * storage, returns a pointer to the driver table 315 * associated with the key's storage location. 316 * 317 * \retval #PSA_SUCCESS \emptydescription 318 * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription 319 */ 320 psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime, 321 psa_se_drv_table_entry_t **p_drv); 322 323 /** Validate the persistence of a key. 324 * 325 * \param[in] lifetime The key lifetime attribute. 326 * 327 * \retval #PSA_SUCCESS \emptydescription 328 * \retval #PSA_ERROR_NOT_SUPPORTED The key is persistent but persistent keys 329 * are not supported. 330 */ 331 psa_status_t psa_validate_key_persistence(psa_key_lifetime_t lifetime); 332 333 /** Validate a key identifier. 334 * 335 * \param[in] key The key identifier. 336 * \param[in] vendor_ok Non-zero to indicate that key identifiers in the 337 * vendor range are allowed, volatile key identifiers 338 * excepted \c 0 otherwise. 339 * 340 * \retval <> 0 if the key identifier is valid, 0 otherwise. 341 */ 342 int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok); 343 344 #endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */ 345