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