1 /*
2  * Copyright (c) 2021-2022, 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 
11 #include "config_tfm.h"
12 #include "tfm_mbedcrypto_include.h"
13 #include "tfm_crypto_api.h"
14 #include "tfm_crypto_key.h"
15 #include "tfm_crypto_defs.h"
16 
17 #include "crypto_library.h"
18 
19 /*!
20  * \addtogroup tfm_crypto_api_shim_layer
21  *
22  */
23 
24 /*!@{*/
25 #if CRYPTO_KEY_MODULE_ENABLED
tfm_crypto_key_management_interface(psa_invec in_vec[],psa_outvec out_vec[],struct tfm_crypto_key_id_s * encoded_key)26 psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
27                                                  psa_outvec out_vec[],
28                                                  struct tfm_crypto_key_id_s *encoded_key)
29 {
30     const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
31     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
32     int32_t partition_id = encoded_key->owner;
33 
34     tfm_crypto_library_key_id_t library_key = tfm_crypto_library_key_id_init(
35                                                   encoded_key->owner, encoded_key->key_id);
36     switch (iov->function_id) {
37     case TFM_CRYPTO_IMPORT_KEY_SID:
38     {
39         const struct psa_client_key_attributes_s *client_key_attr =
40                                                                  in_vec[1].base;
41         const uint8_t *data = in_vec[2].base;
42         size_t data_length = in_vec[2].len;
43         psa_key_id_t *key_id = out_vec[0].base;
44         psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
45 
46         status = tfm_crypto_core_library_key_attributes_from_client(
47                                                        client_key_attr,
48                                                        partition_id,
49                                                        &key_attributes);
50         if (status != PSA_SUCCESS) {
51             return status;
52         }
53 
54         status = psa_import_key(&key_attributes,
55                                 data, data_length, &library_key);
56         /* Update the imported key id */
57         *key_id = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
58     }
59     break;
60     case TFM_CRYPTO_OPEN_KEY_SID:
61     {
62         psa_key_id_t *key_id = out_vec[0].base;
63 
64         status = psa_open_key(library_key, &library_key);
65         *key_id = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
66     }
67     break;
68     case TFM_CRYPTO_CLOSE_KEY_SID:
69     {
70         status = psa_close_key(library_key);
71     }
72     break;
73     case TFM_CRYPTO_DESTROY_KEY_SID:
74     {
75         status = psa_destroy_key(library_key);
76     }
77     break;
78     case TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID:
79     {
80         psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
81         struct psa_client_key_attributes_s *client_key_attr = out_vec[0].base;
82 
83         status = psa_get_key_attributes(library_key, &key_attributes);
84         if (status == PSA_SUCCESS) {
85             status = tfm_crypto_core_library_key_attributes_to_client(&key_attributes,
86                                                                       client_key_attr);
87         }
88     }
89     break;
90     case TFM_CRYPTO_RESET_KEY_ATTRIBUTES_SID:
91     {
92         psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
93         struct psa_client_key_attributes_s *client_key_attr = out_vec[0].base;
94 
95         status = tfm_crypto_core_library_key_attributes_from_client(
96                                                        client_key_attr,
97                                                        partition_id,
98                                                        &key_attributes);
99         if (status != PSA_SUCCESS) {
100             return status;
101         }
102 
103         psa_reset_key_attributes(&key_attributes);
104 
105         status = tfm_crypto_core_library_key_attributes_to_client(&key_attributes,
106                                                                   client_key_attr);
107     }
108     break;
109     case TFM_CRYPTO_EXPORT_KEY_SID:
110     {
111         uint8_t *data = out_vec[0].base;
112         size_t data_size = out_vec[0].len;
113 
114         status = psa_export_key(library_key, data, data_size,
115                                 &(out_vec[0].len));
116         if (status != PSA_SUCCESS) {
117             out_vec[0].len = 0;
118         }
119     }
120     break;
121     case TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID:
122     {
123         uint8_t *data = out_vec[0].base;
124         size_t data_size = out_vec[0].len;
125 
126         status = psa_export_public_key(library_key, data, data_size,
127                                        &(out_vec[0].len));
128         if (status != PSA_SUCCESS) {
129             out_vec[0].len = 0;
130         }
131     }
132     break;
133     case TFM_CRYPTO_PURGE_KEY_SID:
134     {
135         status = psa_purge_key(library_key);
136     }
137     break;
138     case TFM_CRYPTO_COPY_KEY_SID:
139     {
140         psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
141         const struct psa_client_key_attributes_s *client_key_attr =
142                                                                  in_vec[1].base;
143         psa_key_id_t *target_key_id = out_vec[0].base;
144         tfm_crypto_library_key_id_t target_key = tfm_crypto_library_key_id_init_default();
145 
146         status = tfm_crypto_core_library_key_attributes_from_client(
147                                                        client_key_attr,
148                                                        partition_id,
149                                                        &key_attributes);
150         if (status != PSA_SUCCESS) {
151             return status;
152         }
153 
154         status = psa_copy_key(library_key,
155                               &key_attributes,
156                               &target_key);
157         if (status != PSA_SUCCESS) {
158             return status;
159         }
160 
161         *target_key_id = CRYPTO_LIBRARY_GET_KEY_ID(target_key);
162     }
163     break;
164     case TFM_CRYPTO_GENERATE_KEY_SID:
165     {
166         psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
167         const struct psa_client_key_attributes_s *client_key_attr =
168                                                                  in_vec[1].base;
169         psa_key_id_t *key_handle = out_vec[0].base;
170 
171         status = tfm_crypto_core_library_key_attributes_from_client(
172                                                        client_key_attr,
173                                                        partition_id,
174                                                        &key_attributes);
175         if (status != PSA_SUCCESS) {
176             return status;
177         }
178 
179         status = psa_generate_key(&key_attributes, &library_key);
180         if (status != PSA_SUCCESS) {
181             return status;
182         }
183 
184         *key_handle = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
185     }
186     break;
187     default:
188         return PSA_ERROR_NOT_SUPPORTED;
189     }
190 
191     return status;
192 }
193 #else /* CRYPTO_KEY_MODULE_ENABLED  */
tfm_crypto_key_management_interface(psa_invec in_vec[],psa_outvec out_vec[],struct tfm_crypto_key_id_s * encoded_key)194 psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
195                                                  psa_outvec out_vec[],
196                                                  struct tfm_crypto_key_id_s *encoded_key)
197 {
198     (void)in_vec;
199     (void)out_vec;
200     (void)encoded_key;
201 
202     return PSA_ERROR_NOT_SUPPORTED;
203 }
204 #endif /* CRYPTO_KEY_MODULE_ENABLED  */
205 /*!@}*/
206