blob: 2e3db0e970c0334a7e6fb34436cdd8793b1926b1 [file] [log] [blame]
Julian Halld4071382021-07-07 16:45:53 +01001/*
Julian Hallb8b026e2022-02-11 14:19:26 +00002 * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
Julian Halld4071382021-07-07 16:45:53 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Julian Halld4071382021-07-07 16:45:53 +01007#include <psa/crypto.h>
8#include "psa_crypto_client.h"
Julian Halla9490042021-08-04 10:43:34 +01009#include "crypto_caller_selector.h"
Julian Halld4071382021-07-07 16:45:53 +010010
11psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
12 psa_algorithm_t alg)
13{
Julian Hall7a703402021-08-04 09:20:43 +010014 if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
15 return psa_crypto_client_instance.init_status;
Julian Hall8359a632021-07-08 15:10:30 +010016
Julian Hallb8b026e2022-02-11 14:19:26 +000017 if (operation->handle)
18 return PSA_ERROR_BAD_STATE;
19
Julian Hall7a703402021-08-04 09:20:43 +010020 return crypto_caller_hash_setup(&psa_crypto_client_instance.base,
21 &operation->handle, alg);
Julian Halld4071382021-07-07 16:45:53 +010022}
23
24psa_status_t psa_hash_update(psa_hash_operation_t *operation,
25 const uint8_t *input,
26 size_t input_length)
27{
Julian Hall7a703402021-08-04 09:20:43 +010028 return crypto_caller_hash_update(&psa_crypto_client_instance.base,
29 operation->handle,
30 input, input_length);
Julian Halld4071382021-07-07 16:45:53 +010031}
32
33psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
34 uint8_t *hash,
35 size_t hash_size,
36 size_t *hash_length)
37{
Julian Hall7a703402021-08-04 09:20:43 +010038 return crypto_caller_hash_finish(&psa_crypto_client_instance.base,
39 operation->handle,
40 hash, hash_size, hash_length);
Julian Halld4071382021-07-07 16:45:53 +010041}
42
43psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
44{
Julian Hall7a703402021-08-04 09:20:43 +010045 return crypto_caller_hash_abort(&psa_crypto_client_instance.base,
46 operation->handle);
Julian Halld4071382021-07-07 16:45:53 +010047}
48
49psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
50 const uint8_t *hash,
51 size_t hash_length)
52{
Julian Hall7a703402021-08-04 09:20:43 +010053 return crypto_caller_hash_verify(&psa_crypto_client_instance.base,
54 operation->handle,
55 hash, hash_length);
Julian Halld4071382021-07-07 16:45:53 +010056}
57
58psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
59 psa_hash_operation_t *target_operation)
60{
Julian Hallb8b026e2022-02-11 14:19:26 +000061 if (target_operation->handle)
62 return PSA_ERROR_BAD_STATE;
63
Julian Hall7a703402021-08-04 09:20:43 +010064 return crypto_caller_hash_clone(&psa_crypto_client_instance.base,
65 source_operation->handle,
66 &target_operation->handle);
Julian Halld4071382021-07-07 16:45:53 +010067}
68
Julian Hallf284b092021-07-23 12:00:01 +010069psa_status_t psa_hash_suspend(psa_hash_operation_t *operation,
Julian Hall188953d2021-07-30 12:11:43 +010070 uint8_t *hash_state,
71 size_t hash_state_size,
72 size_t *hash_state_length)
Julian Hallf284b092021-07-23 12:00:01 +010073{
Julian Hall09e55002022-02-22 16:36:20 +000074 (void)operation;
75 (void)hash_state;
76 (void)hash_state_size;
77 (void)hash_state_length;
78
Julian Hallf284b092021-07-23 12:00:01 +010079 return PSA_ERROR_NOT_SUPPORTED;
80}
81
82psa_status_t psa_hash_resume(psa_hash_operation_t *operation,
Julian Hall188953d2021-07-30 12:11:43 +010083 const uint8_t *hash_state,
84 size_t hash_state_length)
Julian Hallf284b092021-07-23 12:00:01 +010085{
Julian Hall09e55002022-02-22 16:36:20 +000086 (void)operation;
87 (void)hash_state;
88 (void)hash_state_length;
89
Julian Hallf284b092021-07-23 12:00:01 +010090 return PSA_ERROR_NOT_SUPPORTED;
91}
92
Julian Hall188953d2021-07-30 12:11:43 +010093static psa_status_t multi_hash_update(psa_hash_operation_t *operation,
94 psa_algorithm_t alg,
95 const uint8_t *input,
96 size_t input_length)
97{
98 *operation = psa_hash_operation_init();
99 psa_status_t psa_status = psa_hash_setup(operation, alg);
Julian Hall7a703402021-08-04 09:20:43 +0100100 size_t max_update_size = crypto_caller_hash_max_update_size(&psa_crypto_client_instance.base);
Julian Hall188953d2021-07-30 12:11:43 +0100101
102 if (!max_update_size) {
103
104 /* Don't know the max update size so assume that the entire
105 * input can be handled in a single update. If this isn't
106 * true, the first hash update operation will fail safely.
107 */
108 max_update_size = input_length;
109 }
110
111 if (psa_status == PSA_SUCCESS) {
112
113 size_t bytes_processed = 0;
114
115 while (bytes_processed < input_length) {
116
117 size_t bytes_remaining = input_length - bytes_processed;
118 size_t update_len = (bytes_remaining < max_update_size) ?
119 bytes_remaining :
120 max_update_size;
121
122 psa_status = psa_hash_update(operation, &input[bytes_processed], update_len);
123
124 if (psa_status != PSA_SUCCESS) {
125
126 psa_hash_abort(operation);
127 break;
128 }
129
130 bytes_processed += update_len;
131 }
132 }
133
134 return psa_status;
135}
136
Julian Halld4071382021-07-07 16:45:53 +0100137psa_status_t psa_hash_compare(psa_algorithm_t alg,
138 const uint8_t *input,
139 size_t input_length,
140 const uint8_t *hash,
141 size_t hash_length)
142{
Julian Hall188953d2021-07-30 12:11:43 +0100143 psa_hash_operation_t operation;
144 psa_status_t psa_status = multi_hash_update(&operation, alg, input, input_length);
145
146 if (psa_status == PSA_SUCCESS) {
147
148 psa_status = psa_hash_verify(&operation, hash, hash_length);
Julian Hallc6d7e4d2022-02-16 10:37:04 +0000149
150 if (psa_status != PSA_SUCCESS) {
151
152 psa_hash_abort(&operation);
153 }
Julian Hall188953d2021-07-30 12:11:43 +0100154 }
155
156 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100157}
158
159psa_status_t psa_hash_compute(psa_algorithm_t alg,
160 const uint8_t *input,
161 size_t input_length,
162 uint8_t *hash,
163 size_t hash_size,
164 size_t *hash_length)
165{
Julian Hall188953d2021-07-30 12:11:43 +0100166 psa_hash_operation_t operation;
167 psa_status_t psa_status = multi_hash_update(&operation, alg, input, input_length);
168
169 if (psa_status == PSA_SUCCESS) {
170
171 psa_status = psa_hash_finish(&operation, hash, hash_size, hash_length);
Julian Hallc6d7e4d2022-02-16 10:37:04 +0000172
173 if (psa_status != PSA_SUCCESS) {
174
175 psa_hash_abort(&operation);
176 }
Julian Hall188953d2021-07-30 12:11:43 +0100177 }
178
179 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100180}