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 #include <string.h>
11 
12 #include "config_tfm.h"
13 #include "tfm_mbedcrypto_include.h"
14 #include "tfm_crypto_api.h"
15 #include "tfm_crypto_key.h"
16 #include "tfm_crypto_defs.h"
17 
18 #include "crypto_library.h"
19 
20 /*!
21  * \addtogroup tfm_crypto_api_shim_layer
22  *
23  */
24 
25 /*!@{*/
26 #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)27 psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
28                                                  psa_outvec out_vec[],
29                                                  struct tfm_crypto_key_id_s *encoded_key)
30 {
31     const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
32     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
33     /* Build a key_id in the library key format, i.e. (owner, key_id) */
34     tfm_crypto_library_key_id_t library_key = tfm_crypto_library_key_id_init(
35                                                   encoded_key->owner, encoded_key->key_id);
36     psa_key_attributes_t srv_key_attr;
37 
38     switch (iov->function_id) {
39     case TFM_CRYPTO_IMPORT_KEY_SID:
40     case TFM_CRYPTO_COPY_KEY_SID:
41     case TFM_CRYPTO_GENERATE_KEY_SID:
42         if ((in_vec[1].base == NULL) ||
43             (in_vec[1].len != (sizeof(srv_key_attr) - TFM_CRYPTO_KEY_ATTR_OFFSET_CLIENT_SERVER))) {
44             return PSA_ERROR_PROGRAMMER_ERROR;
45         }
46         memcpy(&srv_key_attr, in_vec[1].base, in_vec[1].len);
47         tfm_crypto_library_get_library_key_id_set_owner(encoded_key->owner, &srv_key_attr);
48         break;
49     default:
50         break;
51     }
52 
53     switch (iov->function_id) {
54     case TFM_CRYPTO_IMPORT_KEY_SID:
55     {
56         const uint8_t *data = in_vec[2].base;
57         size_t data_length = in_vec[2].len;
58         psa_key_id_t *key_id = out_vec[0].base;
59         if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(psa_key_id_t))) {
60             return PSA_ERROR_PROGRAMMER_ERROR;
61         }
62 
63         status = psa_import_key(&srv_key_attr,
64                                 data, data_length, &library_key);
65         /* Update the imported key id */
66         *key_id = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
67     }
68     break;
69     case TFM_CRYPTO_OPEN_KEY_SID:
70     {
71         psa_key_id_t *key_id = out_vec[0].base;
72         if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(psa_key_id_t))) {
73             return PSA_ERROR_PROGRAMMER_ERROR;
74         }
75 
76         status = psa_open_key(library_key, &library_key);
77         *key_id = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
78     }
79     break;
80     case TFM_CRYPTO_CLOSE_KEY_SID:
81     {
82         status = psa_close_key(library_key);
83     }
84     break;
85     case TFM_CRYPTO_DESTROY_KEY_SID:
86     {
87         status = psa_destroy_key(library_key);
88     }
89     break;
90     case TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID:
91     {
92         psa_key_attributes_t *key_attributes = out_vec[0].base;
93 
94         status = psa_get_key_attributes(library_key, &srv_key_attr);
95 
96         /* Note that we just copy out_vec[0].len, because in this context
97          * sizeof(psa_key_attributes_t) would return the size of the service
98          * view of the attributes, while we are passing back to the caller
99          * only the client view of it, i.e. without the owner field at the
100          * end of the structure
101          */
102         if ((out_vec[0].base == NULL) || (out_vec[0].len > sizeof(psa_key_attributes_t))) {
103             return PSA_ERROR_PROGRAMMER_ERROR;
104         }
105         memcpy(key_attributes, &srv_key_attr, out_vec[0].len);
106     }
107     break;
108     case TFM_CRYPTO_EXPORT_KEY_SID:
109     {
110         uint8_t *data = out_vec[0].base;
111         size_t data_size = out_vec[0].len;
112 
113         status = psa_export_key(library_key, data, data_size,
114                                 &(out_vec[0].len));
115         if (status != PSA_SUCCESS) {
116             out_vec[0].len = 0;
117         }
118     }
119     break;
120     case TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID:
121     {
122         uint8_t *data = out_vec[0].base;
123         size_t data_size = out_vec[0].len;
124 
125         status = psa_export_public_key(library_key, data, data_size,
126                                        &(out_vec[0].len));
127         if (status != PSA_SUCCESS) {
128             out_vec[0].len = 0;
129         }
130     }
131     break;
132     case TFM_CRYPTO_PURGE_KEY_SID:
133     {
134         status = psa_purge_key(library_key);
135     }
136     break;
137     case TFM_CRYPTO_COPY_KEY_SID:
138     {
139         psa_key_id_t *target_key_id = out_vec[0].base;
140         tfm_crypto_library_key_id_t target_key = tfm_crypto_library_key_id_init_default();
141         if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(psa_key_id_t))) {
142             return PSA_ERROR_PROGRAMMER_ERROR;
143         }
144 
145         status = psa_copy_key(library_key,
146                               &srv_key_attr,
147                               &target_key);
148         if (status != PSA_SUCCESS) {
149             return status;
150         }
151 
152         *target_key_id = CRYPTO_LIBRARY_GET_KEY_ID(target_key);
153     }
154     break;
155     case TFM_CRYPTO_GENERATE_KEY_SID:
156     {
157         psa_key_id_t *key_handle = out_vec[0].base;
158         if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(psa_key_id_t))) {
159             return PSA_ERROR_PROGRAMMER_ERROR;
160         }
161 
162         status = psa_generate_key(&srv_key_attr, &library_key);
163         if (status != PSA_SUCCESS) {
164             return status;
165         }
166 
167         *key_handle = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
168     }
169     break;
170     default:
171         return PSA_ERROR_NOT_SUPPORTED;
172     }
173 
174     return status;
175 }
176 #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)177 psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
178                                                  psa_outvec out_vec[],
179                                                  struct tfm_crypto_key_id_s *encoded_key)
180 {
181     (void)in_vec;
182     (void)out_vec;
183     (void)encoded_key;
184 
185     return PSA_ERROR_NOT_SUPPORTED;
186 }
187 #endif /* CRYPTO_KEY_MODULE_ENABLED  */
188 /*!@}*/
189