blob: 70836ea6bf4d6e9e6f8957699aca8d294aa3abdc [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
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
Julian Halle7bccbe2021-07-16 09:50:34 +010011
Julian Halld4071382021-07-07 16:45:53 +010012psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
13 psa_key_id_t key,
14 psa_algorithm_t alg)
15{
Julian Hall7a703402021-08-04 09:20:43 +010016 return crypto_caller_cipher_encrypt_setup(&psa_crypto_client_instance.base,
17 &operation->handle,
18 key, alg);
Julian Halld4071382021-07-07 16:45:53 +010019}
20
21psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
22 psa_key_id_t key,
23 psa_algorithm_t alg)
24{
Julian Hall7a703402021-08-04 09:20:43 +010025 return crypto_caller_cipher_decrypt_setup(&psa_crypto_client_instance.base,
26 &operation->handle,
27 key, alg);
Julian Halld4071382021-07-07 16:45:53 +010028}
29
30psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
31 uint8_t *iv,
32 size_t iv_size,
33 size_t *iv_length)
34{
Julian Hall7a703402021-08-04 09:20:43 +010035 return crypto_caller_cipher_generate_iv(&psa_crypto_client_instance.base,
36 operation->handle,
37 iv, iv_size, iv_length);
Julian Halld4071382021-07-07 16:45:53 +010038}
39
40psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
41 const uint8_t *iv,
42 size_t iv_length)
43{
Julian Hall7a703402021-08-04 09:20:43 +010044 return crypto_caller_cipher_set_iv(&psa_crypto_client_instance.base,
45 operation->handle,
46 iv, iv_length);
Julian Halld4071382021-07-07 16:45:53 +010047}
48
49psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
50 const uint8_t *input,
51 size_t input_length,
52 uint8_t *output,
53 size_t output_size,
54 size_t *output_length)
55{
Julian Hall7a703402021-08-04 09:20:43 +010056 return crypto_caller_cipher_update(&psa_crypto_client_instance.base,
57 operation->handle,
58 input, input_length,
59 output, output_size, output_length);
Julian Halld4071382021-07-07 16:45:53 +010060}
61
62psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
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_finish(&psa_crypto_client_instance.base,
68 operation->handle,
69 output, output_size, output_length);
Julian Halld4071382021-07-07 16:45:53 +010070}
71
72psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
73{
Julian Hall7a703402021-08-04 09:20:43 +010074 return crypto_caller_cipher_abort(&psa_crypto_client_instance.base,
75 operation->handle);
Julian Hall188953d2021-07-30 12:11:43 +010076}
77
78static psa_status_t multi_cipher_update(psa_cipher_operation_t *operation,
79 const uint8_t *input,
80 size_t input_length,
81 uint8_t *output,
82 size_t output_size,
83 size_t *output_length)
84{
85 psa_status_t psa_status = PSA_SUCCESS;
Julian Hall7a703402021-08-04 09:20:43 +010086 size_t max_update_size =
87 crypto_caller_cipher_max_update_size(&psa_crypto_client_instance.base);
Julian Hall188953d2021-07-30 12:11:43 +010088 size_t bytes_input = 0;
89 size_t bytes_output = 0;
90
91 *output_length = 0;
92
93 if (!max_update_size) {
94
95 /* Don't know the max update size so assume that the entire
96 * input and output can be handled in a single update. If
97 * this isn't true, the first cipher update operation will fail
98 * safely.
99 */
100 max_update_size = input_length;
101 }
102
103 while ((bytes_input < input_length) && (bytes_output < output_size)) {
104
105 size_t update_output_len = 0;
106 size_t bytes_remaining = input_length - bytes_input;
107 size_t update_len = (bytes_remaining < max_update_size) ?
108 bytes_remaining :
109 max_update_size;
110
111 psa_status = psa_cipher_update(operation,
112 &input[bytes_input], update_len,
113 &output[bytes_output], output_size - bytes_output, &update_output_len);
114
115 if (psa_status != PSA_SUCCESS) {
116
117 psa_cipher_abort(operation);
118 break;
119 }
120
121 bytes_input += update_len;
122 bytes_output += update_output_len;
123 }
124
125 if (psa_status == PSA_SUCCESS) {
126
127 if (bytes_output < output_size) {
128
129 size_t finish_output_len = 0;
130
131 psa_status = psa_cipher_finish(operation,
132 &output[bytes_output], output_size - bytes_output, &finish_output_len);
133
134 if (psa_status == PSA_SUCCESS) {
135
136 *output_length = bytes_output + finish_output_len;
137 }
138 }
139 else {
140
141 psa_cipher_abort(operation);
142 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
143 }
144 }
145
146 return psa_status;
147}
148
Julian Halld670b412021-07-19 15:16:27 +0100149psa_status_t psa_cipher_encrypt(psa_key_id_t key,
150 psa_algorithm_t alg,
151 const uint8_t *input,
152 size_t input_length,
153 uint8_t *output,
154 size_t output_size,
155 size_t *output_length)
156{
Julian Hall188953d2021-07-30 12:11:43 +0100157 psa_cipher_operation_t operation = psa_cipher_operation_init();
158 psa_status_t psa_status = psa_cipher_encrypt_setup(&operation, key, alg);
159
160 if (psa_status == PSA_SUCCESS) {
161
162 psa_status = multi_cipher_update(&operation,
163 input, input_length,
164 output, output_size, output_length);
165 }
166
167 return psa_status;
Julian Halld670b412021-07-19 15:16:27 +0100168}
169
170psa_status_t psa_cipher_decrypt(psa_key_id_t key,
171 psa_algorithm_t alg,
172 const uint8_t *input,
173 size_t input_length,
174 uint8_t *output,
175 size_t output_size,
176 size_t *output_length)
177{
Julian Hall188953d2021-07-30 12:11:43 +0100178 psa_cipher_operation_t operation = psa_cipher_operation_init();
179 psa_status_t psa_status = psa_cipher_decrypt_setup(&operation, key, alg);
180
181 if (psa_status == PSA_SUCCESS) {
182
183 psa_status = multi_cipher_update(&operation,
184 input, input_length,
185 output, output_size, output_length);
186 }
187
188 return psa_status;
Julian Halld670b412021-07-19 15:16:27 +0100189}