1 /*
2  * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <string.h>
11 
12 #include "tfm_sp_log.h"
13 
14 #include "config_tfm.h"
15 #include "psa/crypto.h"
16 #include "psa/error.h"
17 #include "crypto_library.h"
18 
19 /**
20  * \brief This include is required to get the underlying platform function
21  *        to allow the builtin keys support in mbed TLS to map slots to key
22  *        IDs.
23  */
24 #include "tfm_plat_crypto_keys.h"
25 
26 /**
27  * \brief These includes are required to get the interface that TF-M crypto
28  *        exposes on its client side, in particular regarding key attributes
29  */
30 #include "psa/crypto_client_struct.h"
31 
32 /**
33  * \brief This Mbed TLS include is needed to initialise the memory allocator
34  *        of the library used for internal allocations
35  */
36 #include "mbedtls/memory_buffer_alloc.h"
37 
38 /**
39  * \brief This Mbed TLS include is needed to set the mbedtls_printf to the
40  *        function required by the TF-M framework in order to be able to
41  *        print to terminal through mbedtls_printf
42  */
43 #include "mbedtls/platform.h"
44 
45 /**
46  * \brief This Mbed TLS include is needed to retrieve version information for
47  *        display
48  */
49 #include "mbedtls/version.h"
50 
51 #ifndef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
52 #error "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER must be selected in Mbed TLS config file"
53 #endif
54 
55 /**
56  * \brief Static buffer containing the string describing the mbed TLS version. mbed TLS
57  *        guarantees that the string will never be greater than 18 bytes
58  */
59 static char mbedtls_version_full[18];
60 
61 /**
62  * \brief Static buffer to be used by Mbed Crypto for memory allocations
63  *
64  */
65 #include "config_engine_buf.h"
66 static uint8_t mbedtls_mem_buf[CRYPTO_ENGINE_BUF_SIZE] = {0};
67 
68 /*!
69  * \defgroup tfm_crypto_library Set of functions implementing the abstractions of the underlying cryptographic
70  *                              library that implements the PSA Crypto APIs to provide the PSA Crypto core
71  *                              functionality to the TF-M Crypto service. Currently it supports only an
72  *                              mbed TLS based abstraction.
73  */
74 /*!@{*/
tfm_crypto_library_key_id_init(int32_t owner,psa_key_id_t key_id)75 tfm_crypto_library_key_id_t tfm_crypto_library_key_id_init(int32_t owner, psa_key_id_t key_id)
76 {
77     return mbedtls_svc_key_id_make(owner, key_id);
78 }
79 
tfm_crypto_library_get_info(void)80 char *tfm_crypto_library_get_info(void)
81 {
82     memcpy(mbedtls_version_full, MBEDTLS_VERSION_STRING_FULL, sizeof(MBEDTLS_VERSION_STRING_FULL));
83     return mbedtls_version_full;
84 }
85 
tfm_crypto_core_library_init(void)86 psa_status_t tfm_crypto_core_library_init(void)
87 {
88     /* Initialise the Mbed Crypto memory allocator to use static memory
89      * allocation from the provided buffer instead of using the heap
90      */
91     mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf,
92                                      CRYPTO_ENGINE_BUF_SIZE);
93 
94     /* mbedtls_printf is used to print messages including error information. */
95 #if (TFM_PARTITION_LOG_LEVEL >= TFM_PARTITION_LOG_LEVEL_ERROR)
96     mbedtls_platform_set_printf(printf);
97 #endif
98 
99     return PSA_SUCCESS;
100 }
101 
tfm_crypto_core_library_key_attributes_from_client(const struct psa_client_key_attributes_s * client_key_attr,int32_t client_id,psa_key_attributes_t * key_attributes)102 psa_status_t tfm_crypto_core_library_key_attributes_from_client(
103                     const struct psa_client_key_attributes_s *client_key_attr,
104                     int32_t client_id,
105                     psa_key_attributes_t *key_attributes)
106 {
107     psa_core_key_attributes_t *core;
108 
109     if (client_key_attr == NULL || key_attributes == NULL) {
110         return PSA_ERROR_PROGRAMMER_ERROR;
111     }
112 
113     *key_attributes = psa_key_attributes_init();
114     core = &(key_attributes->MBEDTLS_PRIVATE(core));
115 
116     /* Copy core key attributes from the client core key attributes */
117     core->MBEDTLS_PRIVATE(type) = client_key_attr->type;
118     core->MBEDTLS_PRIVATE(lifetime) = client_key_attr->lifetime;
119     core->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) =
120                                                      client_key_attr->usage;
121     core->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) =
122                                                      client_key_attr->alg;
123     core->MBEDTLS_PRIVATE(bits) = client_key_attr->bits;
124 
125     /* Use the client key id as the key_id and its partition id as the owner */
126     core->MBEDTLS_PRIVATE(id) = mbedtls_svc_key_id_make(client_id, client_key_attr->id);
127 
128     return PSA_SUCCESS;
129 }
130 
tfm_crypto_core_library_key_attributes_to_client(const psa_key_attributes_t * key_attributes,struct psa_client_key_attributes_s * client_key_attr)131 psa_status_t tfm_crypto_core_library_key_attributes_to_client(
132                         const psa_key_attributes_t *key_attributes,
133                         struct psa_client_key_attributes_s *client_key_attr)
134 {
135     if (client_key_attr == NULL || key_attributes == NULL) {
136         return PSA_ERROR_PROGRAMMER_ERROR;
137     }
138 
139     struct psa_client_key_attributes_s v = PSA_CLIENT_KEY_ATTRIBUTES_INIT;
140     *client_key_attr = v;
141     psa_core_key_attributes_t core = key_attributes->MBEDTLS_PRIVATE(core);
142 
143     /* Copy core key attributes from the client core key attributes */
144     client_key_attr->type = core.MBEDTLS_PRIVATE(type);
145     client_key_attr->lifetime = core.MBEDTLS_PRIVATE(lifetime);
146     client_key_attr->usage = core.MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage);
147     client_key_attr->alg = core.MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg);
148     client_key_attr->bits = core.MBEDTLS_PRIVATE(bits);
149 
150     /* Return the key_id as the client key id, do not return the owner */
151     client_key_attr->id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(core.MBEDTLS_PRIVATE(id));
152 
153     return PSA_SUCCESS;
154 }
155 
156 /**
157  * \brief This function is required by mbed TLS to enable support for
158  *        platform builtin keys in the PSA Crypto core layer implemented
159  *        by mbed TLS. This function is not standardized by the API hence
160  *        this layer directly provides the symbol required by the library
161  *
162  * \note It maps builtin key IDs to cryptographic drivers and slots. The
163  *       actual data is deferred to a platform function, as different
164  *       platforms may have different key storage capabilities.
165  */
mbedtls_psa_platform_get_builtin_key(mbedtls_svc_key_id_t key_id,psa_key_lifetime_t * lifetime,psa_drv_slot_number_t * slot_number)166 psa_status_t mbedtls_psa_platform_get_builtin_key(
167     mbedtls_svc_key_id_t key_id,
168     psa_key_lifetime_t *lifetime,
169     psa_drv_slot_number_t *slot_number)
170 {
171     const tfm_plat_builtin_key_descriptor_t *desc_table = NULL;
172     size_t number_of_keys = tfm_plat_builtin_key_get_desc_table_ptr(&desc_table);
173 
174     for (size_t idx = 0; idx < number_of_keys; idx++) {
175         if (desc_table[idx].key_id == MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key_id)) {
176             *lifetime = desc_table[idx].lifetime;
177             *slot_number = desc_table[idx].slot_number;
178             return PSA_SUCCESS;
179         }
180     }
181 
182     return PSA_ERROR_DOES_NOT_EXIST;
183 }
184 /*!@}*/
185