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