blob: 469f3418ee5063039497337525c6e97b5cffbf55 [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>
13#include <protocols/service/crypto/packed-c/hash.h>
14#include <common/tlv/tlv.h>
15
16psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
17 psa_algorithm_t alg)
18{
Julian Hall8359a632021-07-08 15:10:30 +010019 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
20 struct ts_crypto_hash_setup_in req_msg;
21 size_t req_len = sizeof(struct ts_crypto_hash_setup_in);
22
23 req_msg.alg = alg;
24
25 rpc_call_handle call_handle;
26 uint8_t *req_buf;
27
Julian Hall99a57e32021-07-28 14:18:50 +010028 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Hall8359a632021-07-08 15:10:30 +010029
30 if (call_handle) {
31
32 uint8_t *resp_buf;
33 size_t resp_len;
34 int opstatus;
35
36 memcpy(req_buf, &req_msg, req_len);
37
Julian Hall99a57e32021-07-28 14:18:50 +010038 psa_crypto_client_instance.base.rpc_status =
39 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Hall8359a632021-07-08 15:10:30 +010040 TS_CRYPTO_OPCODE_HASH_SETUP, &opstatus, &resp_buf, &resp_len);
41
Julian Hall99a57e32021-07-28 14:18:50 +010042 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hall8359a632021-07-08 15:10:30 +010043
44 psa_status = opstatus;
45
46 if (psa_status == PSA_SUCCESS) {
47
48 if (resp_len >= sizeof(struct ts_crypto_hash_setup_out)) {
49
50 struct ts_crypto_hash_setup_out resp_msg;
51 memcpy(&resp_msg, resp_buf, sizeof(struct ts_crypto_hash_setup_out));
52 operation->handle = resp_msg.op_handle;
53 }
54 else {
55 /* Failed to decode response message */
56 psa_status = PSA_ERROR_GENERIC_ERROR;
57 }
58 }
59 }
60
Julian Hall99a57e32021-07-28 14:18:50 +010061 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Hall8359a632021-07-08 15:10:30 +010062 }
63
64 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +010065}
66
67psa_status_t psa_hash_update(psa_hash_operation_t *operation,
68 const uint8_t *input,
69 size_t input_length)
70{
Julian Hall8359a632021-07-08 15:10:30 +010071 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
72 struct ts_crypto_hash_update_in req_msg;
73 size_t req_fixed_len = sizeof(struct ts_crypto_hash_update_in);
74 size_t req_len = req_fixed_len;
75
76 req_msg.op_handle = operation->handle;
77
78 /* Mandatory input data parameter */
79 struct tlv_record data_record;
80 data_record.tag = TS_CRYPTO_HASH_UPDATE_IN_TAG_DATA;
81 data_record.length = input_length;
82 data_record.value = input;
83 req_len += tlv_required_space(data_record.length);
84
85 rpc_call_handle call_handle;
86 uint8_t *req_buf;
87
Julian Hall99a57e32021-07-28 14:18:50 +010088 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Hall8359a632021-07-08 15:10:30 +010089
90 if (call_handle) {
91
92 uint8_t *resp_buf;
93 size_t resp_len;
94 int opstatus;
95 struct tlv_iterator req_iter;
96
97 memcpy(req_buf, &req_msg, req_fixed_len);
98
99 tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
100 tlv_encode(&req_iter, &data_record);
101
Julian Hall99a57e32021-07-28 14:18:50 +0100102 psa_crypto_client_instance.base.rpc_status =
103 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Hall8359a632021-07-08 15:10:30 +0100104 TS_CRYPTO_OPCODE_HASH_UPDATE, &opstatus, &resp_buf, &resp_len);
105
Julian Hall99a57e32021-07-28 14:18:50 +0100106 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
Julian Hall8359a632021-07-08 15:10:30 +0100107
Julian Hall99a57e32021-07-28 14:18:50 +0100108 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Hall8359a632021-07-08 15:10:30 +0100109 }
110
111 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100112}
113
114psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
115 uint8_t *hash,
116 size_t hash_size,
117 size_t *hash_length)
118{
Julian Hall8359a632021-07-08 15:10:30 +0100119 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
120 struct ts_crypto_hash_finish_in req_msg;
121 size_t req_fixed_len = sizeof(struct ts_crypto_hash_finish_in);
122 size_t req_len = req_fixed_len;
123
124 *hash_length = 0;
125 req_msg.op_handle = operation->handle;
126
127 rpc_call_handle call_handle;
128 uint8_t *req_buf;
129
Julian Hall99a57e32021-07-28 14:18:50 +0100130 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Hall8359a632021-07-08 15:10:30 +0100131
132 if (call_handle) {
133
134 uint8_t *resp_buf;
135 size_t resp_len;
136 int opstatus;
137
138 memcpy(req_buf, &req_msg, req_fixed_len);
139
Julian Hall99a57e32021-07-28 14:18:50 +0100140 psa_crypto_client_instance.base.rpc_status =
141 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Hall8359a632021-07-08 15:10:30 +0100142 TS_CRYPTO_OPCODE_HASH_FINISH, &opstatus, &resp_buf, &resp_len);
143
Julian Hall99a57e32021-07-28 14:18:50 +0100144 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hall8359a632021-07-08 15:10:30 +0100145
146 psa_status = opstatus;
147
148 if (psa_status == PSA_SUCCESS) {
149
150 struct tlv_const_iterator resp_iter;
151 struct tlv_record decoded_record;
152 tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
153
154 if (tlv_find_decode(&resp_iter,
155 TS_CRYPTO_HASH_FINISH_OUT_TAG_HASH, &decoded_record)) {
156
157 if (decoded_record.length <= hash_size) {
158
159 memcpy(hash, decoded_record.value, decoded_record.length);
160 *hash_length = decoded_record.length;
161 }
162 else {
163 /* Provided buffer is too small */
164 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
165 }
166 }
167 else {
168 /* Mandatory response parameter missing */
169 psa_status = PSA_ERROR_GENERIC_ERROR;
170 }
171 }
172 }
173
Julian Hall99a57e32021-07-28 14:18:50 +0100174 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Hall8359a632021-07-08 15:10:30 +0100175 }
176
177 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100178}
179
180psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
181{
Julian Hall0ed3d452021-07-15 14:31:07 +0100182 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
183 struct ts_crypto_hash_abort_in req_msg;
184 size_t req_fixed_len = sizeof(struct ts_crypto_hash_abort_in);
185 size_t req_len = req_fixed_len;
186
187 req_msg.op_handle = operation->handle;
188
189 rpc_call_handle call_handle;
190 uint8_t *req_buf;
191
Julian Hall99a57e32021-07-28 14:18:50 +0100192 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Hall0ed3d452021-07-15 14:31:07 +0100193
194 if (call_handle) {
195
196 uint8_t *resp_buf;
197 size_t resp_len;
198 int opstatus;
199
200 memcpy(req_buf, &req_msg, req_fixed_len);
201
Julian Hall99a57e32021-07-28 14:18:50 +0100202 psa_crypto_client_instance.base.rpc_status =
203 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Hall0ed3d452021-07-15 14:31:07 +0100204 TS_CRYPTO_OPCODE_HASH_ABORT, &opstatus, &resp_buf, &resp_len);
205
Julian Hall99a57e32021-07-28 14:18:50 +0100206 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
Julian Hall0ed3d452021-07-15 14:31:07 +0100207
Julian Hall99a57e32021-07-28 14:18:50 +0100208 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Hall0ed3d452021-07-15 14:31:07 +0100209 }
210
211 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100212}
213
214psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
215 const uint8_t *hash,
216 size_t hash_length)
217{
Julian Hall0ed3d452021-07-15 14:31:07 +0100218 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
219 struct ts_crypto_hash_verify_in req_msg;
220 size_t req_fixed_len = sizeof(struct ts_crypto_hash_verify_in);
221 size_t req_len = req_fixed_len;
222
223 req_msg.op_handle = operation->handle;
224
225 /* Mandatory input data parameter */
226 struct tlv_record data_record;
227 data_record.tag = TS_CRYPTO_HASH_VERIFY_IN_TAG_HASH;
228 data_record.length = hash_length;
229 data_record.value = hash;
230 req_len += tlv_required_space(data_record.length);
231
232 rpc_call_handle call_handle;
233 uint8_t *req_buf;
234
Julian Hall99a57e32021-07-28 14:18:50 +0100235 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Hall0ed3d452021-07-15 14:31:07 +0100236
237 if (call_handle) {
238
239 uint8_t *resp_buf;
240 size_t resp_len;
241 int opstatus;
242 struct tlv_iterator req_iter;
243
244 memcpy(req_buf, &req_msg, req_fixed_len);
245
246 tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
247 tlv_encode(&req_iter, &data_record);
248
Julian Hall99a57e32021-07-28 14:18:50 +0100249 psa_crypto_client_instance.base.rpc_status =
250 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Hall0ed3d452021-07-15 14:31:07 +0100251 TS_CRYPTO_OPCODE_HASH_VERIFY, &opstatus, &resp_buf, &resp_len);
252
Julian Hall99a57e32021-07-28 14:18:50 +0100253 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
Julian Hall0ed3d452021-07-15 14:31:07 +0100254
Julian Hall99a57e32021-07-28 14:18:50 +0100255 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Hall0ed3d452021-07-15 14:31:07 +0100256 }
257
258 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100259}
260
261psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
262 psa_hash_operation_t *target_operation)
263{
Julian Hall0ed3d452021-07-15 14:31:07 +0100264 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
265 struct ts_crypto_hash_clone_in req_msg;
266 size_t req_fixed_len = sizeof(struct ts_crypto_hash_clone_in);
267 size_t req_len = req_fixed_len;
268
269 req_msg.source_op_handle = source_operation->handle;
270
271 rpc_call_handle call_handle;
272 uint8_t *req_buf;
273
Julian Hall99a57e32021-07-28 14:18:50 +0100274 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Hall0ed3d452021-07-15 14:31:07 +0100275
276 if (call_handle) {
277
278 uint8_t *resp_buf;
279 size_t resp_len;
280 int opstatus;
281
282 memcpy(req_buf, &req_msg, req_fixed_len);
283
Julian Hall99a57e32021-07-28 14:18:50 +0100284 psa_crypto_client_instance.base.rpc_status =
285 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Hall0ed3d452021-07-15 14:31:07 +0100286 TS_CRYPTO_OPCODE_HASH_CLONE, &opstatus, &resp_buf, &resp_len);
287
Julian Hall99a57e32021-07-28 14:18:50 +0100288 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hall0ed3d452021-07-15 14:31:07 +0100289
290 psa_status = opstatus;
291
292 if (psa_status == PSA_SUCCESS) {
293
294 if (resp_len >= sizeof(struct ts_crypto_hash_clone_out)) {
295
296 struct ts_crypto_hash_clone_out resp_msg;
297 memcpy(&resp_msg, resp_buf, sizeof(struct ts_crypto_hash_clone_out));
298 target_operation->handle = resp_msg.target_op_handle;
299 }
300 else {
301 /* Failed to decode response message */
302 psa_status = PSA_ERROR_GENERIC_ERROR;
303 }
304 }
305 }
306
Julian Hall99a57e32021-07-28 14:18:50 +0100307 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Hall0ed3d452021-07-15 14:31:07 +0100308 }
309
310 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100311}
312
Julian Hallf284b092021-07-23 12:00:01 +0100313psa_status_t psa_hash_suspend(psa_hash_operation_t *operation,
Julian Hall188953d2021-07-30 12:11:43 +0100314 uint8_t *hash_state,
315 size_t hash_state_size,
316 size_t *hash_state_length)
Julian Hallf284b092021-07-23 12:00:01 +0100317{
318 return PSA_ERROR_NOT_SUPPORTED;
319}
320
321psa_status_t psa_hash_resume(psa_hash_operation_t *operation,
Julian Hall188953d2021-07-30 12:11:43 +0100322 const uint8_t *hash_state,
323 size_t hash_state_length)
Julian Hallf284b092021-07-23 12:00:01 +0100324{
325 return PSA_ERROR_NOT_SUPPORTED;
326}
327
Julian Hall188953d2021-07-30 12:11:43 +0100328static size_t max_hash_update_size(void)
329{
330 /* Returns the maximum number of bytes that may be
331 * carried as a parameter of the hash_update operation
332 * using the packed-c encoding.
333 */
334 size_t payload_space = psa_crypto_client_instance.base.service_info.max_payload;
335 size_t overhead = sizeof(struct ts_crypto_hash_update_in) + TLV_HDR_LEN;
336
337 return (payload_space > overhead) ? payload_space - overhead : 0;
338}
339
340static psa_status_t multi_hash_update(psa_hash_operation_t *operation,
341 psa_algorithm_t alg,
342 const uint8_t *input,
343 size_t input_length)
344{
345 *operation = psa_hash_operation_init();
346 psa_status_t psa_status = psa_hash_setup(operation, alg);
347 size_t max_update_size = max_hash_update_size();
348
349 if (!max_update_size) {
350
351 /* Don't know the max update size so assume that the entire
352 * input can be handled in a single update. If this isn't
353 * true, the first hash update operation will fail safely.
354 */
355 max_update_size = input_length;
356 }
357
358 if (psa_status == PSA_SUCCESS) {
359
360 size_t bytes_processed = 0;
361
362 while (bytes_processed < input_length) {
363
364 size_t bytes_remaining = input_length - bytes_processed;
365 size_t update_len = (bytes_remaining < max_update_size) ?
366 bytes_remaining :
367 max_update_size;
368
369 psa_status = psa_hash_update(operation, &input[bytes_processed], update_len);
370
371 if (psa_status != PSA_SUCCESS) {
372
373 psa_hash_abort(operation);
374 break;
375 }
376
377 bytes_processed += update_len;
378 }
379 }
380
381 return psa_status;
382}
383
Julian Halld4071382021-07-07 16:45:53 +0100384psa_status_t psa_hash_compare(psa_algorithm_t alg,
385 const uint8_t *input,
386 size_t input_length,
387 const uint8_t *hash,
388 size_t hash_length)
389{
Julian Hall188953d2021-07-30 12:11:43 +0100390 psa_hash_operation_t operation;
391 psa_status_t psa_status = multi_hash_update(&operation, alg, input, input_length);
392
393 if (psa_status == PSA_SUCCESS) {
394
395 psa_status = psa_hash_verify(&operation, hash, hash_length);
396 }
397
398 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100399}
400
401psa_status_t psa_hash_compute(psa_algorithm_t alg,
402 const uint8_t *input,
403 size_t input_length,
404 uint8_t *hash,
405 size_t hash_size,
406 size_t *hash_length)
407{
Julian Hall188953d2021-07-30 12:11:43 +0100408 psa_hash_operation_t operation;
409 psa_status_t psa_status = multi_hash_update(&operation, alg, input, input_length);
410
411 if (psa_status == PSA_SUCCESS) {
412
413 psa_status = psa_hash_finish(&operation, hash, hash_size, hash_length);
414 }
415
416 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100417}