1 /*
2 * Copyright (c) 2019-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
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 * \defgroup tfm_crypto_api_shim_layer Set of functions implementing a thin shim
22 * layer between the TF-M Crypto service
23 * frontend and the underlying library which
24 * implements the PSA Crypto APIs
25 * (i.e. mbed TLS)
26 */
27
28 /*!@{*/
29 #if CRYPTO_AEAD_MODULE_ENABLED
tfm_crypto_aead_interface(psa_invec in_vec[],psa_outvec out_vec[],struct tfm_crypto_key_id_s * encoded_key)30 psa_status_t tfm_crypto_aead_interface(psa_invec in_vec[],
31 psa_outvec out_vec[],
32 struct tfm_crypto_key_id_s *encoded_key)
33 {
34 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
35 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
36 psa_aead_operation_t *operation = NULL;
37 uint32_t *p_handle = NULL;
38 enum tfm_crypto_func_sid_t sid = (enum tfm_crypto_func_sid_t)iov->function_id;
39
40 tfm_crypto_library_key_id_t library_key = tfm_crypto_library_key_id_init(
41 encoded_key->owner, encoded_key->key_id);
42 if (sid == TFM_CRYPTO_AEAD_ENCRYPT_SID) {
43 #if CRYPTO_SINGLE_PART_FUNCS_DISABLED
44 return PSA_ERROR_NOT_SUPPORTED;
45 #else
46 const struct tfm_crypto_aead_pack_input *aead_pack_input =
47 &iov->aead_in;
48 const uint8_t *nonce = aead_pack_input->nonce;
49 size_t nonce_length = aead_pack_input->nonce_length;
50 const uint8_t *plaintext = in_vec[1].base;
51 size_t plaintext_length = in_vec[1].len;
52 uint8_t *ciphertext = out_vec[0].base;
53 size_t ciphertext_size = out_vec[0].len;
54 const uint8_t *additional_data = in_vec[2].base;
55 size_t additional_data_length = in_vec[2].len;
56
57 status = psa_aead_encrypt(library_key, iov->alg, nonce, nonce_length,
58 additional_data, additional_data_length,
59 plaintext, plaintext_length,
60 ciphertext, ciphertext_size, &out_vec[0].len);
61 if (status != PSA_SUCCESS) {
62 out_vec[0].len = 0;
63 }
64 return status;
65 #endif
66 }
67
68 if (sid == TFM_CRYPTO_AEAD_DECRYPT_SID) {
69 #if CRYPTO_SINGLE_PART_FUNCS_DISABLED
70 return PSA_ERROR_NOT_SUPPORTED;
71 #else
72 const struct tfm_crypto_aead_pack_input *aead_pack_input =
73 &iov->aead_in;
74 const uint8_t *nonce = aead_pack_input->nonce;
75 size_t nonce_length = aead_pack_input->nonce_length;
76 const uint8_t *ciphertext = in_vec[1].base;
77 size_t ciphertext_length = in_vec[1].len;
78 uint8_t *plaintext = out_vec[0].base;
79 size_t plaintext_size = out_vec[0].len;
80 const uint8_t *additional_data = in_vec[2].base;
81 size_t additional_data_length = in_vec[2].len;
82
83 status = psa_aead_decrypt(library_key, iov->alg, nonce, nonce_length,
84 additional_data, additional_data_length,
85 ciphertext, ciphertext_length,
86 plaintext, plaintext_size, &out_vec[0].len);
87 if (status != PSA_SUCCESS) {
88 out_vec[0].len = 0;
89 }
90 return status;
91 #endif
92 }
93
94 if ((sid == TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID) ||
95 (sid == TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID)) {
96 p_handle = out_vec[0].base;
97 if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(uint32_t))) {
98 return PSA_ERROR_PROGRAMMER_ERROR;
99 }
100 *p_handle = iov->op_handle;
101 status = tfm_crypto_operation_alloc(TFM_CRYPTO_AEAD_OPERATION,
102 out_vec[0].base,
103 (void **)&operation);
104 } else {
105 status = tfm_crypto_operation_lookup(TFM_CRYPTO_AEAD_OPERATION,
106 iov->op_handle,
107 (void **)&operation);
108 if ((sid == TFM_CRYPTO_AEAD_FINISH_SID) ||
109 (sid == TFM_CRYPTO_AEAD_VERIFY_SID) ||
110 (sid == TFM_CRYPTO_AEAD_ABORT_SID)) {
111 /*
112 * finish()/abort() interface put handle pointer in out_vec[0].
113 * Therefore, out_vec[0] shall be specially set to original handle
114 * value. Otherwise, later psa_write() may override the original
115 * handle value in client with garbage data in message out_vec[0],
116 * if lookup fails.
117 */
118 p_handle = out_vec[0].base;
119 if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(uint32_t))) {
120 return PSA_ERROR_PROGRAMMER_ERROR;
121 }
122 *p_handle = iov->op_handle;
123 }
124 }
125 if (status != PSA_SUCCESS) {
126 if (sid == TFM_CRYPTO_AEAD_ABORT_SID) {
127 /*
128 * Mbed TLS psa_aead_abort() will return a misleading error code
129 * if it is called with invalid operation content, since it
130 * doesn't validate the operation handle.
131 * It is neither necessary to call tfm_crypto_operation_release()
132 * with an invalid handle.
133 * Therefore return PSA_SUCCESS directly as psa_aead_abort() can be
134 * called multiple times.
135 */
136 return PSA_SUCCESS;
137 }
138 return status;
139 }
140
141 switch (sid) {
142 case TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID:
143 {
144 status = psa_aead_encrypt_setup(operation, library_key, iov->alg);
145 if (status != PSA_SUCCESS) {
146 goto release_operation_and_return;
147 }
148 }
149 break;
150 case TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID:
151 {
152 status = psa_aead_decrypt_setup(operation, library_key, iov->alg);
153 if (status != PSA_SUCCESS) {
154 goto release_operation_and_return;
155 }
156 }
157 break;
158 case TFM_CRYPTO_AEAD_FINISH_SID:
159 {
160 uint8_t *ciphertext = out_vec[2].base;
161 size_t ciphertext_size = out_vec[2].len;
162 uint8_t *tag = out_vec[1].base;
163 size_t tag_size = out_vec[1].len;
164
165 status = psa_aead_finish(operation,
166 ciphertext, ciphertext_size, &out_vec[2].len,
167 tag, tag_size, &out_vec[1].len);
168 if (status == PSA_SUCCESS) {
169 goto release_operation_and_return;
170 } else {
171 out_vec[1].len = 0;
172 out_vec[2].len = 0;
173 }
174 }
175 break;
176 case TFM_CRYPTO_AEAD_ABORT_SID:
177 {
178 status = psa_aead_abort(operation);
179 goto release_operation_and_return;
180 }
181 case TFM_CRYPTO_AEAD_GENERATE_NONCE_SID:
182 {
183 uint8_t *nonce = out_vec[0].base;
184 size_t nonce_size = out_vec[0].len;
185
186 status = psa_aead_generate_nonce(operation,
187 nonce,
188 nonce_size,
189 &out_vec[0].len);
190 if (status != PSA_SUCCESS) {
191 out_vec[0].len = 0;
192 }
193 return status;
194 }
195 case TFM_CRYPTO_AEAD_SET_NONCE_SID:
196 {
197 const uint8_t *nonce = in_vec[1].base;
198 size_t nonce_size = in_vec[1].len;
199
200 return psa_aead_set_nonce(operation, nonce, nonce_size);
201 }
202 case TFM_CRYPTO_AEAD_SET_LENGTHS_SID:
203 {
204 return psa_aead_set_lengths(operation, iov->ad_length,
205 iov->plaintext_length);
206 }
207 case TFM_CRYPTO_AEAD_UPDATE_SID:
208 {
209 const uint8_t *input = in_vec[1].base;
210 size_t input_length = in_vec[1].len;
211 uint8_t *output = out_vec[0].base;
212 size_t output_size = out_vec[0].len;
213
214 status = psa_aead_update(operation, input, input_length,
215 output, output_size, &out_vec[0].len);
216 if (status != PSA_SUCCESS) {
217 out_vec[0].len = 0;
218 }
219 return status;
220 }
221 case TFM_CRYPTO_AEAD_UPDATE_AD_SID:
222 {
223 const uint8_t *input = in_vec[1].base;
224 size_t input_length = in_vec[1].len;
225
226 return psa_aead_update_ad(operation, input, input_length);
227 }
228 case TFM_CRYPTO_AEAD_VERIFY_SID:
229 {
230 const uint8_t *tag = in_vec[1].base;
231 size_t tag_length = in_vec[1].len;
232 uint8_t *plaintext = out_vec[1].base;
233 size_t plaintext_size = out_vec[1].len;
234
235 status = psa_aead_verify(operation,
236 plaintext, plaintext_size, &out_vec[1].len,
237 tag, tag_length);
238 if (status == PSA_SUCCESS) {
239 goto release_operation_and_return;
240 } else {
241 out_vec[1].len = 0;
242 }
243 }
244 break;
245 default:
246 return PSA_ERROR_NOT_SUPPORTED;
247 }
248
249 return status;
250
251 release_operation_and_return:
252 /* Release the operation context, ignore if the operation fails. */
253 (void)tfm_crypto_operation_release(p_handle);
254 return status;
255 }
256 #else /* CRYPTO_AEAD_MODULE_ENABLED */
tfm_crypto_aead_interface(psa_invec in_vec[],psa_outvec out_vec[],struct tfm_crypto_key_id_s * encoded_key)257 psa_status_t tfm_crypto_aead_interface(psa_invec in_vec[],
258 psa_outvec out_vec[],
259 struct tfm_crypto_key_id_s *encoded_key)
260 {
261 (void)in_vec;
262 (void)out_vec;
263 (void)encoded_key;
264
265 return PSA_ERROR_NOT_SUPPORTED;
266 }
267 #endif /* CRYPTO_AEAD_MODULE_ENABLED */
268 /*!@}*/
269