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