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