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