1 /*
2 * Copyright (c) 2018-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 * \addtogroup tfm_crypto_api_shim_layer
22 *
23 */
24
25 /*!@{*/
26 #if CRYPTO_CIPHER_MODULE_ENABLED
tfm_crypto_cipher_interface(psa_invec in_vec[],psa_outvec out_vec[],struct tfm_crypto_key_id_s * encoded_key)27 psa_status_t tfm_crypto_cipher_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_NOT_SUPPORTED;
33 psa_cipher_operation_t *operation = NULL;
34 uint32_t *p_handle = NULL;
35 enum tfm_crypto_func_sid_t sid = iov->function_id;
36
37 tfm_crypto_library_key_id_t library_key = tfm_crypto_library_key_id_init(
38 encoded_key->owner, encoded_key->key_id);
39 if (sid == TFM_CRYPTO_CIPHER_ENCRYPT_SID) {
40 #if CRYPTO_SINGLE_PART_FUNCS_DISABLED
41 return PSA_ERROR_NOT_SUPPORTED;
42 #else
43 const uint8_t *input = in_vec[1].base;
44 size_t input_length = in_vec[1].len;
45 uint8_t *output = out_vec[0].base;
46 size_t output_size = out_vec[0].len;
47
48 status = psa_cipher_encrypt(library_key, iov->alg, input, input_length,
49 output, output_size, &out_vec[0].len);
50 if (status != PSA_SUCCESS) {
51 out_vec[0].len = 0;
52 }
53 return status;
54 #endif
55 }
56
57 if (sid == TFM_CRYPTO_CIPHER_DECRYPT_SID) {
58 #if CRYPTO_SINGLE_PART_FUNCS_DISABLED
59 return PSA_ERROR_NOT_SUPPORTED;
60 #else
61 const uint8_t *input = in_vec[1].base;
62 size_t input_length = in_vec[1].len;
63 uint8_t *output = out_vec[0].base;
64 size_t output_size = out_vec[0].len;
65
66 status = psa_cipher_decrypt(library_key, iov->alg, input, input_length,
67 output, output_size, &out_vec[0].len);
68 if (status != PSA_SUCCESS) {
69 out_vec[0].len = 0;
70 }
71 return status;
72 #endif
73 }
74
75 if ((sid == TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID) ||
76 (sid == TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID)) {
77 p_handle = out_vec[0].base;
78 if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(uint32_t))) {
79 return PSA_ERROR_PROGRAMMER_ERROR;
80 }
81 *p_handle = iov->op_handle;
82 status = tfm_crypto_operation_alloc(TFM_CRYPTO_CIPHER_OPERATION,
83 out_vec[0].base,
84 (void **)&operation);
85 } else {
86 status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
87 iov->op_handle,
88 (void **)&operation);
89 if ((sid == TFM_CRYPTO_CIPHER_FINISH_SID) ||
90 (sid == TFM_CRYPTO_CIPHER_ABORT_SID)) {
91 /*
92 * finish()/abort() interface put handle in out_vec[0].
93 * Therefore, out_vec[0] shall be specially set to original handle
94 * value. Otherwise, the garbage data in message out_vec[0] may
95 * override the original handle value in client, after lookup fails.
96 */
97 p_handle = out_vec[0].base;
98 if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(uint32_t))) {
99 return PSA_ERROR_PROGRAMMER_ERROR;
100 }
101 *p_handle = iov->op_handle;
102 }
103 }
104 if (status != PSA_SUCCESS) {
105 if (sid == TFM_CRYPTO_CIPHER_ABORT_SID) {
106 /*
107 * Mbed TLS psa_cipher_abort() will return a misleading error code
108 * if it is called with invalid operation content, since it
109 * doesn't validate the operation handle.
110 * It is neither necessary to call tfm_crypto_operation_release()
111 * with an invalid handle.
112 * Therefore return PSA_SUCCESS directly as psa_cipher_abort() can
113 * be called multiple times.
114 */
115 return PSA_SUCCESS;
116 }
117 return status;
118 }
119
120 switch (sid) {
121 case TFM_CRYPTO_CIPHER_GENERATE_IV_SID:
122 {
123 unsigned char *iv = out_vec[0].base;
124 size_t iv_size = out_vec[0].len;
125
126 status = psa_cipher_generate_iv(operation, iv, iv_size, &out_vec[0].len);
127 if (status != PSA_SUCCESS) {
128 out_vec[0].len = 0;
129 }
130 return status;
131 }
132 case TFM_CRYPTO_CIPHER_SET_IV_SID:
133 {
134 const unsigned char *iv = in_vec[1].base;
135 size_t iv_length = in_vec[1].len;
136
137 return psa_cipher_set_iv(operation, iv, iv_length);
138 }
139 case TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID:
140 {
141 status = psa_cipher_encrypt_setup(operation, library_key, iov->alg);
142 if (status != PSA_SUCCESS) {
143 goto release_operation_and_return;
144 }
145 }
146 break;
147 case TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID:
148 {
149 status = psa_cipher_decrypt_setup(operation, library_key, iov->alg);
150 if (status != PSA_SUCCESS) {
151 goto release_operation_and_return;
152 }
153 }
154 break;
155 case TFM_CRYPTO_CIPHER_UPDATE_SID:
156 {
157 const uint8_t *input = in_vec[1].base;
158 size_t input_length = in_vec[1].len;
159 unsigned char *output = out_vec[0].base;
160 size_t output_size = out_vec[0].len;
161
162 status = psa_cipher_update(operation, input, input_length,
163 output, output_size, &out_vec[0].len);
164 if (status != PSA_SUCCESS) {
165 out_vec[0].len = 0;
166 }
167 return status;
168 }
169 case TFM_CRYPTO_CIPHER_FINISH_SID:
170 {
171 uint8_t *output = out_vec[1].base;
172 size_t output_size = out_vec[1].len;
173
174 status = psa_cipher_finish(operation,
175 output, output_size, &out_vec[1].len);
176 if (status == PSA_SUCCESS) {
177 /* In case of success automatically release the operation */
178 goto release_operation_and_return;
179 } else {
180 out_vec[1].len = 0;
181 }
182 }
183 break;
184 case TFM_CRYPTO_CIPHER_ABORT_SID:
185 {
186 status = psa_cipher_abort(operation);
187 goto release_operation_and_return;
188 }
189 default:
190 return PSA_ERROR_NOT_SUPPORTED;
191 }
192
193 return status;
194
195 release_operation_and_return:
196 /* Release the operation context, ignore if the operation fails. */
197 (void)tfm_crypto_operation_release(p_handle);
198 return status;
199 }
200 #else /* CRYPTO_CIPHER_MODULE_ENABLED */
tfm_crypto_cipher_interface(psa_invec in_vec[],psa_outvec out_vec[],struct tfm_crypto_key_id_s * encoded_key)201 psa_status_t tfm_crypto_cipher_interface(psa_invec in_vec[],
202 psa_outvec out_vec[],
203 struct tfm_crypto_key_id_s *encoded_key)
204 {
205 (void)in_vec;
206 (void)out_vec;
207 (void)encoded_key;
208
209 return PSA_ERROR_NOT_SUPPORTED;
210 }
211 #endif /* CRYPTO_CIPHER_MODULE_ENABLED */
212 /*!@}*/
213