blob: a11a6d08b3bc5cbfca182136d8b23f97b949f4b7 [file] [log] [blame]
Julian Halld4071382021-07-07 16:45:53 +01001/*
2 * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <string.h>
8#include <stdlib.h>
9#include <psa/crypto.h>
10#include "psa_crypto_client.h"
11#include <protocols/rpc/common/packed-c/status.h>
12#include <protocols/service/crypto/packed-c/opcodes.h>
Julian Halla6d3cbc2021-07-20 10:13:21 +010013#include <protocols/service/crypto/packed-c/mac.h>
Julian Halld4071382021-07-07 16:45:53 +010014#include <common/tlv/tlv.h>
15
Julian Halla6d3cbc2021-07-20 10:13:21 +010016static psa_status_t common_mac_setup(psa_mac_operation_t *operation,
17 psa_key_id_t key,
18 psa_algorithm_t alg,
19 uint32_t opcode)
20{
21 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
22 struct ts_crypto_mac_setup_in req_msg;
23 size_t req_len = sizeof(struct ts_crypto_mac_setup_in);
24
25 req_msg.key_id = key;
26 req_msg.alg = alg;
27
28 rpc_call_handle call_handle;
29 uint8_t *req_buf;
30
Julian Hall99a57e32021-07-28 14:18:50 +010031 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halla6d3cbc2021-07-20 10:13:21 +010032
33 if (call_handle) {
34
35 uint8_t *resp_buf;
36 size_t resp_len;
37 int opstatus;
38
39 memcpy(req_buf, &req_msg, req_len);
40
Julian Hall99a57e32021-07-28 14:18:50 +010041 psa_crypto_client_instance.base.rpc_status =
42 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halla6d3cbc2021-07-20 10:13:21 +010043 opcode, &opstatus, &resp_buf, &resp_len);
44
Julian Hall99a57e32021-07-28 14:18:50 +010045 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Halla6d3cbc2021-07-20 10:13:21 +010046
47 psa_status = opstatus;
48
49 if (psa_status == PSA_SUCCESS) {
50
51 if (resp_len >= sizeof(struct ts_crypto_mac_setup_out)) {
52
53 struct ts_crypto_mac_setup_out resp_msg;
54 memcpy(&resp_msg, resp_buf, sizeof(struct ts_crypto_mac_setup_out));
55 operation->handle = resp_msg.op_handle;
56 }
57 else {
58 /* Failed to decode response message */
59 psa_status = PSA_ERROR_GENERIC_ERROR;
60 }
61 }
62 }
63
Julian Hall99a57e32021-07-28 14:18:50 +010064 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halla6d3cbc2021-07-20 10:13:21 +010065 }
66
67 return psa_status;
68}
69
Julian Halld4071382021-07-07 16:45:53 +010070psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
71 psa_key_id_t key,
72 psa_algorithm_t alg)
73{
Julian Halla6d3cbc2021-07-20 10:13:21 +010074 return common_mac_setup(operation, key, alg, TS_CRYPTO_OPCODE_MAC_SIGN_SETUP);
Julian Halld4071382021-07-07 16:45:53 +010075}
76
77psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
78 psa_key_id_t key,
79 psa_algorithm_t alg)
80{
Julian Halla6d3cbc2021-07-20 10:13:21 +010081 return common_mac_setup(operation, key, alg, TS_CRYPTO_OPCODE_MAC_VERIFY_SETUP);
Julian Halld4071382021-07-07 16:45:53 +010082}
83
84psa_status_t psa_mac_update(psa_mac_operation_t *operation,
85 const uint8_t *input,
86 size_t input_length)
87{
Julian Halla6d3cbc2021-07-20 10:13:21 +010088 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
89 struct ts_crypto_mac_update_in req_msg;
90 size_t req_fixed_len = sizeof(struct ts_crypto_mac_update_in);
91 size_t req_len = req_fixed_len;
92
93 req_msg.op_handle = operation->handle;
94
95 /* Mandatory input data parameter */
96 struct tlv_record data_record;
97 data_record.tag = TS_CRYPTO_MAC_UPDATE_IN_TAG_DATA;
98 data_record.length = input_length;
99 data_record.value = input;
100 req_len += tlv_required_space(data_record.length);
101
102 rpc_call_handle call_handle;
103 uint8_t *req_buf;
104
Julian Hall99a57e32021-07-28 14:18:50 +0100105 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halla6d3cbc2021-07-20 10:13:21 +0100106
107 if (call_handle) {
108
109 uint8_t *resp_buf;
110 size_t resp_len;
111 int opstatus;
112 struct tlv_iterator req_iter;
113
114 memcpy(req_buf, &req_msg, req_fixed_len);
115
116 tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
117 tlv_encode(&req_iter, &data_record);
118
Julian Hall99a57e32021-07-28 14:18:50 +0100119 psa_crypto_client_instance.base.rpc_status =
120 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halla6d3cbc2021-07-20 10:13:21 +0100121 TS_CRYPTO_OPCODE_MAC_UPDATE, &opstatus, &resp_buf, &resp_len);
122
Julian Hall99a57e32021-07-28 14:18:50 +0100123 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
Julian Halla6d3cbc2021-07-20 10:13:21 +0100124
Julian Hall99a57e32021-07-28 14:18:50 +0100125 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halla6d3cbc2021-07-20 10:13:21 +0100126 }
127
128 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100129}
130
131psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
132 uint8_t *mac,
133 size_t mac_size,
134 size_t *mac_length)
135{
Julian Halla6d3cbc2021-07-20 10:13:21 +0100136 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
137 struct ts_crypto_mac_sign_finish_in req_msg;
138 size_t req_fixed_len = sizeof(struct ts_crypto_mac_sign_finish_in);
139 size_t req_len = req_fixed_len;
140
141 *mac_length = 0;
142 req_msg.op_handle = operation->handle;
143
144 rpc_call_handle call_handle;
145 uint8_t *req_buf;
146
Julian Hall99a57e32021-07-28 14:18:50 +0100147 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halla6d3cbc2021-07-20 10:13:21 +0100148
149 if (call_handle) {
150
151 uint8_t *resp_buf;
152 size_t resp_len;
153 int opstatus;
154
155 memcpy(req_buf, &req_msg, req_fixed_len);
156
Julian Hall99a57e32021-07-28 14:18:50 +0100157 psa_crypto_client_instance.base.rpc_status =
158 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halla6d3cbc2021-07-20 10:13:21 +0100159 TS_CRYPTO_OPCODE_MAC_SIGN_FINISH, &opstatus, &resp_buf, &resp_len);
160
Julian Hall99a57e32021-07-28 14:18:50 +0100161 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Halla6d3cbc2021-07-20 10:13:21 +0100162
163 psa_status = opstatus;
164
165 if (psa_status == PSA_SUCCESS) {
166
167 struct tlv_const_iterator resp_iter;
168 struct tlv_record decoded_record;
169 tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
170
171 if (tlv_find_decode(&resp_iter,
172 TS_CRYPTO_MAC_SIGN_FINISH_OUT_TAG_MAC, &decoded_record)) {
173
174 if (decoded_record.length <= mac_size) {
175
176 memcpy(mac, decoded_record.value, decoded_record.length);
177 *mac_length = decoded_record.length;
178 }
179 else {
180 /* Provided buffer is too small */
181 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
182 }
183 }
184 else {
185 /* Mandatory response parameter missing */
186 psa_status = PSA_ERROR_GENERIC_ERROR;
187 }
188 }
189 }
190
Julian Hall99a57e32021-07-28 14:18:50 +0100191 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halla6d3cbc2021-07-20 10:13:21 +0100192 }
193
194 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100195}
196
197psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
198 const uint8_t *mac,
199 size_t mac_length)
200{
Julian Halla6d3cbc2021-07-20 10:13:21 +0100201 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
202 struct ts_crypto_mac_verify_finish_in req_msg;
203 size_t req_fixed_len = sizeof(struct ts_crypto_mac_verify_finish_in);
204 size_t req_len = req_fixed_len;
205
206 req_msg.op_handle = operation->handle;
207
208 /* Mandatory input data parameter */
209 struct tlv_record data_record;
210 data_record.tag = TS_CRYPTO_MAC_VERIFY_FINISH_IN_TAG_MAC;
211 data_record.length = mac_length;
212 data_record.value = mac;
213 req_len += tlv_required_space(data_record.length);
214
215 rpc_call_handle call_handle;
216 uint8_t *req_buf;
217
Julian Hall99a57e32021-07-28 14:18:50 +0100218 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halla6d3cbc2021-07-20 10:13:21 +0100219
220 if (call_handle) {
221
222 uint8_t *resp_buf;
223 size_t resp_len;
224 int opstatus;
225 struct tlv_iterator req_iter;
226
227 memcpy(req_buf, &req_msg, req_fixed_len);
228
229 tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
230 tlv_encode(&req_iter, &data_record);
231
Julian Hall99a57e32021-07-28 14:18:50 +0100232 psa_crypto_client_instance.base.rpc_status =
233 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halla6d3cbc2021-07-20 10:13:21 +0100234 TS_CRYPTO_OPCODE_MAC_VERIFY_FINISH, &opstatus, &resp_buf, &resp_len);
235
Julian Hall99a57e32021-07-28 14:18:50 +0100236 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
Julian Halla6d3cbc2021-07-20 10:13:21 +0100237
Julian Hall99a57e32021-07-28 14:18:50 +0100238 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halla6d3cbc2021-07-20 10:13:21 +0100239 }
240
241 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100242}
243
244psa_status_t psa_mac_abort(psa_mac_operation_t *operation)
245{
Julian Halla6d3cbc2021-07-20 10:13:21 +0100246 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
247 struct ts_crypto_mac_abort_in req_msg;
248 size_t req_fixed_len = sizeof(struct ts_crypto_mac_abort_in);
249 size_t req_len = req_fixed_len;
250
251 req_msg.op_handle = operation->handle;
252
253 rpc_call_handle call_handle;
254 uint8_t *req_buf;
255
Julian Hall99a57e32021-07-28 14:18:50 +0100256 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halla6d3cbc2021-07-20 10:13:21 +0100257
258 if (call_handle) {
259
260 uint8_t *resp_buf;
261 size_t resp_len;
262 int opstatus;
263
264 memcpy(req_buf, &req_msg, req_fixed_len);
265
Julian Hall99a57e32021-07-28 14:18:50 +0100266 psa_crypto_client_instance.base.rpc_status =
267 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halla6d3cbc2021-07-20 10:13:21 +0100268 TS_CRYPTO_OPCODE_MAC_ABORT, &opstatus, &resp_buf, &resp_len);
269
Julian Hall99a57e32021-07-28 14:18:50 +0100270 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
Julian Halla6d3cbc2021-07-20 10:13:21 +0100271
Julian Hall99a57e32021-07-28 14:18:50 +0100272 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halla6d3cbc2021-07-20 10:13:21 +0100273 }
274
275 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100276}
Julian Halld670b412021-07-19 15:16:27 +0100277
Julian Hall188953d2021-07-30 12:11:43 +0100278static size_t max_mac_update_size(void)
279{
280 /* Returns the maximum number of bytes that may be
281 * carried as a parameter of the mac_update operation
282 * using the packed-c encoding.
283 */
284 size_t payload_space = psa_crypto_client_instance.base.service_info.max_payload;
285 size_t overhead = sizeof(struct ts_crypto_mac_update_in) + TLV_HDR_LEN;
286
287 return (payload_space > overhead) ? payload_space - overhead : 0;
288}
289
290static psa_status_t multi_mac_update(psa_mac_operation_t *operation,
291 const uint8_t *input,
292 size_t input_length)
293{
294 psa_status_t psa_status = PSA_SUCCESS;
295 size_t max_update_size = max_mac_update_size();
296 size_t bytes_processed = 0;
297
298 if (!max_update_size) {
299
300 /* Don't know the max update size so assume that the entire
301 * input can be handled in a single update. If this isn't
302 * true, the first mac update operation will fail safely.
303 */
304 max_update_size = input_length;
305 }
306
307 while (bytes_processed < input_length) {
308
309 size_t bytes_remaining = input_length - bytes_processed;
310 size_t update_len = (bytes_remaining < max_update_size) ?
311 bytes_remaining :
312 max_update_size;
313
314 psa_status = psa_mac_update(operation, &input[bytes_processed], update_len);
315
316 if (psa_status != PSA_SUCCESS) {
317
318 psa_mac_abort(operation);
319 break;
320 }
321
322 bytes_processed += update_len;
323 }
324
325 return psa_status;
326}
327
Julian Halld670b412021-07-19 15:16:27 +0100328psa_status_t psa_mac_verify(psa_key_id_t key,
329 psa_algorithm_t alg,
330 const uint8_t *input,
331 size_t input_length,
332 const uint8_t *mac,
333 size_t mac_length)
334{
Julian Hall188953d2021-07-30 12:11:43 +0100335 psa_mac_operation_t operation = psa_mac_operation_init();
336 psa_status_t psa_status = psa_mac_verify_setup(&operation, key, alg);
337
338 if (psa_status == PSA_SUCCESS) {
339
340 psa_status = multi_mac_update(&operation, input, input_length);
341 }
342
343 if (psa_status == PSA_SUCCESS) {
344
345 psa_status = psa_mac_verify_finish(&operation, mac, mac_length);
346 }
347
348 return psa_status;
Julian Halld670b412021-07-19 15:16:27 +0100349}
Julian Hallb7db5802021-07-26 16:20:40 +0100350
351psa_status_t psa_mac_compute(psa_key_id_t key,
352 psa_algorithm_t alg,
353 const uint8_t *input,
354 size_t input_length,
355 uint8_t *mac,
356 size_t mac_size,
357 size_t *mac_length)
358{
Julian Hall188953d2021-07-30 12:11:43 +0100359 psa_mac_operation_t operation = psa_mac_operation_init();
360 psa_status_t psa_status = psa_mac_sign_setup(&operation, key, alg);
361
362 if (psa_status == PSA_SUCCESS) {
363
364 psa_status = multi_mac_update(&operation, input, input_length);
365 }
366
367 if (psa_status == PSA_SUCCESS) {
368
369 psa_status = psa_mac_sign_finish(&operation, mac, mac_size, mac_length);
370 }
371
372 return psa_status;
Julian Hallb7db5802021-07-26 16:20:40 +0100373}