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 * \addtogroup tfm_crypto_api_shim_layer
22 *
23 */
24
25 /*!@{*/
26 #if CRYPTO_MAC_MODULE_ENABLED
tfm_crypto_mac_interface(psa_invec in_vec[],psa_outvec out_vec[],struct tfm_crypto_key_id_s * encoded_key)27 psa_status_t tfm_crypto_mac_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_mac_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_MAC_COMPUTE_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 *mac = out_vec[0].base;
46 size_t mac_size = out_vec[0].len;
47
48 status = psa_mac_compute(library_key, iov->alg, input, input_length,
49 mac, mac_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_MAC_VERIFY_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 const uint8_t *mac = in_vec[2].base;
64 size_t mac_length = in_vec[2].len;
65
66 return psa_mac_verify(library_key, iov->alg, input, input_length,
67 mac, mac_length);
68 #endif
69 }
70
71 if ((sid == TFM_CRYPTO_MAC_SIGN_SETUP_SID) ||
72 (sid == TFM_CRYPTO_MAC_VERIFY_SETUP_SID)) {
73 p_handle = out_vec[0].base;
74 if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(uint32_t))) {
75 return PSA_ERROR_PROGRAMMER_ERROR;
76 }
77 *p_handle = iov->op_handle;
78 status = tfm_crypto_operation_alloc(TFM_CRYPTO_MAC_OPERATION,
79 out_vec[0].base,
80 (void **)&operation);
81 } else {
82 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
83 iov->op_handle,
84 (void **)&operation);
85 if ((sid == TFM_CRYPTO_MAC_SIGN_FINISH_SID) ||
86 (sid == TFM_CRYPTO_MAC_VERIFY_FINISH_SID) ||
87 (sid == TFM_CRYPTO_MAC_ABORT_SID)) {
88 /*
89 * finish()/abort() interface put handle in out_vec[0].
90 * Therefore, out_vec[0] shall be specially set to original handle
91 * value. Otherwise, the garbage data in message out_vec[0] may
92 * override the original handle value in client, after lookup fails.
93 */
94 p_handle = out_vec[0].base;
95 if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(uint32_t))) {
96 return PSA_ERROR_PROGRAMMER_ERROR;
97 }
98 *p_handle = iov->op_handle;
99 }
100 }
101 if (status != PSA_SUCCESS) {
102 if (sid == TFM_CRYPTO_MAC_ABORT_SID) {
103 /*
104 * Mbed TLS psa_mac_abort() will return a misleading error code
105 * if it is called with invalid operation content, since it
106 * doesn't validate the operation handle.
107 * It is neither necessary to call tfm_crypto_operation_release()
108 * with an invalid handle.
109 * Therefore return PSA_SUCCESS directly as psa_mac_abort() can be
110 * called multiple times.
111 */
112 return PSA_SUCCESS;
113 }
114 return status;
115 }
116
117 switch (sid) {
118 case TFM_CRYPTO_MAC_SIGN_SETUP_SID:
119 {
120 status = psa_mac_sign_setup(operation, library_key, iov->alg);
121 if (status != PSA_SUCCESS) {
122 goto release_operation_and_return;
123 }
124 }
125 break;
126 case TFM_CRYPTO_MAC_VERIFY_SETUP_SID:
127 {
128 status = psa_mac_verify_setup(operation, library_key, iov->alg);
129 if (status != PSA_SUCCESS) {
130 goto release_operation_and_return;
131 }
132 }
133 break;
134 case TFM_CRYPTO_MAC_UPDATE_SID:
135 {
136 const uint8_t *input = in_vec[1].base;
137 size_t input_length = in_vec[1].len;
138
139 return psa_mac_update(operation, input, input_length);
140 }
141 case TFM_CRYPTO_MAC_SIGN_FINISH_SID:
142 {
143 uint8_t *mac = out_vec[1].base;
144 size_t mac_size = out_vec[1].len;
145
146 status = psa_mac_sign_finish(operation, mac, mac_size, &out_vec[1].len);
147 if (status == PSA_SUCCESS) {
148 /* In case of success automatically release the operation */
149 goto release_operation_and_return;
150 } else {
151 out_vec[1].len = 0;
152 }
153 }
154 break;
155 case TFM_CRYPTO_MAC_VERIFY_FINISH_SID:
156 {
157 const uint8_t *mac = in_vec[1].base;
158 size_t mac_length = in_vec[1].len;
159
160 status = psa_mac_verify_finish(operation, mac, mac_length);
161 if (status == PSA_SUCCESS) {
162 goto release_operation_and_return;
163 }
164 }
165 break;
166 case TFM_CRYPTO_MAC_ABORT_SID:
167 {
168 status = psa_mac_abort(operation);
169 goto release_operation_and_return;
170 }
171 default:
172 return PSA_ERROR_NOT_SUPPORTED;
173 }
174
175 return status;
176
177 release_operation_and_return:
178 /* Release the operation context, ignore if the operation fails. */
179 (void)tfm_crypto_operation_release(p_handle);
180 return status;
181 }
182 #else /* CRYPTO_MAC_MODULE_ENABLED */
tfm_crypto_mac_interface(psa_invec in_vec[],psa_outvec out_vec[],struct tfm_crypto_key_id_s * encoded_key)183 psa_status_t tfm_crypto_mac_interface(psa_invec in_vec[],
184 psa_outvec out_vec[],
185 struct tfm_crypto_key_id_s *encoded_key)
186 {
187 (void)in_vec;
188 (void)out_vec;
189 (void)encoded_key;
190
191 return PSA_ERROR_NOT_SUPPORTED;
192 }
193 #endif /* CRYPTO_MAC_MODULE_ENABLED */
194 /*!@}*/
195