blob: 24a8c284b4031a57519c5081a1a35d0f5a168f31 [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_cipher_encrypt_setup(psa_cipher_operation_t *operation,
12 psa_key_id_t key,
13 psa_algorithm_t alg)
14{
Julian Hallb8b026e2022-02-11 14:19:26 +000015 if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
16 return psa_crypto_client_instance.init_status;
17
18 if (operation->handle)
19 return PSA_ERROR_BAD_STATE;
20
Julian Hall7a703402021-08-04 09:20:43 +010021 return crypto_caller_cipher_encrypt_setup(&psa_crypto_client_instance.base,
22 &operation->handle,
23 key, alg);
Julian Halld4071382021-07-07 16:45:53 +010024}
25
26psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
27 psa_key_id_t key,
28 psa_algorithm_t alg)
29{
Julian Hallb8b026e2022-02-11 14:19:26 +000030 if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
31 return psa_crypto_client_instance.init_status;
32
33 if (operation->handle)
34 return PSA_ERROR_BAD_STATE;
35
Julian Hall7a703402021-08-04 09:20:43 +010036 return crypto_caller_cipher_decrypt_setup(&psa_crypto_client_instance.base,
37 &operation->handle,
38 key, alg);
Julian Halld4071382021-07-07 16:45:53 +010039}
40
41psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
42 uint8_t *iv,
43 size_t iv_size,
44 size_t *iv_length)
45{
Julian Hall7a703402021-08-04 09:20:43 +010046 return crypto_caller_cipher_generate_iv(&psa_crypto_client_instance.base,
47 operation->handle,
48 iv, iv_size, iv_length);
Julian Halld4071382021-07-07 16:45:53 +010049}
50
51psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
52 const uint8_t *iv,
53 size_t iv_length)
54{
Julian Hall7a703402021-08-04 09:20:43 +010055 return crypto_caller_cipher_set_iv(&psa_crypto_client_instance.base,
56 operation->handle,
57 iv, iv_length);
Julian Halld4071382021-07-07 16:45:53 +010058}
59
60psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
61 const uint8_t *input,
62 size_t input_length,
63 uint8_t *output,
64 size_t output_size,
65 size_t *output_length)
66{
Julian Hall7a703402021-08-04 09:20:43 +010067 return crypto_caller_cipher_update(&psa_crypto_client_instance.base,
68 operation->handle,
69 input, input_length,
70 output, output_size, output_length);
Julian Halld4071382021-07-07 16:45:53 +010071}
72
73psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
74 uint8_t *output,
75 size_t output_size,
76 size_t *output_length)
77{
Julian Hall7a703402021-08-04 09:20:43 +010078 return crypto_caller_cipher_finish(&psa_crypto_client_instance.base,
79 operation->handle,
80 output, output_size, output_length);
Julian Halld4071382021-07-07 16:45:53 +010081}
82
83psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
84{
Julian Hall7a703402021-08-04 09:20:43 +010085 return crypto_caller_cipher_abort(&psa_crypto_client_instance.base,
86 operation->handle);
Julian Hall188953d2021-07-30 12:11:43 +010087}
88
89static psa_status_t multi_cipher_update(psa_cipher_operation_t *operation,
90 const uint8_t *input,
91 size_t input_length,
92 uint8_t *output,
93 size_t output_size,
94 size_t *output_length)
95{
96 psa_status_t psa_status = PSA_SUCCESS;
Julian Hall7a703402021-08-04 09:20:43 +010097 size_t max_update_size =
98 crypto_caller_cipher_max_update_size(&psa_crypto_client_instance.base);
Julian Hall188953d2021-07-30 12:11:43 +010099 size_t bytes_input = 0;
100 size_t bytes_output = 0;
101
102 *output_length = 0;
103
104 if (!max_update_size) {
105
106 /* Don't know the max update size so assume that the entire
107 * input and output can be handled in a single update. If
108 * this isn't true, the first cipher update operation will fail
109 * safely.
110 */
111 max_update_size = input_length;
112 }
113
Julian Hall1fc2d922022-02-15 15:46:58 +0000114 while (bytes_input < input_length) {
115
116 if (bytes_output >= output_size) {
117
118 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
119 break;
120 }
Julian Hall188953d2021-07-30 12:11:43 +0100121
122 size_t update_output_len = 0;
123 size_t bytes_remaining = input_length - bytes_input;
124 size_t update_len = (bytes_remaining < max_update_size) ?
125 bytes_remaining :
126 max_update_size;
127
128 psa_status = psa_cipher_update(operation,
129 &input[bytes_input], update_len,
130 &output[bytes_output], output_size - bytes_output, &update_output_len);
131
Julian Hall1fc2d922022-02-15 15:46:58 +0000132 if (psa_status != PSA_SUCCESS)
Julian Hall188953d2021-07-30 12:11:43 +0100133 break;
Julian Hall188953d2021-07-30 12:11:43 +0100134
135 bytes_input += update_len;
136 bytes_output += update_output_len;
137 }
138
139 if (psa_status == PSA_SUCCESS) {
140
141 if (bytes_output < output_size) {
142
143 size_t finish_output_len = 0;
144
145 psa_status = psa_cipher_finish(operation,
146 &output[bytes_output], output_size - bytes_output, &finish_output_len);
147
148 if (psa_status == PSA_SUCCESS) {
149
150 *output_length = bytes_output + finish_output_len;
151 }
152 }
153 else {
154
Julian Hall188953d2021-07-30 12:11:43 +0100155 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
156 }
157 }
158
159 return psa_status;
160}
161
Julian Halld670b412021-07-19 15:16:27 +0100162psa_status_t psa_cipher_encrypt(psa_key_id_t key,
163 psa_algorithm_t alg,
164 const uint8_t *input,
165 size_t input_length,
166 uint8_t *output,
167 size_t output_size,
168 size_t *output_length)
169{
Julian Hall188953d2021-07-30 12:11:43 +0100170 psa_cipher_operation_t operation = psa_cipher_operation_init();
171 psa_status_t psa_status = psa_cipher_encrypt_setup(&operation, key, alg);
172
173 if (psa_status == PSA_SUCCESS) {
174
Julian Hall1fc2d922022-02-15 15:46:58 +0000175 size_t ciphertext_len = 0;
176 size_t iv_len = 0;
177
178 psa_status = psa_cipher_generate_iv(&operation, output, output_size, &iv_len);
179
180 if (psa_status == PSA_SUCCESS) {
181
182 if (iv_len <= output_size) {
183
184 psa_status = multi_cipher_update(&operation,
185 input, input_length,
186 &output[iv_len], output_size - iv_len, &ciphertext_len);
187
188 *output_length = iv_len + ciphertext_len;
189 }
190 else {
191
192 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
193 }
194 }
195
196 if (psa_status != PSA_SUCCESS) {
197
198 psa_cipher_abort(&operation);
199 }
Julian Hall188953d2021-07-30 12:11:43 +0100200 }
201
202 return psa_status;
Julian Halld670b412021-07-19 15:16:27 +0100203}
204
205psa_status_t psa_cipher_decrypt(psa_key_id_t key,
206 psa_algorithm_t alg,
207 const uint8_t *input,
208 size_t input_length,
209 uint8_t *output,
210 size_t output_size,
211 size_t *output_length)
212{
Julian Hall1fc2d922022-02-15 15:46:58 +0000213 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
214 psa_status_t psa_status = psa_get_key_attributes(key, &attributes);
Julian Hall188953d2021-07-30 12:11:43 +0100215
216 if (psa_status == PSA_SUCCESS) {
217
Julian Hall1fc2d922022-02-15 15:46:58 +0000218 psa_cipher_operation_t operation = psa_cipher_operation_init();
219 psa_status = psa_cipher_decrypt_setup(&operation, key, alg);
220
221 if (psa_status == PSA_SUCCESS) {
222
223 size_t iv_len = PSA_CIPHER_IV_LENGTH(psa_get_key_type(&attributes), alg);
224
225 if (input_length >= iv_len) {
226
227 psa_status = psa_cipher_set_iv(&operation, input, iv_len);
228
229 if (psa_status == PSA_SUCCESS) {
230
231 psa_status = multi_cipher_update(&operation,
232 &input[iv_len], input_length - iv_len,
233 output, output_size, output_length);
234 }
235 }
236 else {
237
238 psa_status = PSA_ERROR_INVALID_ARGUMENT;
239 }
240
241 if (psa_status != PSA_SUCCESS) {
242
243 psa_cipher_abort(&operation);
244 }
245 }
246
247 psa_reset_key_attributes(&attributes);
Julian Hall188953d2021-07-30 12:11:43 +0100248 }
249
250 return psa_status;
Julian Halld670b412021-07-19 15:16:27 +0100251}