1 /*
2  *  PSA crypto support for secure element drivers
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_SE_H
10 #define PSA_CRYPTO_SE_H
11 
12 #include "mbedtls/build_info.h"
13 
14 #include "psa/crypto.h"
15 #include "psa/crypto_se_driver.h"
16 
17 /** The maximum location value that this implementation supports
18  * for a secure element.
19  *
20  * This is not a characteristic that each PSA implementation has, but a
21  * limitation of the current implementation due to the constraints imposed
22  * by storage. See #PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE.
23  *
24  * The minimum location value for a secure element is 1, like on any
25  * PSA implementation (0 means a transparent key).
26  */
27 #define PSA_MAX_SE_LOCATION 255
28 
29 /** The base of the range of ITS file identifiers for secure element
30  * driver persistent data.
31  *
32  * We use a slice of the implementation reserved range 0xffff0000..0xffffffff,
33  * specifically the range 0xfffffe00..0xfffffeff. The length of this range
34  * drives the value of #PSA_MAX_SE_LOCATION. The identifier 0xfffffe00 is
35  * actually not used since it corresponds to #PSA_KEY_LOCATION_LOCAL_STORAGE
36  * which doesn't have a driver.
37  */
38 #define PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE ((psa_key_id_t) 0xfffffe00)
39 
40 /** The maximum number of registered secure element driver locations. */
41 #define PSA_MAX_SE_DRIVERS 4
42 
43 /** Unregister all secure element drivers.
44  *
45  * \warning Do not call this function while the library is in the initialized
46  *          state. This function is only intended to be called at the end
47  *          of mbedtls_psa_crypto_free().
48  */
49 void psa_unregister_all_se_drivers(void);
50 
51 /** Initialize all secure element drivers.
52  *
53  * Called from psa_crypto_init().
54  */
55 psa_status_t psa_init_all_se_drivers(void);
56 
57 /** A structure that describes a registered secure element driver.
58  *
59  * A secure element driver table entry contains a pointer to the
60  * driver's method table as well as the driver context structure.
61  */
62 typedef struct psa_se_drv_table_entry_s psa_se_drv_table_entry_t;
63 
64 /** Return the secure element driver information for a lifetime value.
65  *
66  * \param lifetime              The lifetime value to query.
67  * \param[out] p_methods        On output, if there is a driver,
68  *                              \c *methods points to its method table.
69  *                              Otherwise \c *methods is \c NULL.
70  * \param[out] p_drv_context    On output, if there is a driver,
71  *                              \c *drv_context points to its context
72  *                              structure.
73  *                              Otherwise \c *drv_context is \c NULL.
74  *
75  * \retval 1
76  *         \p lifetime corresponds to a registered driver.
77  * \retval 0
78  *         \p lifetime does not correspond to a registered driver.
79  */
80 int psa_get_se_driver(psa_key_lifetime_t lifetime,
81                       const psa_drv_se_t **p_methods,
82                       psa_drv_se_context_t **p_drv_context);
83 
84 /** Return the secure element driver table entry for a lifetime value.
85  *
86  * \param lifetime      The lifetime value to query.
87  *
88  * \return The driver table entry for \p lifetime, or
89  *         \p NULL if \p lifetime does not correspond to a registered driver.
90  */
91 psa_se_drv_table_entry_t *psa_get_se_driver_entry(
92     psa_key_lifetime_t lifetime);
93 
94 /** Return the method table for a secure element driver.
95  *
96  * \param[in] driver    The driver table entry to access, or \c NULL.
97  *
98  * \return The driver's method table.
99  *         \c NULL if \p driver is \c NULL.
100  */
101 const psa_drv_se_t *psa_get_se_driver_methods(
102     const psa_se_drv_table_entry_t *driver);
103 
104 /** Return the context of a secure element driver.
105  *
106  * \param[in] driver    The driver table entry to access, or \c NULL.
107  *
108  * \return A pointer to the driver context.
109  *         \c NULL if \p driver is \c NULL.
110  */
111 psa_drv_se_context_t *psa_get_se_driver_context(
112     psa_se_drv_table_entry_t *driver);
113 
114 /** Find a free slot for a key that is to be created.
115  *
116  * This function calls the relevant method in the driver to find a suitable
117  * slot for a key with the given attributes.
118  *
119  * \param[in] attributes    Metadata about the key that is about to be created.
120  * \param[in] driver        The driver table entry to query.
121  * \param[out] slot_number  On success, a slot number that is free in this
122  *                          secure element.
123  */
124 psa_status_t psa_find_se_slot_for_key(
125     const psa_key_attributes_t *attributes,
126     psa_key_creation_method_t method,
127     psa_se_drv_table_entry_t *driver,
128     psa_key_slot_number_t *slot_number);
129 
130 /** Destroy a key in a secure element.
131  *
132  * This function calls the relevant driver method to destroy a key
133  * and updates the driver's persistent data.
134  */
135 psa_status_t psa_destroy_se_key(psa_se_drv_table_entry_t *driver,
136                                 psa_key_slot_number_t slot_number);
137 
138 /** Load the persistent data of a secure element driver.
139  *
140  * \param driver        The driver table entry containing the persistent
141  *                      data to load from storage.
142  *
143  * \return #PSA_SUCCESS
144  * \return #PSA_ERROR_NOT_SUPPORTED
145  * \return #PSA_ERROR_DOES_NOT_EXIST
146  * \return #PSA_ERROR_STORAGE_FAILURE
147  * \return #PSA_ERROR_DATA_CORRUPT
148  * \return #PSA_ERROR_INVALID_ARGUMENT
149  */
150 psa_status_t psa_load_se_persistent_data(
151     const psa_se_drv_table_entry_t *driver);
152 
153 /** Save the persistent data of a secure element driver.
154  *
155  * \param[in] driver    The driver table entry containing the persistent
156  *                      data to save to storage.
157  *
158  * \return #PSA_SUCCESS
159  * \return #PSA_ERROR_NOT_SUPPORTED
160  * \return #PSA_ERROR_NOT_PERMITTED
161  * \return #PSA_ERROR_NOT_SUPPORTED
162  * \return #PSA_ERROR_INSUFFICIENT_STORAGE
163  * \return #PSA_ERROR_STORAGE_FAILURE
164  * \return #PSA_ERROR_INVALID_ARGUMENT
165  */
166 psa_status_t psa_save_se_persistent_data(
167     const psa_se_drv_table_entry_t *driver);
168 
169 /** Destroy the persistent data of a secure element driver.
170  *
171  * This is currently only used for testing.
172  *
173  * \param[in] location  The location identifier for the driver whose
174  *                      persistent data is to be erased.
175  */
176 psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location);
177 
178 
179 /** The storage representation of a key whose data is in a secure element.
180  */
181 typedef struct {
182     uint8_t slot_number[sizeof(psa_key_slot_number_t)];
183 } psa_se_key_data_storage_t;
184 
185 #endif /* PSA_CRYPTO_SE_H */
186