xref: /aosp_15_r20/external/mbedtls/library/psa_crypto_se.c (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi /*
2*62c56f98SSadaf Ebrahimi  *  PSA crypto support for secure element drivers
3*62c56f98SSadaf Ebrahimi  */
4*62c56f98SSadaf Ebrahimi /*
5*62c56f98SSadaf Ebrahimi  *  Copyright The Mbed TLS Contributors
6*62c56f98SSadaf Ebrahimi  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7*62c56f98SSadaf Ebrahimi  */
8*62c56f98SSadaf Ebrahimi 
9*62c56f98SSadaf Ebrahimi #include "common.h"
10*62c56f98SSadaf Ebrahimi 
11*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
12*62c56f98SSadaf Ebrahimi 
13*62c56f98SSadaf Ebrahimi #include <stdint.h>
14*62c56f98SSadaf Ebrahimi #include <string.h>
15*62c56f98SSadaf Ebrahimi 
16*62c56f98SSadaf Ebrahimi #include "psa/crypto_se_driver.h"
17*62c56f98SSadaf Ebrahimi 
18*62c56f98SSadaf Ebrahimi #include "psa_crypto_se.h"
19*62c56f98SSadaf Ebrahimi 
20*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_ITS_FILE_C)
21*62c56f98SSadaf Ebrahimi #include "psa_crypto_its.h"
22*62c56f98SSadaf Ebrahimi #else /* Native ITS implementation */
23*62c56f98SSadaf Ebrahimi #include "psa/error.h"
24*62c56f98SSadaf Ebrahimi #include "psa/internal_trusted_storage.h"
25*62c56f98SSadaf Ebrahimi #endif
26*62c56f98SSadaf Ebrahimi 
27*62c56f98SSadaf Ebrahimi #include "mbedtls/platform.h"
28*62c56f98SSadaf Ebrahimi 
29*62c56f98SSadaf Ebrahimi 
30*62c56f98SSadaf Ebrahimi 
31*62c56f98SSadaf Ebrahimi /****************************************************************/
32*62c56f98SSadaf Ebrahimi /* Driver lookup */
33*62c56f98SSadaf Ebrahimi /****************************************************************/
34*62c56f98SSadaf Ebrahimi 
35*62c56f98SSadaf Ebrahimi /* This structure is identical to psa_drv_se_context_t declared in
36*62c56f98SSadaf Ebrahimi  * `crypto_se_driver.h`, except that some parts are writable here
37*62c56f98SSadaf Ebrahimi  * (non-const, or pointer to non-const). */
38*62c56f98SSadaf Ebrahimi typedef struct {
39*62c56f98SSadaf Ebrahimi     void *persistent_data;
40*62c56f98SSadaf Ebrahimi     size_t persistent_data_size;
41*62c56f98SSadaf Ebrahimi     uintptr_t transient_data;
42*62c56f98SSadaf Ebrahimi } psa_drv_se_internal_context_t;
43*62c56f98SSadaf Ebrahimi 
44*62c56f98SSadaf Ebrahimi struct psa_se_drv_table_entry_s {
45*62c56f98SSadaf Ebrahimi     psa_key_location_t location;
46*62c56f98SSadaf Ebrahimi     const psa_drv_se_t *methods;
47*62c56f98SSadaf Ebrahimi     union {
48*62c56f98SSadaf Ebrahimi         psa_drv_se_internal_context_t internal;
49*62c56f98SSadaf Ebrahimi         psa_drv_se_context_t context;
50*62c56f98SSadaf Ebrahimi     } u;
51*62c56f98SSadaf Ebrahimi };
52*62c56f98SSadaf Ebrahimi 
53*62c56f98SSadaf Ebrahimi static psa_se_drv_table_entry_t driver_table[PSA_MAX_SE_DRIVERS];
54*62c56f98SSadaf Ebrahimi 
psa_get_se_driver_entry(psa_key_lifetime_t lifetime)55*62c56f98SSadaf Ebrahimi psa_se_drv_table_entry_t *psa_get_se_driver_entry(
56*62c56f98SSadaf Ebrahimi     psa_key_lifetime_t lifetime)
57*62c56f98SSadaf Ebrahimi {
58*62c56f98SSadaf Ebrahimi     size_t i;
59*62c56f98SSadaf Ebrahimi     psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
60*62c56f98SSadaf Ebrahimi     /* In the driver table, location=0 means an entry that isn't used.
61*62c56f98SSadaf Ebrahimi      * No driver has a location of 0 because it's a reserved value
62*62c56f98SSadaf Ebrahimi      * (which designates transparent keys). Make sure we never return
63*62c56f98SSadaf Ebrahimi      * a driver entry for location 0. */
64*62c56f98SSadaf Ebrahimi     if (location == 0) {
65*62c56f98SSadaf Ebrahimi         return NULL;
66*62c56f98SSadaf Ebrahimi     }
67*62c56f98SSadaf Ebrahimi     for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
68*62c56f98SSadaf Ebrahimi         if (driver_table[i].location == location) {
69*62c56f98SSadaf Ebrahimi             return &driver_table[i];
70*62c56f98SSadaf Ebrahimi         }
71*62c56f98SSadaf Ebrahimi     }
72*62c56f98SSadaf Ebrahimi     return NULL;
73*62c56f98SSadaf Ebrahimi }
74*62c56f98SSadaf Ebrahimi 
psa_get_se_driver_methods(const psa_se_drv_table_entry_t * driver)75*62c56f98SSadaf Ebrahimi const psa_drv_se_t *psa_get_se_driver_methods(
76*62c56f98SSadaf Ebrahimi     const psa_se_drv_table_entry_t *driver)
77*62c56f98SSadaf Ebrahimi {
78*62c56f98SSadaf Ebrahimi     return driver->methods;
79*62c56f98SSadaf Ebrahimi }
80*62c56f98SSadaf Ebrahimi 
psa_get_se_driver_context(psa_se_drv_table_entry_t * driver)81*62c56f98SSadaf Ebrahimi psa_drv_se_context_t *psa_get_se_driver_context(
82*62c56f98SSadaf Ebrahimi     psa_se_drv_table_entry_t *driver)
83*62c56f98SSadaf Ebrahimi {
84*62c56f98SSadaf Ebrahimi     return &driver->u.context;
85*62c56f98SSadaf Ebrahimi }
86*62c56f98SSadaf Ebrahimi 
psa_get_se_driver(psa_key_lifetime_t lifetime,const psa_drv_se_t ** p_methods,psa_drv_se_context_t ** p_drv_context)87*62c56f98SSadaf Ebrahimi int psa_get_se_driver(psa_key_lifetime_t lifetime,
88*62c56f98SSadaf Ebrahimi                       const psa_drv_se_t **p_methods,
89*62c56f98SSadaf Ebrahimi                       psa_drv_se_context_t **p_drv_context)
90*62c56f98SSadaf Ebrahimi {
91*62c56f98SSadaf Ebrahimi     psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry(lifetime);
92*62c56f98SSadaf Ebrahimi     if (p_methods != NULL) {
93*62c56f98SSadaf Ebrahimi         *p_methods = (driver ? driver->methods : NULL);
94*62c56f98SSadaf Ebrahimi     }
95*62c56f98SSadaf Ebrahimi     if (p_drv_context != NULL) {
96*62c56f98SSadaf Ebrahimi         *p_drv_context = (driver ? &driver->u.context : NULL);
97*62c56f98SSadaf Ebrahimi     }
98*62c56f98SSadaf Ebrahimi     return driver != NULL;
99*62c56f98SSadaf Ebrahimi }
100*62c56f98SSadaf Ebrahimi 
101*62c56f98SSadaf Ebrahimi 
102*62c56f98SSadaf Ebrahimi 
103*62c56f98SSadaf Ebrahimi /****************************************************************/
104*62c56f98SSadaf Ebrahimi /* Persistent data management */
105*62c56f98SSadaf Ebrahimi /****************************************************************/
106*62c56f98SSadaf Ebrahimi 
psa_get_se_driver_its_file_uid(const psa_se_drv_table_entry_t * driver,psa_storage_uid_t * uid)107*62c56f98SSadaf Ebrahimi static psa_status_t psa_get_se_driver_its_file_uid(
108*62c56f98SSadaf Ebrahimi     const psa_se_drv_table_entry_t *driver,
109*62c56f98SSadaf Ebrahimi     psa_storage_uid_t *uid)
110*62c56f98SSadaf Ebrahimi {
111*62c56f98SSadaf Ebrahimi     if (driver->location > PSA_MAX_SE_LOCATION) {
112*62c56f98SSadaf Ebrahimi         return PSA_ERROR_NOT_SUPPORTED;
113*62c56f98SSadaf Ebrahimi     }
114*62c56f98SSadaf Ebrahimi 
115*62c56f98SSadaf Ebrahimi     /* ITS file sizes are limited to 32 bits. */
116*62c56f98SSadaf Ebrahimi     if (driver->u.internal.persistent_data_size > UINT32_MAX) {
117*62c56f98SSadaf Ebrahimi         return PSA_ERROR_NOT_SUPPORTED;
118*62c56f98SSadaf Ebrahimi     }
119*62c56f98SSadaf Ebrahimi 
120*62c56f98SSadaf Ebrahimi     /* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
121*62c56f98SSadaf Ebrahimi     *uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->location;
122*62c56f98SSadaf Ebrahimi     return PSA_SUCCESS;
123*62c56f98SSadaf Ebrahimi }
124*62c56f98SSadaf Ebrahimi 
psa_load_se_persistent_data(const psa_se_drv_table_entry_t * driver)125*62c56f98SSadaf Ebrahimi psa_status_t psa_load_se_persistent_data(
126*62c56f98SSadaf Ebrahimi     const psa_se_drv_table_entry_t *driver)
127*62c56f98SSadaf Ebrahimi {
128*62c56f98SSadaf Ebrahimi     psa_status_t status;
129*62c56f98SSadaf Ebrahimi     psa_storage_uid_t uid;
130*62c56f98SSadaf Ebrahimi     size_t length;
131*62c56f98SSadaf Ebrahimi 
132*62c56f98SSadaf Ebrahimi     status = psa_get_se_driver_its_file_uid(driver, &uid);
133*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS) {
134*62c56f98SSadaf Ebrahimi         return status;
135*62c56f98SSadaf Ebrahimi     }
136*62c56f98SSadaf Ebrahimi 
137*62c56f98SSadaf Ebrahimi     /* Read the amount of persistent data that the driver requests.
138*62c56f98SSadaf Ebrahimi      * If the data in storage is larger, it is truncated. If the data
139*62c56f98SSadaf Ebrahimi      * in storage is smaller, silently keep what is already at the end
140*62c56f98SSadaf Ebrahimi      * of the output buffer. */
141*62c56f98SSadaf Ebrahimi     /* psa_get_se_driver_its_file_uid ensures that the size_t
142*62c56f98SSadaf Ebrahimi      * persistent_data_size is in range, but compilers don't know that,
143*62c56f98SSadaf Ebrahimi      * so cast to reassure them. */
144*62c56f98SSadaf Ebrahimi     return psa_its_get(uid, 0,
145*62c56f98SSadaf Ebrahimi                        (uint32_t) driver->u.internal.persistent_data_size,
146*62c56f98SSadaf Ebrahimi                        driver->u.internal.persistent_data,
147*62c56f98SSadaf Ebrahimi                        &length);
148*62c56f98SSadaf Ebrahimi }
149*62c56f98SSadaf Ebrahimi 
psa_save_se_persistent_data(const psa_se_drv_table_entry_t * driver)150*62c56f98SSadaf Ebrahimi psa_status_t psa_save_se_persistent_data(
151*62c56f98SSadaf Ebrahimi     const psa_se_drv_table_entry_t *driver)
152*62c56f98SSadaf Ebrahimi {
153*62c56f98SSadaf Ebrahimi     psa_status_t status;
154*62c56f98SSadaf Ebrahimi     psa_storage_uid_t uid;
155*62c56f98SSadaf Ebrahimi 
156*62c56f98SSadaf Ebrahimi     status = psa_get_se_driver_its_file_uid(driver, &uid);
157*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS) {
158*62c56f98SSadaf Ebrahimi         return status;
159*62c56f98SSadaf Ebrahimi     }
160*62c56f98SSadaf Ebrahimi 
161*62c56f98SSadaf Ebrahimi     /* psa_get_se_driver_its_file_uid ensures that the size_t
162*62c56f98SSadaf Ebrahimi      * persistent_data_size is in range, but compilers don't know that,
163*62c56f98SSadaf Ebrahimi      * so cast to reassure them. */
164*62c56f98SSadaf Ebrahimi     return psa_its_set(uid,
165*62c56f98SSadaf Ebrahimi                        (uint32_t) driver->u.internal.persistent_data_size,
166*62c56f98SSadaf Ebrahimi                        driver->u.internal.persistent_data,
167*62c56f98SSadaf Ebrahimi                        0);
168*62c56f98SSadaf Ebrahimi }
169*62c56f98SSadaf Ebrahimi 
psa_destroy_se_persistent_data(psa_key_location_t location)170*62c56f98SSadaf Ebrahimi psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location)
171*62c56f98SSadaf Ebrahimi {
172*62c56f98SSadaf Ebrahimi     psa_storage_uid_t uid;
173*62c56f98SSadaf Ebrahimi     if (location > PSA_MAX_SE_LOCATION) {
174*62c56f98SSadaf Ebrahimi         return PSA_ERROR_NOT_SUPPORTED;
175*62c56f98SSadaf Ebrahimi     }
176*62c56f98SSadaf Ebrahimi     uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + location;
177*62c56f98SSadaf Ebrahimi     return psa_its_remove(uid);
178*62c56f98SSadaf Ebrahimi }
179*62c56f98SSadaf Ebrahimi 
psa_find_se_slot_for_key(const psa_key_attributes_t * attributes,psa_key_creation_method_t method,psa_se_drv_table_entry_t * driver,psa_key_slot_number_t * slot_number)180*62c56f98SSadaf Ebrahimi psa_status_t psa_find_se_slot_for_key(
181*62c56f98SSadaf Ebrahimi     const psa_key_attributes_t *attributes,
182*62c56f98SSadaf Ebrahimi     psa_key_creation_method_t method,
183*62c56f98SSadaf Ebrahimi     psa_se_drv_table_entry_t *driver,
184*62c56f98SSadaf Ebrahimi     psa_key_slot_number_t *slot_number)
185*62c56f98SSadaf Ebrahimi {
186*62c56f98SSadaf Ebrahimi     psa_status_t status;
187*62c56f98SSadaf Ebrahimi     psa_key_location_t key_location =
188*62c56f98SSadaf Ebrahimi         PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes));
189*62c56f98SSadaf Ebrahimi 
190*62c56f98SSadaf Ebrahimi     /* If the location is wrong, it's a bug in the library. */
191*62c56f98SSadaf Ebrahimi     if (driver->location != key_location) {
192*62c56f98SSadaf Ebrahimi         return PSA_ERROR_CORRUPTION_DETECTED;
193*62c56f98SSadaf Ebrahimi     }
194*62c56f98SSadaf Ebrahimi 
195*62c56f98SSadaf Ebrahimi     /* If the driver doesn't support key creation in any way, give up now. */
196*62c56f98SSadaf Ebrahimi     if (driver->methods->key_management == NULL) {
197*62c56f98SSadaf Ebrahimi         return PSA_ERROR_NOT_SUPPORTED;
198*62c56f98SSadaf Ebrahimi     }
199*62c56f98SSadaf Ebrahimi 
200*62c56f98SSadaf Ebrahimi     if (psa_get_key_slot_number(attributes, slot_number) == PSA_SUCCESS) {
201*62c56f98SSadaf Ebrahimi         /* The application wants to use a specific slot. Allow it if
202*62c56f98SSadaf Ebrahimi          * the driver supports it. On a system with isolation,
203*62c56f98SSadaf Ebrahimi          * the crypto service must check that the application is
204*62c56f98SSadaf Ebrahimi          * permitted to request this slot. */
205*62c56f98SSadaf Ebrahimi         psa_drv_se_validate_slot_number_t p_validate_slot_number =
206*62c56f98SSadaf Ebrahimi             driver->methods->key_management->p_validate_slot_number;
207*62c56f98SSadaf Ebrahimi         if (p_validate_slot_number == NULL) {
208*62c56f98SSadaf Ebrahimi             return PSA_ERROR_NOT_SUPPORTED;
209*62c56f98SSadaf Ebrahimi         }
210*62c56f98SSadaf Ebrahimi         status = p_validate_slot_number(&driver->u.context,
211*62c56f98SSadaf Ebrahimi                                         driver->u.internal.persistent_data,
212*62c56f98SSadaf Ebrahimi                                         attributes, method,
213*62c56f98SSadaf Ebrahimi                                         *slot_number);
214*62c56f98SSadaf Ebrahimi     } else if (method == PSA_KEY_CREATION_REGISTER) {
215*62c56f98SSadaf Ebrahimi         /* The application didn't specify a slot number. This doesn't
216*62c56f98SSadaf Ebrahimi          * make sense when registering a slot. */
217*62c56f98SSadaf Ebrahimi         return PSA_ERROR_INVALID_ARGUMENT;
218*62c56f98SSadaf Ebrahimi     } else {
219*62c56f98SSadaf Ebrahimi         /* The application didn't tell us which slot to use. Let the driver
220*62c56f98SSadaf Ebrahimi          * choose. This is the normal case. */
221*62c56f98SSadaf Ebrahimi         psa_drv_se_allocate_key_t p_allocate =
222*62c56f98SSadaf Ebrahimi             driver->methods->key_management->p_allocate;
223*62c56f98SSadaf Ebrahimi         if (p_allocate == NULL) {
224*62c56f98SSadaf Ebrahimi             return PSA_ERROR_NOT_SUPPORTED;
225*62c56f98SSadaf Ebrahimi         }
226*62c56f98SSadaf Ebrahimi         status = p_allocate(&driver->u.context,
227*62c56f98SSadaf Ebrahimi                             driver->u.internal.persistent_data,
228*62c56f98SSadaf Ebrahimi                             attributes, method,
229*62c56f98SSadaf Ebrahimi                             slot_number);
230*62c56f98SSadaf Ebrahimi     }
231*62c56f98SSadaf Ebrahimi     return status;
232*62c56f98SSadaf Ebrahimi }
233*62c56f98SSadaf Ebrahimi 
psa_destroy_se_key(psa_se_drv_table_entry_t * driver,psa_key_slot_number_t slot_number)234*62c56f98SSadaf Ebrahimi psa_status_t psa_destroy_se_key(psa_se_drv_table_entry_t *driver,
235*62c56f98SSadaf Ebrahimi                                 psa_key_slot_number_t slot_number)
236*62c56f98SSadaf Ebrahimi {
237*62c56f98SSadaf Ebrahimi     psa_status_t status;
238*62c56f98SSadaf Ebrahimi     psa_status_t storage_status;
239*62c56f98SSadaf Ebrahimi     /* Normally a missing method would mean that the action is not
240*62c56f98SSadaf Ebrahimi      * supported. But psa_destroy_key() is not supposed to return
241*62c56f98SSadaf Ebrahimi      * PSA_ERROR_NOT_SUPPORTED: if you can create a key, you should
242*62c56f98SSadaf Ebrahimi      * be able to destroy it. The only use case for a driver that
243*62c56f98SSadaf Ebrahimi      * does not have a way to destroy keys at all is if the keys are
244*62c56f98SSadaf Ebrahimi      * locked in a read-only state: we can use the keys but not
245*62c56f98SSadaf Ebrahimi      * destroy them. Hence, if the driver doesn't support destroying
246*62c56f98SSadaf Ebrahimi      * keys, it's really a lack of permission. */
247*62c56f98SSadaf Ebrahimi     if (driver->methods->key_management == NULL ||
248*62c56f98SSadaf Ebrahimi         driver->methods->key_management->p_destroy == NULL) {
249*62c56f98SSadaf Ebrahimi         return PSA_ERROR_NOT_PERMITTED;
250*62c56f98SSadaf Ebrahimi     }
251*62c56f98SSadaf Ebrahimi     status = driver->methods->key_management->p_destroy(
252*62c56f98SSadaf Ebrahimi         &driver->u.context,
253*62c56f98SSadaf Ebrahimi         driver->u.internal.persistent_data,
254*62c56f98SSadaf Ebrahimi         slot_number);
255*62c56f98SSadaf Ebrahimi     storage_status = psa_save_se_persistent_data(driver);
256*62c56f98SSadaf Ebrahimi     return status == PSA_SUCCESS ? storage_status : status;
257*62c56f98SSadaf Ebrahimi }
258*62c56f98SSadaf Ebrahimi 
psa_init_all_se_drivers(void)259*62c56f98SSadaf Ebrahimi psa_status_t psa_init_all_se_drivers(void)
260*62c56f98SSadaf Ebrahimi {
261*62c56f98SSadaf Ebrahimi     size_t i;
262*62c56f98SSadaf Ebrahimi     for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
263*62c56f98SSadaf Ebrahimi         psa_se_drv_table_entry_t *driver = &driver_table[i];
264*62c56f98SSadaf Ebrahimi         if (driver->location == 0) {
265*62c56f98SSadaf Ebrahimi             continue; /* skipping unused entry */
266*62c56f98SSadaf Ebrahimi         }
267*62c56f98SSadaf Ebrahimi         const psa_drv_se_t *methods = psa_get_se_driver_methods(driver);
268*62c56f98SSadaf Ebrahimi         if (methods->p_init != NULL) {
269*62c56f98SSadaf Ebrahimi             psa_status_t status = methods->p_init(
270*62c56f98SSadaf Ebrahimi                 &driver->u.context,
271*62c56f98SSadaf Ebrahimi                 driver->u.internal.persistent_data,
272*62c56f98SSadaf Ebrahimi                 driver->location);
273*62c56f98SSadaf Ebrahimi             if (status != PSA_SUCCESS) {
274*62c56f98SSadaf Ebrahimi                 return status;
275*62c56f98SSadaf Ebrahimi             }
276*62c56f98SSadaf Ebrahimi             status = psa_save_se_persistent_data(driver);
277*62c56f98SSadaf Ebrahimi             if (status != PSA_SUCCESS) {
278*62c56f98SSadaf Ebrahimi                 return status;
279*62c56f98SSadaf Ebrahimi             }
280*62c56f98SSadaf Ebrahimi         }
281*62c56f98SSadaf Ebrahimi     }
282*62c56f98SSadaf Ebrahimi     return PSA_SUCCESS;
283*62c56f98SSadaf Ebrahimi }
284*62c56f98SSadaf Ebrahimi 
285*62c56f98SSadaf Ebrahimi 
286*62c56f98SSadaf Ebrahimi 
287*62c56f98SSadaf Ebrahimi /****************************************************************/
288*62c56f98SSadaf Ebrahimi /* Driver registration */
289*62c56f98SSadaf Ebrahimi /****************************************************************/
290*62c56f98SSadaf Ebrahimi 
psa_register_se_driver(psa_key_location_t location,const psa_drv_se_t * methods)291*62c56f98SSadaf Ebrahimi psa_status_t psa_register_se_driver(
292*62c56f98SSadaf Ebrahimi     psa_key_location_t location,
293*62c56f98SSadaf Ebrahimi     const psa_drv_se_t *methods)
294*62c56f98SSadaf Ebrahimi {
295*62c56f98SSadaf Ebrahimi     size_t i;
296*62c56f98SSadaf Ebrahimi     psa_status_t status;
297*62c56f98SSadaf Ebrahimi 
298*62c56f98SSadaf Ebrahimi     if (methods->hal_version != PSA_DRV_SE_HAL_VERSION) {
299*62c56f98SSadaf Ebrahimi         return PSA_ERROR_NOT_SUPPORTED;
300*62c56f98SSadaf Ebrahimi     }
301*62c56f98SSadaf Ebrahimi     /* Driver table entries are 0-initialized. 0 is not a valid driver
302*62c56f98SSadaf Ebrahimi      * location because it means a transparent key. */
303*62c56f98SSadaf Ebrahimi     MBEDTLS_STATIC_ASSERT(PSA_KEY_LOCATION_LOCAL_STORAGE == 0,
304*62c56f98SSadaf Ebrahimi                           "Secure element support requires 0 to mean a local key");
305*62c56f98SSadaf Ebrahimi 
306*62c56f98SSadaf Ebrahimi     if (location == PSA_KEY_LOCATION_LOCAL_STORAGE) {
307*62c56f98SSadaf Ebrahimi         return PSA_ERROR_INVALID_ARGUMENT;
308*62c56f98SSadaf Ebrahimi     }
309*62c56f98SSadaf Ebrahimi     if (location > PSA_MAX_SE_LOCATION) {
310*62c56f98SSadaf Ebrahimi         return PSA_ERROR_NOT_SUPPORTED;
311*62c56f98SSadaf Ebrahimi     }
312*62c56f98SSadaf Ebrahimi 
313*62c56f98SSadaf Ebrahimi     for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
314*62c56f98SSadaf Ebrahimi         if (driver_table[i].location == 0) {
315*62c56f98SSadaf Ebrahimi             break;
316*62c56f98SSadaf Ebrahimi         }
317*62c56f98SSadaf Ebrahimi         /* Check that location isn't already in use up to the first free
318*62c56f98SSadaf Ebrahimi          * entry. Since entries are created in order and never deleted,
319*62c56f98SSadaf Ebrahimi          * there can't be a used entry after the first free entry. */
320*62c56f98SSadaf Ebrahimi         if (driver_table[i].location == location) {
321*62c56f98SSadaf Ebrahimi             return PSA_ERROR_ALREADY_EXISTS;
322*62c56f98SSadaf Ebrahimi         }
323*62c56f98SSadaf Ebrahimi     }
324*62c56f98SSadaf Ebrahimi     if (i == PSA_MAX_SE_DRIVERS) {
325*62c56f98SSadaf Ebrahimi         return PSA_ERROR_INSUFFICIENT_MEMORY;
326*62c56f98SSadaf Ebrahimi     }
327*62c56f98SSadaf Ebrahimi 
328*62c56f98SSadaf Ebrahimi     driver_table[i].location = location;
329*62c56f98SSadaf Ebrahimi     driver_table[i].methods = methods;
330*62c56f98SSadaf Ebrahimi     driver_table[i].u.internal.persistent_data_size =
331*62c56f98SSadaf Ebrahimi         methods->persistent_data_size;
332*62c56f98SSadaf Ebrahimi 
333*62c56f98SSadaf Ebrahimi     if (methods->persistent_data_size != 0) {
334*62c56f98SSadaf Ebrahimi         driver_table[i].u.internal.persistent_data =
335*62c56f98SSadaf Ebrahimi             mbedtls_calloc(1, methods->persistent_data_size);
336*62c56f98SSadaf Ebrahimi         if (driver_table[i].u.internal.persistent_data == NULL) {
337*62c56f98SSadaf Ebrahimi             status = PSA_ERROR_INSUFFICIENT_MEMORY;
338*62c56f98SSadaf Ebrahimi             goto error;
339*62c56f98SSadaf Ebrahimi         }
340*62c56f98SSadaf Ebrahimi         /* Load the driver's persistent data. On first use, the persistent
341*62c56f98SSadaf Ebrahimi          * data does not exist in storage, and is initialized to
342*62c56f98SSadaf Ebrahimi          * all-bits-zero by the calloc call just above. */
343*62c56f98SSadaf Ebrahimi         status = psa_load_se_persistent_data(&driver_table[i]);
344*62c56f98SSadaf Ebrahimi         if (status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST) {
345*62c56f98SSadaf Ebrahimi             goto error;
346*62c56f98SSadaf Ebrahimi         }
347*62c56f98SSadaf Ebrahimi     }
348*62c56f98SSadaf Ebrahimi 
349*62c56f98SSadaf Ebrahimi     return PSA_SUCCESS;
350*62c56f98SSadaf Ebrahimi 
351*62c56f98SSadaf Ebrahimi error:
352*62c56f98SSadaf Ebrahimi     memset(&driver_table[i], 0, sizeof(driver_table[i]));
353*62c56f98SSadaf Ebrahimi     return status;
354*62c56f98SSadaf Ebrahimi }
355*62c56f98SSadaf Ebrahimi 
psa_unregister_all_se_drivers(void)356*62c56f98SSadaf Ebrahimi void psa_unregister_all_se_drivers(void)
357*62c56f98SSadaf Ebrahimi {
358*62c56f98SSadaf Ebrahimi     size_t i;
359*62c56f98SSadaf Ebrahimi     for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
360*62c56f98SSadaf Ebrahimi         if (driver_table[i].u.internal.persistent_data != NULL) {
361*62c56f98SSadaf Ebrahimi             mbedtls_free(driver_table[i].u.internal.persistent_data);
362*62c56f98SSadaf Ebrahimi         }
363*62c56f98SSadaf Ebrahimi     }
364*62c56f98SSadaf Ebrahimi     memset(driver_table, 0, sizeof(driver_table));
365*62c56f98SSadaf Ebrahimi }
366*62c56f98SSadaf Ebrahimi 
367*62c56f98SSadaf Ebrahimi 
368*62c56f98SSadaf Ebrahimi 
369*62c56f98SSadaf Ebrahimi /****************************************************************/
370*62c56f98SSadaf Ebrahimi /* The end */
371*62c56f98SSadaf Ebrahimi /****************************************************************/
372*62c56f98SSadaf Ebrahimi 
373*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
374