1 /*
2 * Copyright (c) 2022-2024, Texas Instruments Incorporated - http://www.ti.com
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <stdint.h>
34 #include <stdbool.h>
35
36 #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyKeyStore_PSA.h>
37 #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyKeyStore_PSA_helpers.h>
38 #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyKeyStore_PSA_s.h>
39
40 #include <third_party/tfm/secure_fw/spm/core/spm.h>
41 #include <third_party/tfm/interface/include/psa/error.h>
42 #include <third_party/tfm/interface/include/psa/service.h>
43 #include <third_party/tfm/secure_fw/spm/include/utilities.h>
44
45 #include <third_party/tfm/platform/ext/target/ti/cc26x4/cmse.h> /* TI CMSE helper functions */
46 #include "ti_drivers_config.h" /* Sysconfig generated header */
47
48 /*
49 * ======== KeyStore_s_copyKeyAttributesFromClient ========
50 */
KeyStore_s_copyKeyAttributesFromClient(struct psa_client_key_attributes_s * clientKeyAttr,int32_t clientId,psa_key_attributes_t * keyAttributes)51 psa_status_t KeyStore_s_copyKeyAttributesFromClient(struct psa_client_key_attributes_s *clientKeyAttr,
52 int32_t clientId,
53 psa_key_attributes_t *keyAttributes)
54 {
55 if (clientKeyAttr == NULL || keyAttributes == NULL)
56 {
57 return PSA_ERROR_PROGRAMMER_ERROR;
58 }
59
60 *keyAttributes = psa_key_attributes_init();
61
62 /* Copy core key attributes from the client core key attributes */
63 keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type) = clientKeyAttr->type;
64 keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) = clientKeyAttr->lifetime;
65 keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = clientKeyAttr->usage;
66 keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = clientKeyAttr->alg;
67 keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = clientKeyAttr->bits;
68
69 /* Use the client key id as the key_id and its partition id as the owner */
70 keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = clientKeyAttr->id;
71 keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = clientId;
72
73 return PSA_SUCCESS;
74 }
75
76 /**
77 * \brief Converts key attributes to client key attributes.
78 * Follows tfm_crypto_key_attributes_to_client()
79 *
80 * \param[in] keyAttributes Key attributes, no address verification necessary as this is always in secure side
81 * \param[out] clientKeyAttr Client key attributes, address location must be verified to be in non-secure memory by
82 * calling functions
83 *
84 * \return Return values as described in \ref psa_status_t
85 */
86 /*
87 * ======== KeyStore_s_copyKeyAttributesToClient ========
88 */
KeyStore_s_copyKeyAttributesToClient(const psa_key_attributes_t * keyAttributes,struct psa_client_key_attributes_s * clientKeyAttr)89 static psa_status_t KeyStore_s_copyKeyAttributesToClient(const psa_key_attributes_t *keyAttributes,
90 struct psa_client_key_attributes_s *clientKeyAttr)
91 {
92 if (clientKeyAttr == NULL || keyAttributes == NULL)
93 {
94 return PSA_ERROR_PROGRAMMER_ERROR;
95 }
96
97 struct psa_client_key_attributes_s v = {0, 0, 0, 0, 0, 0};
98 *clientKeyAttr = v;
99
100 /* Copy core key attributes from the client core key attributes */
101 clientKeyAttr->type = keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type);
102 clientKeyAttr->lifetime = keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime);
103 clientKeyAttr->usage = keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage);
104 clientKeyAttr->alg = keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg);
105 clientKeyAttr->bits = keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits);
106
107 /* Return the key_id as the client key id, do not return the owner */
108 clientKeyAttr->id = keyAttributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id);
109
110 return PSA_SUCCESS;
111 }
112
113 /**
114 * \brief Copies key ID from secure side to client key ID
115 *
116 * \param[in] keyID Key ID, no address verification necessary as this is always in secure side
117 * \param[out] clientKeyID Client key ID, address location must be verified to be in non-secure memory by
118 * calling functions
119 *
120 */
121 /*
122 * ======== KeyStore_s_copyKeyIDtoClient ========
123 */
KeyStore_s_copyKeyIDtoClient(KeyStore_PSA_KeyFileId * keyID,uint32_t * clientKeyID)124 static void KeyStore_s_copyKeyIDtoClient(KeyStore_PSA_KeyFileId *keyID, uint32_t *clientKeyID)
125 {
126 /* Copy the keyID output from the KeyStore driver to client keyID */
127 *clientKeyID = keyID->MBEDTLS_PRIVATE(key_id);
128 }
129
130 /*
131 * ======== KeyStore_s_copyKeyIDFromClient ========
132 */
KeyStore_s_copyKeyIDFromClient(KeyStore_PSA_KeyFileId * keyID,int32_t clientId,uint32_t * clientKeyID)133 void KeyStore_s_copyKeyIDFromClient(KeyStore_PSA_KeyFileId *keyID, int32_t clientId, uint32_t *clientKeyID)
134 {
135 /* Copy keyID from client to KeyStore driver and set the owner to the caller's ID */
136 keyID->MBEDTLS_PRIVATE(key_id) = *clientKeyID;
137 keyID->MBEDTLS_PRIVATE(owner) = clientId;
138 }
139
140 /*
141 * ======== KeyStore_s_getKeyAttributes ========
142 */
KeyStore_s_getKeyAttributes(psa_msg_t * msg)143 psa_status_t KeyStore_s_getKeyAttributes(psa_msg_t *msg)
144 {
145 KeyStore_s_GetKeyAttributesMsg getKeyAttributesMsg;
146 int_fast16_t ret = KEYSTORE_PSA_STATUS_RESOURCE_UNAVAILABLE;
147 KeyStore_PSA_KeyAttributes keyAttributes = KEYSTORE_PSA_KEY_ATTRIBUTES_INIT;
148 KeyStore_PSA_KeyFileId keyID;
149
150 if ((msg->in_size[0] != sizeof(getKeyAttributesMsg)) || (msg->out_size[0] != sizeof(ret)))
151 {
152 return PSA_ERROR_PROGRAMMER_ERROR;
153 }
154
155 psa_read(msg->handle, 0, &getKeyAttributesMsg, sizeof(getKeyAttributesMsg));
156
157 if (TFM_CLIENT_ID_IS_NS(msg->client_id))
158 {
159 if (cmse_has_unpriv_nonsecure_rw_access(getKeyAttributesMsg.attributes,
160 sizeof(struct psa_client_key_attributes_s)) == NULL)
161 {
162 return PSA_ERROR_PROGRAMMER_ERROR;
163 }
164 }
165
166 KeyStore_s_copyKeyIDFromClient(&keyID, msg->client_id, &getKeyAttributesMsg.key);
167
168 ret = KeyStore_PSA_getKeyAttributes(keyID, &keyAttributes);
169
170 if (ret == KEYSTORE_PSA_STATUS_SUCCESS)
171 {
172 ret = KeyStore_s_copyKeyAttributesToClient(&keyAttributes,
173 (struct psa_client_key_attributes_s *)
174 getKeyAttributesMsg.attributes);
175 }
176
177 psa_write(msg->handle, 0, &ret, sizeof(ret));
178
179 return PSA_SUCCESS;
180 }
181
182 /*
183 * ======== KeyStore_s_importKey ========
184 */
KeyStore_s_importKey(psa_msg_t * msg)185 psa_status_t KeyStore_s_importKey(psa_msg_t *msg)
186 {
187 KeyStore_s_ImportKeyMsg importKeyMsg;
188 int_fast16_t ret = KEYSTORE_PSA_STATUS_RESOURCE_UNAVAILABLE;
189 KeyStore_PSA_KeyAttributes keyAttributes = KEYSTORE_PSA_KEY_ATTRIBUTES_INIT;
190 KeyStore_PSA_KeyFileId keyID;
191
192 if ((msg->in_size[0] != sizeof(importKeyMsg)) || (msg->out_size[0] != sizeof(ret)))
193 {
194 return PSA_ERROR_PROGRAMMER_ERROR;
195 }
196
197 psa_read(msg->handle, 0, &importKeyMsg, sizeof(importKeyMsg));
198
199 if (TFM_CLIENT_ID_IS_NS(msg->client_id))
200 {
201 /* Validate input address range */
202 if ((cmse_has_unpriv_nonsecure_rw_access(importKeyMsg.key, sizeof(KeyStore_PSA_KeyFileId)) == NULL) ||
203 (cmse_has_unpriv_nonsecure_read_access(importKeyMsg.attributes, sizeof(KeyStore_PSA_KeyAttributes)) ==
204 NULL) ||
205 (cmse_has_unpriv_nonsecure_read_access(importKeyMsg.data, importKeyMsg.dataLength) == NULL))
206 {
207 return PSA_ERROR_PROGRAMMER_ERROR;
208 }
209 }
210
211 /* Copy keyID from application for persistent keys */
212 if (importKeyMsg.attributes->lifetime)
213 {
214 KeyStore_s_copyKeyIDFromClient(&keyID, msg->client_id, importKeyMsg.key);
215 }
216
217 ret = KeyStore_s_copyKeyAttributesFromClient((struct psa_client_key_attributes_s *)importKeyMsg.attributes,
218 msg->client_id,
219 &keyAttributes);
220
221 if (ret == PSA_SUCCESS)
222 {
223 ret = KeyStore_PSA_importKey(&keyAttributes, importKeyMsg.data, importKeyMsg.dataLength, &keyID);
224
225 KeyStore_s_copyKeyIDtoClient(&keyID, importKeyMsg.key);
226 }
227
228 psa_write(msg->handle, 0, &ret, sizeof(ret));
229
230 return PSA_SUCCESS;
231 }
232
233 /*
234 * ======== KeyStore_s_destroyPurgeKey ========
235 */
KeyStore_s_destroyPurgeKey(psa_msg_t * msg,int32_t msgType)236 psa_status_t KeyStore_s_destroyPurgeKey(psa_msg_t *msg, int32_t msgType)
237 {
238 KeyStore_s_DestroyPurgeKeyMsg destroyMsg;
239 int_fast16_t ret = PSA_ERROR_PROGRAMMER_ERROR;
240 KeyStore_PSA_KeyFileId keyID;
241
242 if ((msg->in_size[0] != sizeof(destroyMsg)) || (msg->out_size[0] != sizeof(ret)))
243 {
244 return PSA_ERROR_PROGRAMMER_ERROR;
245 }
246
247 psa_read(msg->handle, 0, &destroyMsg, sizeof(destroyMsg));
248
249 KeyStore_s_copyKeyIDFromClient(&keyID, msg->client_id, &destroyMsg.key);
250
251 if (msgType == KEYSTORE_PSA_S_MSG_TYPE_DESTROY_KEY)
252 {
253 ret = KeyStore_PSA_destroyKey(keyID);
254 }
255 else if (msgType == KEYSTORE_PSA_S_MSG_TYPE_PURGE_KEY)
256 {
257 ret = KeyStore_PSA_purgeKey(keyID);
258 }
259
260 psa_write(msg->handle, 0, &ret, sizeof(ret));
261
262 return PSA_SUCCESS;
263 }
264
265 /*
266 * ======== KeyStore_s_exportKey ========
267 */
KeyStore_s_exportKey(psa_msg_t * msg,int32_t msgType)268 psa_status_t KeyStore_s_exportKey(psa_msg_t *msg, int32_t msgType)
269 {
270 KeyStore_s_ExportMsg exportMsg;
271 int_fast16_t ret = PSA_ERROR_PROGRAMMER_ERROR;
272 KeyStore_PSA_KeyFileId keyID;
273
274 if ((msg->in_size[0] != sizeof(exportMsg)) || (msg->out_size[0] != sizeof(ret)))
275 {
276 return PSA_ERROR_PROGRAMMER_ERROR;
277 }
278
279 psa_read(msg->handle, 0, &exportMsg, sizeof(exportMsg));
280
281 if (TFM_CLIENT_ID_IS_NS(msg->client_id))
282 {
283 /* Validate input address range */
284 if (cmse_has_unpriv_nonsecure_rw_access(exportMsg.data, exportMsg.dataSize) == NULL)
285 {
286 return PSA_ERROR_PROGRAMMER_ERROR;
287 }
288 }
289
290 KeyStore_s_copyKeyIDFromClient(&keyID, msg->client_id, &exportMsg.key);
291
292 if (msgType == KEYSTORE_PSA_S_MSG_TYPE_EXPORT_KEY)
293 {
294 ret = KeyStore_PSA_exportKey(keyID, exportMsg.data, exportMsg.dataSize, exportMsg.dataLength);
295 }
296 else if (msgType == KEYSTORE_PSA_S_MSG_TYPE_EXPORT_PUBLIC_KEY)
297 {
298 ret = KeyStore_PSA_exportPublicKey(keyID, exportMsg.data, exportMsg.dataSize, exportMsg.dataLength);
299 }
300
301 psa_write(msg->handle, 0, &ret, sizeof(ret));
302
303 return PSA_SUCCESS;
304 }
305
306 /*
307 * ======== KeyStore_s_resetKeyAttributes ========
308 */
KeyStore_s_resetKeyAttributes(psa_msg_t * msg)309 psa_status_t KeyStore_s_resetKeyAttributes(psa_msg_t *msg)
310 {
311 KeyStore_s_ResetKeyAttributesMsg resetKeyAttributeMsg;
312 KeyStore_PSA_KeyAttributes keyAttributes = KEYSTORE_PSA_KEY_ATTRIBUTES_INIT;
313
314 if ((msg->in_size[0] != sizeof(resetKeyAttributeMsg)))
315 {
316 return PSA_ERROR_PROGRAMMER_ERROR;
317 }
318
319 psa_read(msg->handle, 0, &resetKeyAttributeMsg, sizeof(resetKeyAttributeMsg));
320
321 KeyStore_s_copyKeyAttributesFromClient((struct psa_client_key_attributes_s *)resetKeyAttributeMsg.attributes,
322 msg->client_id,
323 &keyAttributes);
324
325 /*
326 * Following TF-M's implementation of psa_reset_key_attributes(), KeyStore_PSA_resetKeyAttributes() cannot be
327 * directly called from non-secure application. KeyStore S/NS interface makes a PSA call to reset the attributes
328 * using the function in secure partition
329 */
330 KeyStore_PSA_resetKeyAttributes(&keyAttributes);
331
332 KeyStore_s_copyKeyAttributesToClient(&keyAttributes, resetKeyAttributeMsg.attributes);
333
334 return PSA_SUCCESS;
335 }
336
337 /*
338 * ======== KeyStore_s_getKey ========
339 */
KeyStore_s_getKey(psa_msg_t * msg)340 psa_status_t KeyStore_s_getKey(psa_msg_t *msg)
341 {
342 KeyStore_s_GetKeyMsg getKeyMsg;
343 int_fast16_t ret = PSA_ERROR_PROGRAMMER_ERROR;
344 KeyStore_PSA_KeyFileId keyID;
345
346 if ((msg->in_size[0] != sizeof(getKeyMsg)) || (msg->out_size[0] != sizeof(ret)) ||
347 TFM_CLIENT_ID_IS_NS(msg->client_id))
348 {
349 return PSA_ERROR_PROGRAMMER_ERROR;
350 }
351
352 psa_read(msg->handle, 0, &getKeyMsg, sizeof(getKeyMsg));
353
354 KeyStore_s_copyKeyIDFromClient(&keyID, msg->client_id, &getKeyMsg.key);
355
356 ret = KeyStore_PSA_getKey(keyID,
357 getKeyMsg.data,
358 getKeyMsg.dataSize,
359 getKeyMsg.dataLength,
360 getKeyMsg.alg,
361 getKeyMsg.usage);
362
363 psa_write(msg->handle, 0, &ret, sizeof(ret));
364
365 return PSA_SUCCESS;
366 }
367
368 /*
369 * ======== KeyStore_s_handlePsaMsg ========
370 */
KeyStore_s_handlePsaMsg(psa_msg_t * msg)371 psa_status_t KeyStore_s_handlePsaMsg(psa_msg_t *msg)
372 {
373 psa_status_t status = PSA_ERROR_PROGRAMMER_ERROR;
374
375 switch (msg->type)
376 {
377 case KEYSTORE_PSA_S_MSG_TYPE_GET_KEY:
378 status = KeyStore_s_getKey(msg);
379 break;
380 /* Fall through for exporting */
381 case KEYSTORE_PSA_S_MSG_TYPE_EXPORT_PUBLIC_KEY:
382 case KEYSTORE_PSA_S_MSG_TYPE_EXPORT_KEY:
383 status = KeyStore_s_exportKey(msg, msg->type);
384 break;
385 /* Fall through for destroying */
386 case KEYSTORE_PSA_S_MSG_TYPE_DESTROY_KEY:
387 case KEYSTORE_PSA_S_MSG_TYPE_PURGE_KEY:
388 status = KeyStore_s_destroyPurgeKey(msg, msg->type);
389 break;
390 case KEYSTORE_PSA_S_MSG_TYPE_IMPORT_KEY:
391 status = KeyStore_s_importKey(msg);
392 break;
393 case KEYSTORE_PSA_S_MSG_TYPE_GET_KEY_ATTRIBUTES:
394 status = KeyStore_s_getKeyAttributes(msg);
395 break;
396 case KEYSTORE_PSA_S_MSG_TYPE_RESET_KEY_ATTRIBUTES:
397 status = KeyStore_s_resetKeyAttributes(msg);
398 break;
399 default:
400 /* Unkown PSA message type */
401 status = PSA_ERROR_PROGRAMMER_ERROR;
402 break;
403 }
404
405 return status;
406 }
407
408 /*
409 * ======== KeyStore_s_init ========
410 */
KeyStore_s_init(void)411 void KeyStore_s_init(void)
412 {
413 KeyStore_PSA_init();
414 }
415