xref: /aosp_15_r20/external/mbedtls/library/psa_crypto_storage.c (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi /*
2*62c56f98SSadaf Ebrahimi  *  PSA persistent key storage
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_STORAGE_C)
12*62c56f98SSadaf Ebrahimi 
13*62c56f98SSadaf Ebrahimi #include <stdlib.h>
14*62c56f98SSadaf Ebrahimi #include <string.h>
15*62c56f98SSadaf Ebrahimi 
16*62c56f98SSadaf Ebrahimi #include "psa/crypto.h"
17*62c56f98SSadaf Ebrahimi #include "psa_crypto_storage.h"
18*62c56f98SSadaf Ebrahimi #include "mbedtls/platform_util.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 /* Key storage */
33*62c56f98SSadaf Ebrahimi /****************************************************************/
34*62c56f98SSadaf Ebrahimi 
35*62c56f98SSadaf Ebrahimi /* Determine a file name (ITS file identifier) for the given key identifier.
36*62c56f98SSadaf Ebrahimi  * The file name must be distinct from any file that is used for a purpose
37*62c56f98SSadaf Ebrahimi  * other than storing a key. Currently, the only such file is the random seed
38*62c56f98SSadaf Ebrahimi  * file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID and whose value is
39*62c56f98SSadaf Ebrahimi  * 0xFFFFFF52. */
psa_its_identifier_of_slot(mbedtls_svc_key_id_t key)40*62c56f98SSadaf Ebrahimi static psa_storage_uid_t psa_its_identifier_of_slot(mbedtls_svc_key_id_t key)
41*62c56f98SSadaf Ebrahimi {
42*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
43*62c56f98SSadaf Ebrahimi     /* Encode the owner in the upper 32 bits. This means that if
44*62c56f98SSadaf Ebrahimi      * owner values are nonzero (as they are on a PSA platform),
45*62c56f98SSadaf Ebrahimi      * no key file will ever have a value less than 0x100000000, so
46*62c56f98SSadaf Ebrahimi      * the whole range 0..0xffffffff is available for non-key files. */
47*62c56f98SSadaf Ebrahimi     uint32_t unsigned_owner_id = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(key);
48*62c56f98SSadaf Ebrahimi     return ((uint64_t) unsigned_owner_id << 32) |
49*62c56f98SSadaf Ebrahimi            MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key);
50*62c56f98SSadaf Ebrahimi #else
51*62c56f98SSadaf Ebrahimi     /* Use the key id directly as a file name.
52*62c56f98SSadaf Ebrahimi      * psa_is_key_id_valid() in psa_crypto_slot_management.c
53*62c56f98SSadaf Ebrahimi      * is responsible for ensuring that key identifiers do not have a
54*62c56f98SSadaf Ebrahimi      * value that is reserved for non-key files. */
55*62c56f98SSadaf Ebrahimi     return key;
56*62c56f98SSadaf Ebrahimi #endif
57*62c56f98SSadaf Ebrahimi }
58*62c56f98SSadaf Ebrahimi 
59*62c56f98SSadaf Ebrahimi /**
60*62c56f98SSadaf Ebrahimi  * \brief Load persistent data for the given key slot number.
61*62c56f98SSadaf Ebrahimi  *
62*62c56f98SSadaf Ebrahimi  * This function reads data from a storage backend and returns the data in a
63*62c56f98SSadaf Ebrahimi  * buffer.
64*62c56f98SSadaf Ebrahimi  *
65*62c56f98SSadaf Ebrahimi  * \param key               Persistent identifier of the key to be loaded. This
66*62c56f98SSadaf Ebrahimi  *                          should be an occupied storage location.
67*62c56f98SSadaf Ebrahimi  * \param[out] data         Buffer where the data is to be written.
68*62c56f98SSadaf Ebrahimi  * \param data_size         Size of the \c data buffer in bytes.
69*62c56f98SSadaf Ebrahimi  *
70*62c56f98SSadaf Ebrahimi  * \retval #PSA_SUCCESS \emptydescription
71*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_DATA_INVALID \emptydescription
72*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
73*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
74*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
75*62c56f98SSadaf Ebrahimi  */
psa_crypto_storage_load(const mbedtls_svc_key_id_t key,uint8_t * data,size_t data_size)76*62c56f98SSadaf Ebrahimi static psa_status_t psa_crypto_storage_load(
77*62c56f98SSadaf Ebrahimi     const mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size)
78*62c56f98SSadaf Ebrahimi {
79*62c56f98SSadaf Ebrahimi     psa_status_t status;
80*62c56f98SSadaf Ebrahimi     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
81*62c56f98SSadaf Ebrahimi     struct psa_storage_info_t data_identifier_info;
82*62c56f98SSadaf Ebrahimi     size_t data_length = 0;
83*62c56f98SSadaf Ebrahimi 
84*62c56f98SSadaf Ebrahimi     status = psa_its_get_info(data_identifier, &data_identifier_info);
85*62c56f98SSadaf Ebrahimi     if (status  != PSA_SUCCESS) {
86*62c56f98SSadaf Ebrahimi         return status;
87*62c56f98SSadaf Ebrahimi     }
88*62c56f98SSadaf Ebrahimi 
89*62c56f98SSadaf Ebrahimi     status = psa_its_get(data_identifier, 0, (uint32_t) data_size, data, &data_length);
90*62c56f98SSadaf Ebrahimi     if (data_size  != data_length) {
91*62c56f98SSadaf Ebrahimi         return PSA_ERROR_DATA_INVALID;
92*62c56f98SSadaf Ebrahimi     }
93*62c56f98SSadaf Ebrahimi 
94*62c56f98SSadaf Ebrahimi     return status;
95*62c56f98SSadaf Ebrahimi }
96*62c56f98SSadaf Ebrahimi 
psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key)97*62c56f98SSadaf Ebrahimi int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key)
98*62c56f98SSadaf Ebrahimi {
99*62c56f98SSadaf Ebrahimi     psa_status_t ret;
100*62c56f98SSadaf Ebrahimi     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
101*62c56f98SSadaf Ebrahimi     struct psa_storage_info_t data_identifier_info;
102*62c56f98SSadaf Ebrahimi 
103*62c56f98SSadaf Ebrahimi     ret = psa_its_get_info(data_identifier, &data_identifier_info);
104*62c56f98SSadaf Ebrahimi 
105*62c56f98SSadaf Ebrahimi     if (ret == PSA_ERROR_DOES_NOT_EXIST) {
106*62c56f98SSadaf Ebrahimi         return 0;
107*62c56f98SSadaf Ebrahimi     }
108*62c56f98SSadaf Ebrahimi     return 1;
109*62c56f98SSadaf Ebrahimi }
110*62c56f98SSadaf Ebrahimi 
111*62c56f98SSadaf Ebrahimi /**
112*62c56f98SSadaf Ebrahimi  * \brief Store persistent data for the given key slot number.
113*62c56f98SSadaf Ebrahimi  *
114*62c56f98SSadaf Ebrahimi  * This function stores the given data buffer to a persistent storage.
115*62c56f98SSadaf Ebrahimi  *
116*62c56f98SSadaf Ebrahimi  * \param key           Persistent identifier of the key to be stored. This
117*62c56f98SSadaf Ebrahimi  *                      should be an unoccupied storage location.
118*62c56f98SSadaf Ebrahimi  * \param[in] data      Buffer containing the data to be stored.
119*62c56f98SSadaf Ebrahimi  * \param data_length   The number of bytes
120*62c56f98SSadaf Ebrahimi  *                      that make up the data.
121*62c56f98SSadaf Ebrahimi  *
122*62c56f98SSadaf Ebrahimi  * \retval #PSA_SUCCESS \emptydescription
123*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
124*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
125*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
126*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_DATA_INVALID \emptydescription
127*62c56f98SSadaf Ebrahimi  */
psa_crypto_storage_store(const mbedtls_svc_key_id_t key,const uint8_t * data,size_t data_length)128*62c56f98SSadaf Ebrahimi static psa_status_t psa_crypto_storage_store(const mbedtls_svc_key_id_t key,
129*62c56f98SSadaf Ebrahimi                                              const uint8_t *data,
130*62c56f98SSadaf Ebrahimi                                              size_t data_length)
131*62c56f98SSadaf Ebrahimi {
132*62c56f98SSadaf Ebrahimi     psa_status_t status;
133*62c56f98SSadaf Ebrahimi     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
134*62c56f98SSadaf Ebrahimi     struct psa_storage_info_t data_identifier_info;
135*62c56f98SSadaf Ebrahimi 
136*62c56f98SSadaf Ebrahimi     if (psa_is_key_present_in_storage(key) == 1) {
137*62c56f98SSadaf Ebrahimi         return PSA_ERROR_ALREADY_EXISTS;
138*62c56f98SSadaf Ebrahimi     }
139*62c56f98SSadaf Ebrahimi 
140*62c56f98SSadaf Ebrahimi     status = psa_its_set(data_identifier, (uint32_t) data_length, data, 0);
141*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS) {
142*62c56f98SSadaf Ebrahimi         return PSA_ERROR_DATA_INVALID;
143*62c56f98SSadaf Ebrahimi     }
144*62c56f98SSadaf Ebrahimi 
145*62c56f98SSadaf Ebrahimi     status = psa_its_get_info(data_identifier, &data_identifier_info);
146*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS) {
147*62c56f98SSadaf Ebrahimi         goto exit;
148*62c56f98SSadaf Ebrahimi     }
149*62c56f98SSadaf Ebrahimi 
150*62c56f98SSadaf Ebrahimi     if (data_identifier_info.size != data_length) {
151*62c56f98SSadaf Ebrahimi         status = PSA_ERROR_DATA_INVALID;
152*62c56f98SSadaf Ebrahimi         goto exit;
153*62c56f98SSadaf Ebrahimi     }
154*62c56f98SSadaf Ebrahimi 
155*62c56f98SSadaf Ebrahimi exit:
156*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS) {
157*62c56f98SSadaf Ebrahimi         /* Remove the file in case we managed to create it but something
158*62c56f98SSadaf Ebrahimi          * went wrong. It's ok if the file doesn't exist. If the file exists
159*62c56f98SSadaf Ebrahimi          * but the removal fails, we're already reporting an error so there's
160*62c56f98SSadaf Ebrahimi          * nothing else we can do. */
161*62c56f98SSadaf Ebrahimi         (void) psa_its_remove(data_identifier);
162*62c56f98SSadaf Ebrahimi     }
163*62c56f98SSadaf Ebrahimi     return status;
164*62c56f98SSadaf Ebrahimi }
165*62c56f98SSadaf Ebrahimi 
psa_destroy_persistent_key(const mbedtls_svc_key_id_t key)166*62c56f98SSadaf Ebrahimi psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key)
167*62c56f98SSadaf Ebrahimi {
168*62c56f98SSadaf Ebrahimi     psa_status_t ret;
169*62c56f98SSadaf Ebrahimi     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
170*62c56f98SSadaf Ebrahimi     struct psa_storage_info_t data_identifier_info;
171*62c56f98SSadaf Ebrahimi 
172*62c56f98SSadaf Ebrahimi     ret = psa_its_get_info(data_identifier, &data_identifier_info);
173*62c56f98SSadaf Ebrahimi     if (ret == PSA_ERROR_DOES_NOT_EXIST) {
174*62c56f98SSadaf Ebrahimi         return PSA_SUCCESS;
175*62c56f98SSadaf Ebrahimi     }
176*62c56f98SSadaf Ebrahimi 
177*62c56f98SSadaf Ebrahimi     if (psa_its_remove(data_identifier) != PSA_SUCCESS) {
178*62c56f98SSadaf Ebrahimi         return PSA_ERROR_DATA_INVALID;
179*62c56f98SSadaf Ebrahimi     }
180*62c56f98SSadaf Ebrahimi 
181*62c56f98SSadaf Ebrahimi     ret = psa_its_get_info(data_identifier, &data_identifier_info);
182*62c56f98SSadaf Ebrahimi     if (ret != PSA_ERROR_DOES_NOT_EXIST) {
183*62c56f98SSadaf Ebrahimi         return PSA_ERROR_DATA_INVALID;
184*62c56f98SSadaf Ebrahimi     }
185*62c56f98SSadaf Ebrahimi 
186*62c56f98SSadaf Ebrahimi     return PSA_SUCCESS;
187*62c56f98SSadaf Ebrahimi }
188*62c56f98SSadaf Ebrahimi 
189*62c56f98SSadaf Ebrahimi /**
190*62c56f98SSadaf Ebrahimi  * \brief Get data length for given key slot number.
191*62c56f98SSadaf Ebrahimi  *
192*62c56f98SSadaf Ebrahimi  * \param key               Persistent identifier whose stored data length
193*62c56f98SSadaf Ebrahimi  *                          is to be obtained.
194*62c56f98SSadaf Ebrahimi  * \param[out] data_length  The number of bytes that make up the data.
195*62c56f98SSadaf Ebrahimi  *
196*62c56f98SSadaf Ebrahimi  * \retval #PSA_SUCCESS \emptydescription
197*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
198*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
199*62c56f98SSadaf Ebrahimi  * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
200*62c56f98SSadaf Ebrahimi  */
psa_crypto_storage_get_data_length(const mbedtls_svc_key_id_t key,size_t * data_length)201*62c56f98SSadaf Ebrahimi static psa_status_t psa_crypto_storage_get_data_length(
202*62c56f98SSadaf Ebrahimi     const mbedtls_svc_key_id_t key,
203*62c56f98SSadaf Ebrahimi     size_t *data_length)
204*62c56f98SSadaf Ebrahimi {
205*62c56f98SSadaf Ebrahimi     psa_status_t status;
206*62c56f98SSadaf Ebrahimi     psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
207*62c56f98SSadaf Ebrahimi     struct psa_storage_info_t data_identifier_info;
208*62c56f98SSadaf Ebrahimi 
209*62c56f98SSadaf Ebrahimi     status = psa_its_get_info(data_identifier, &data_identifier_info);
210*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS) {
211*62c56f98SSadaf Ebrahimi         return status;
212*62c56f98SSadaf Ebrahimi     }
213*62c56f98SSadaf Ebrahimi 
214*62c56f98SSadaf Ebrahimi     *data_length = (size_t) data_identifier_info.size;
215*62c56f98SSadaf Ebrahimi 
216*62c56f98SSadaf Ebrahimi     return PSA_SUCCESS;
217*62c56f98SSadaf Ebrahimi }
218*62c56f98SSadaf Ebrahimi 
219*62c56f98SSadaf Ebrahimi /**
220*62c56f98SSadaf Ebrahimi  * Persistent key storage magic header.
221*62c56f98SSadaf Ebrahimi  */
222*62c56f98SSadaf Ebrahimi #define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
223*62c56f98SSadaf Ebrahimi #define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER))
224*62c56f98SSadaf Ebrahimi 
225*62c56f98SSadaf Ebrahimi typedef struct {
226*62c56f98SSadaf Ebrahimi     uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
227*62c56f98SSadaf Ebrahimi     uint8_t version[4];
228*62c56f98SSadaf Ebrahimi     uint8_t lifetime[sizeof(psa_key_lifetime_t)];
229*62c56f98SSadaf Ebrahimi     uint8_t type[2];
230*62c56f98SSadaf Ebrahimi     uint8_t bits[2];
231*62c56f98SSadaf Ebrahimi     uint8_t policy[sizeof(psa_key_policy_t)];
232*62c56f98SSadaf Ebrahimi     uint8_t data_len[4];
233*62c56f98SSadaf Ebrahimi     uint8_t key_data[];
234*62c56f98SSadaf Ebrahimi } psa_persistent_key_storage_format;
235*62c56f98SSadaf Ebrahimi 
psa_format_key_data_for_storage(const uint8_t * data,const size_t data_length,const psa_core_key_attributes_t * attr,uint8_t * storage_data)236*62c56f98SSadaf Ebrahimi void psa_format_key_data_for_storage(const uint8_t *data,
237*62c56f98SSadaf Ebrahimi                                      const size_t data_length,
238*62c56f98SSadaf Ebrahimi                                      const psa_core_key_attributes_t *attr,
239*62c56f98SSadaf Ebrahimi                                      uint8_t *storage_data)
240*62c56f98SSadaf Ebrahimi {
241*62c56f98SSadaf Ebrahimi     psa_persistent_key_storage_format *storage_format =
242*62c56f98SSadaf Ebrahimi         (psa_persistent_key_storage_format *) storage_data;
243*62c56f98SSadaf Ebrahimi 
244*62c56f98SSadaf Ebrahimi     memcpy(storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER,
245*62c56f98SSadaf Ebrahimi            PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH);
246*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT32_LE(0, storage_format->version, 0);
247*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT32_LE(attr->lifetime, storage_format->lifetime, 0);
248*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_LE((uint16_t) attr->type, storage_format->type, 0);
249*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_LE((uint16_t) attr->bits, storage_format->bits, 0);
250*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT32_LE(attr->policy.usage, storage_format->policy, 0);
251*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT32_LE(attr->policy.alg, storage_format->policy, sizeof(uint32_t));
252*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT32_LE(attr->policy.alg2, storage_format->policy, 2 * sizeof(uint32_t));
253*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT32_LE(data_length, storage_format->data_len, 0);
254*62c56f98SSadaf Ebrahimi     memcpy(storage_format->key_data, data, data_length);
255*62c56f98SSadaf Ebrahimi }
256*62c56f98SSadaf Ebrahimi 
check_magic_header(const uint8_t * data)257*62c56f98SSadaf Ebrahimi static psa_status_t check_magic_header(const uint8_t *data)
258*62c56f98SSadaf Ebrahimi {
259*62c56f98SSadaf Ebrahimi     if (memcmp(data, PSA_KEY_STORAGE_MAGIC_HEADER,
260*62c56f98SSadaf Ebrahimi                PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH) != 0) {
261*62c56f98SSadaf Ebrahimi         return PSA_ERROR_DATA_INVALID;
262*62c56f98SSadaf Ebrahimi     }
263*62c56f98SSadaf Ebrahimi     return PSA_SUCCESS;
264*62c56f98SSadaf Ebrahimi }
265*62c56f98SSadaf Ebrahimi 
psa_parse_key_data_from_storage(const uint8_t * storage_data,size_t storage_data_length,uint8_t ** key_data,size_t * key_data_length,psa_core_key_attributes_t * attr)266*62c56f98SSadaf Ebrahimi psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
267*62c56f98SSadaf Ebrahimi                                              size_t storage_data_length,
268*62c56f98SSadaf Ebrahimi                                              uint8_t **key_data,
269*62c56f98SSadaf Ebrahimi                                              size_t *key_data_length,
270*62c56f98SSadaf Ebrahimi                                              psa_core_key_attributes_t *attr)
271*62c56f98SSadaf Ebrahimi {
272*62c56f98SSadaf Ebrahimi     psa_status_t status;
273*62c56f98SSadaf Ebrahimi     const psa_persistent_key_storage_format *storage_format =
274*62c56f98SSadaf Ebrahimi         (const psa_persistent_key_storage_format *) storage_data;
275*62c56f98SSadaf Ebrahimi     uint32_t version;
276*62c56f98SSadaf Ebrahimi 
277*62c56f98SSadaf Ebrahimi     if (storage_data_length < sizeof(*storage_format)) {
278*62c56f98SSadaf Ebrahimi         return PSA_ERROR_DATA_INVALID;
279*62c56f98SSadaf Ebrahimi     }
280*62c56f98SSadaf Ebrahimi 
281*62c56f98SSadaf Ebrahimi     status = check_magic_header(storage_data);
282*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS) {
283*62c56f98SSadaf Ebrahimi         return status;
284*62c56f98SSadaf Ebrahimi     }
285*62c56f98SSadaf Ebrahimi 
286*62c56f98SSadaf Ebrahimi     version = MBEDTLS_GET_UINT32_LE(storage_format->version, 0);
287*62c56f98SSadaf Ebrahimi     if (version != 0) {
288*62c56f98SSadaf Ebrahimi         return PSA_ERROR_DATA_INVALID;
289*62c56f98SSadaf Ebrahimi     }
290*62c56f98SSadaf Ebrahimi 
291*62c56f98SSadaf Ebrahimi     *key_data_length = MBEDTLS_GET_UINT32_LE(storage_format->data_len, 0);
292*62c56f98SSadaf Ebrahimi     if (*key_data_length > (storage_data_length - sizeof(*storage_format)) ||
293*62c56f98SSadaf Ebrahimi         *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) {
294*62c56f98SSadaf Ebrahimi         return PSA_ERROR_DATA_INVALID;
295*62c56f98SSadaf Ebrahimi     }
296*62c56f98SSadaf Ebrahimi 
297*62c56f98SSadaf Ebrahimi     if (*key_data_length == 0) {
298*62c56f98SSadaf Ebrahimi         *key_data = NULL;
299*62c56f98SSadaf Ebrahimi     } else {
300*62c56f98SSadaf Ebrahimi         *key_data = mbedtls_calloc(1, *key_data_length);
301*62c56f98SSadaf Ebrahimi         if (*key_data == NULL) {
302*62c56f98SSadaf Ebrahimi             return PSA_ERROR_INSUFFICIENT_MEMORY;
303*62c56f98SSadaf Ebrahimi         }
304*62c56f98SSadaf Ebrahimi         memcpy(*key_data, storage_format->key_data, *key_data_length);
305*62c56f98SSadaf Ebrahimi     }
306*62c56f98SSadaf Ebrahimi 
307*62c56f98SSadaf Ebrahimi     attr->lifetime = MBEDTLS_GET_UINT32_LE(storage_format->lifetime, 0);
308*62c56f98SSadaf Ebrahimi     attr->type = MBEDTLS_GET_UINT16_LE(storage_format->type, 0);
309*62c56f98SSadaf Ebrahimi     attr->bits = MBEDTLS_GET_UINT16_LE(storage_format->bits, 0);
310*62c56f98SSadaf Ebrahimi     attr->policy.usage = MBEDTLS_GET_UINT32_LE(storage_format->policy, 0);
311*62c56f98SSadaf Ebrahimi     attr->policy.alg = MBEDTLS_GET_UINT32_LE(storage_format->policy, sizeof(uint32_t));
312*62c56f98SSadaf Ebrahimi     attr->policy.alg2 = MBEDTLS_GET_UINT32_LE(storage_format->policy, 2 * sizeof(uint32_t));
313*62c56f98SSadaf Ebrahimi 
314*62c56f98SSadaf Ebrahimi     return PSA_SUCCESS;
315*62c56f98SSadaf Ebrahimi }
316*62c56f98SSadaf Ebrahimi 
psa_save_persistent_key(const psa_core_key_attributes_t * attr,const uint8_t * data,const size_t data_length)317*62c56f98SSadaf Ebrahimi psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
318*62c56f98SSadaf Ebrahimi                                      const uint8_t *data,
319*62c56f98SSadaf Ebrahimi                                      const size_t data_length)
320*62c56f98SSadaf Ebrahimi {
321*62c56f98SSadaf Ebrahimi     size_t storage_data_length;
322*62c56f98SSadaf Ebrahimi     uint8_t *storage_data;
323*62c56f98SSadaf Ebrahimi     psa_status_t status;
324*62c56f98SSadaf Ebrahimi 
325*62c56f98SSadaf Ebrahimi     /* All keys saved to persistent storage always have a key context */
326*62c56f98SSadaf Ebrahimi     if (data == NULL || data_length == 0) {
327*62c56f98SSadaf Ebrahimi         return PSA_ERROR_INVALID_ARGUMENT;
328*62c56f98SSadaf Ebrahimi     }
329*62c56f98SSadaf Ebrahimi 
330*62c56f98SSadaf Ebrahimi     if (data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) {
331*62c56f98SSadaf Ebrahimi         return PSA_ERROR_INSUFFICIENT_STORAGE;
332*62c56f98SSadaf Ebrahimi     }
333*62c56f98SSadaf Ebrahimi     storage_data_length = data_length + sizeof(psa_persistent_key_storage_format);
334*62c56f98SSadaf Ebrahimi 
335*62c56f98SSadaf Ebrahimi     storage_data = mbedtls_calloc(1, storage_data_length);
336*62c56f98SSadaf Ebrahimi     if (storage_data == NULL) {
337*62c56f98SSadaf Ebrahimi         return PSA_ERROR_INSUFFICIENT_MEMORY;
338*62c56f98SSadaf Ebrahimi     }
339*62c56f98SSadaf Ebrahimi 
340*62c56f98SSadaf Ebrahimi     psa_format_key_data_for_storage(data, data_length, attr, storage_data);
341*62c56f98SSadaf Ebrahimi 
342*62c56f98SSadaf Ebrahimi     status = psa_crypto_storage_store(attr->id,
343*62c56f98SSadaf Ebrahimi                                       storage_data, storage_data_length);
344*62c56f98SSadaf Ebrahimi 
345*62c56f98SSadaf Ebrahimi     mbedtls_zeroize_and_free(storage_data, storage_data_length);
346*62c56f98SSadaf Ebrahimi 
347*62c56f98SSadaf Ebrahimi     return status;
348*62c56f98SSadaf Ebrahimi }
349*62c56f98SSadaf Ebrahimi 
psa_free_persistent_key_data(uint8_t * key_data,size_t key_data_length)350*62c56f98SSadaf Ebrahimi void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length)
351*62c56f98SSadaf Ebrahimi {
352*62c56f98SSadaf Ebrahimi     mbedtls_zeroize_and_free(key_data, key_data_length);
353*62c56f98SSadaf Ebrahimi }
354*62c56f98SSadaf Ebrahimi 
psa_load_persistent_key(psa_core_key_attributes_t * attr,uint8_t ** data,size_t * data_length)355*62c56f98SSadaf Ebrahimi psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
356*62c56f98SSadaf Ebrahimi                                      uint8_t **data,
357*62c56f98SSadaf Ebrahimi                                      size_t *data_length)
358*62c56f98SSadaf Ebrahimi {
359*62c56f98SSadaf Ebrahimi     psa_status_t status = PSA_SUCCESS;
360*62c56f98SSadaf Ebrahimi     uint8_t *loaded_data;
361*62c56f98SSadaf Ebrahimi     size_t storage_data_length = 0;
362*62c56f98SSadaf Ebrahimi     mbedtls_svc_key_id_t key = attr->id;
363*62c56f98SSadaf Ebrahimi 
364*62c56f98SSadaf Ebrahimi     status = psa_crypto_storage_get_data_length(key, &storage_data_length);
365*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS) {
366*62c56f98SSadaf Ebrahimi         return status;
367*62c56f98SSadaf Ebrahimi     }
368*62c56f98SSadaf Ebrahimi 
369*62c56f98SSadaf Ebrahimi     loaded_data = mbedtls_calloc(1, storage_data_length);
370*62c56f98SSadaf Ebrahimi 
371*62c56f98SSadaf Ebrahimi     if (loaded_data == NULL) {
372*62c56f98SSadaf Ebrahimi         return PSA_ERROR_INSUFFICIENT_MEMORY;
373*62c56f98SSadaf Ebrahimi     }
374*62c56f98SSadaf Ebrahimi 
375*62c56f98SSadaf Ebrahimi     status = psa_crypto_storage_load(key, loaded_data, storage_data_length);
376*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS) {
377*62c56f98SSadaf Ebrahimi         goto exit;
378*62c56f98SSadaf Ebrahimi     }
379*62c56f98SSadaf Ebrahimi 
380*62c56f98SSadaf Ebrahimi     status = psa_parse_key_data_from_storage(loaded_data, storage_data_length,
381*62c56f98SSadaf Ebrahimi                                              data, data_length, attr);
382*62c56f98SSadaf Ebrahimi 
383*62c56f98SSadaf Ebrahimi     /* All keys saved to persistent storage always have a key context */
384*62c56f98SSadaf Ebrahimi     if (status == PSA_SUCCESS &&
385*62c56f98SSadaf Ebrahimi         (*data == NULL || *data_length == 0)) {
386*62c56f98SSadaf Ebrahimi         status = PSA_ERROR_STORAGE_FAILURE;
387*62c56f98SSadaf Ebrahimi     }
388*62c56f98SSadaf Ebrahimi 
389*62c56f98SSadaf Ebrahimi exit:
390*62c56f98SSadaf Ebrahimi     mbedtls_zeroize_and_free(loaded_data, storage_data_length);
391*62c56f98SSadaf Ebrahimi     return status;
392*62c56f98SSadaf Ebrahimi }
393*62c56f98SSadaf Ebrahimi 
394*62c56f98SSadaf Ebrahimi 
395*62c56f98SSadaf Ebrahimi 
396*62c56f98SSadaf Ebrahimi /****************************************************************/
397*62c56f98SSadaf Ebrahimi /* Transactions */
398*62c56f98SSadaf Ebrahimi /****************************************************************/
399*62c56f98SSadaf Ebrahimi 
400*62c56f98SSadaf Ebrahimi #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
401*62c56f98SSadaf Ebrahimi 
402*62c56f98SSadaf Ebrahimi psa_crypto_transaction_t psa_crypto_transaction;
403*62c56f98SSadaf Ebrahimi 
psa_crypto_save_transaction(void)404*62c56f98SSadaf Ebrahimi psa_status_t psa_crypto_save_transaction(void)
405*62c56f98SSadaf Ebrahimi {
406*62c56f98SSadaf Ebrahimi     struct psa_storage_info_t p_info;
407*62c56f98SSadaf Ebrahimi     psa_status_t status;
408*62c56f98SSadaf Ebrahimi     status = psa_its_get_info(PSA_CRYPTO_ITS_TRANSACTION_UID, &p_info);
409*62c56f98SSadaf Ebrahimi     if (status == PSA_SUCCESS) {
410*62c56f98SSadaf Ebrahimi         /* This shouldn't happen: we're trying to start a transaction while
411*62c56f98SSadaf Ebrahimi          * there is still a transaction that hasn't been replayed. */
412*62c56f98SSadaf Ebrahimi         return PSA_ERROR_CORRUPTION_DETECTED;
413*62c56f98SSadaf Ebrahimi     } else if (status != PSA_ERROR_DOES_NOT_EXIST) {
414*62c56f98SSadaf Ebrahimi         return status;
415*62c56f98SSadaf Ebrahimi     }
416*62c56f98SSadaf Ebrahimi     return psa_its_set(PSA_CRYPTO_ITS_TRANSACTION_UID,
417*62c56f98SSadaf Ebrahimi                        sizeof(psa_crypto_transaction),
418*62c56f98SSadaf Ebrahimi                        &psa_crypto_transaction,
419*62c56f98SSadaf Ebrahimi                        0);
420*62c56f98SSadaf Ebrahimi }
421*62c56f98SSadaf Ebrahimi 
psa_crypto_load_transaction(void)422*62c56f98SSadaf Ebrahimi psa_status_t psa_crypto_load_transaction(void)
423*62c56f98SSadaf Ebrahimi {
424*62c56f98SSadaf Ebrahimi     psa_status_t status;
425*62c56f98SSadaf Ebrahimi     size_t length;
426*62c56f98SSadaf Ebrahimi     status = psa_its_get(PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
427*62c56f98SSadaf Ebrahimi                          sizeof(psa_crypto_transaction),
428*62c56f98SSadaf Ebrahimi                          &psa_crypto_transaction, &length);
429*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS) {
430*62c56f98SSadaf Ebrahimi         return status;
431*62c56f98SSadaf Ebrahimi     }
432*62c56f98SSadaf Ebrahimi     if (length != sizeof(psa_crypto_transaction)) {
433*62c56f98SSadaf Ebrahimi         return PSA_ERROR_DATA_INVALID;
434*62c56f98SSadaf Ebrahimi     }
435*62c56f98SSadaf Ebrahimi     return PSA_SUCCESS;
436*62c56f98SSadaf Ebrahimi }
437*62c56f98SSadaf Ebrahimi 
psa_crypto_stop_transaction(void)438*62c56f98SSadaf Ebrahimi psa_status_t psa_crypto_stop_transaction(void)
439*62c56f98SSadaf Ebrahimi {
440*62c56f98SSadaf Ebrahimi     psa_status_t status = psa_its_remove(PSA_CRYPTO_ITS_TRANSACTION_UID);
441*62c56f98SSadaf Ebrahimi     /* Whether or not updating the storage succeeded, the transaction is
442*62c56f98SSadaf Ebrahimi      * finished now. It's too late to go back, so zero out the in-memory
443*62c56f98SSadaf Ebrahimi      * data. */
444*62c56f98SSadaf Ebrahimi     memset(&psa_crypto_transaction, 0, sizeof(psa_crypto_transaction));
445*62c56f98SSadaf Ebrahimi     return status;
446*62c56f98SSadaf Ebrahimi }
447*62c56f98SSadaf Ebrahimi 
448*62c56f98SSadaf Ebrahimi #endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
449*62c56f98SSadaf Ebrahimi 
450*62c56f98SSadaf Ebrahimi 
451*62c56f98SSadaf Ebrahimi 
452*62c56f98SSadaf Ebrahimi /****************************************************************/
453*62c56f98SSadaf Ebrahimi /* Random generator state */
454*62c56f98SSadaf Ebrahimi /****************************************************************/
455*62c56f98SSadaf Ebrahimi 
456*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_INJECT_ENTROPY)
mbedtls_psa_storage_inject_entropy(const unsigned char * seed,size_t seed_size)457*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_psa_storage_inject_entropy(const unsigned char *seed,
458*62c56f98SSadaf Ebrahimi                                                 size_t seed_size)
459*62c56f98SSadaf Ebrahimi {
460*62c56f98SSadaf Ebrahimi     psa_status_t status;
461*62c56f98SSadaf Ebrahimi     struct psa_storage_info_t p_info;
462*62c56f98SSadaf Ebrahimi 
463*62c56f98SSadaf Ebrahimi     status = psa_its_get_info(PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info);
464*62c56f98SSadaf Ebrahimi 
465*62c56f98SSadaf Ebrahimi     if (PSA_ERROR_DOES_NOT_EXIST == status) { /* No seed exists */
466*62c56f98SSadaf Ebrahimi         status = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0);
467*62c56f98SSadaf Ebrahimi     } else if (PSA_SUCCESS == status) {
468*62c56f98SSadaf Ebrahimi         /* You should not be here. Seed needs to be injected only once */
469*62c56f98SSadaf Ebrahimi         status = PSA_ERROR_NOT_PERMITTED;
470*62c56f98SSadaf Ebrahimi     }
471*62c56f98SSadaf Ebrahimi     return status;
472*62c56f98SSadaf Ebrahimi }
473*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_INJECT_ENTROPY */
474*62c56f98SSadaf Ebrahimi 
475*62c56f98SSadaf Ebrahimi 
476*62c56f98SSadaf Ebrahimi 
477*62c56f98SSadaf Ebrahimi /****************************************************************/
478*62c56f98SSadaf Ebrahimi /* The end */
479*62c56f98SSadaf Ebrahimi /****************************************************************/
480*62c56f98SSadaf Ebrahimi 
481*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
482