blob: 3ab8ea21ab28e50e69e7084aee1dbf8818931b76 [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
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 Hallb8b026e2022-02-11 14:19:26 +000016 if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
17 return psa_crypto_client_instance.init_status;
18
19 if (operation->handle)
20 return PSA_ERROR_BAD_STATE;
21
Julian Hall7a703402021-08-04 09:20:43 +010022 return crypto_caller_cipher_encrypt_setup(&psa_crypto_client_instance.base,
23 &operation->handle,
24 key, alg);
Julian Halld4071382021-07-07 16:45:53 +010025}
26
27psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
28 psa_key_id_t key,
29 psa_algorithm_t alg)
30{
Julian Hallb8b026e2022-02-11 14:19:26 +000031 if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
32 return psa_crypto_client_instance.init_status;
33
34 if (operation->handle)
35 return PSA_ERROR_BAD_STATE;
36
Julian Hall7a703402021-08-04 09:20:43 +010037 return crypto_caller_cipher_decrypt_setup(&psa_crypto_client_instance.base,
38 &operation->handle,
39 key, alg);
Julian Halld4071382021-07-07 16:45:53 +010040}
41
42psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
43 uint8_t *iv,
44 size_t iv_size,
45 size_t *iv_length)
46{
Julian Hall7a703402021-08-04 09:20:43 +010047 return crypto_caller_cipher_generate_iv(&psa_crypto_client_instance.base,
48 operation->handle,
49 iv, iv_size, iv_length);
Julian Halld4071382021-07-07 16:45:53 +010050}
51
52psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
53 const uint8_t *iv,
54 size_t iv_length)
55{
Julian Hall7a703402021-08-04 09:20:43 +010056 return crypto_caller_cipher_set_iv(&psa_crypto_client_instance.base,
57 operation->handle,
58 iv, iv_length);
Julian Halld4071382021-07-07 16:45:53 +010059}
60
61psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
62 const uint8_t *input,
63 size_t input_length,
64 uint8_t *output,
65 size_t output_size,
66 size_t *output_length)
67{
Julian Hall7a703402021-08-04 09:20:43 +010068 return crypto_caller_cipher_update(&psa_crypto_client_instance.base,
69 operation->handle,
70 input, input_length,
71 output, output_size, output_length);
Julian Halld4071382021-07-07 16:45:53 +010072}
73
74psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
75 uint8_t *output,
76 size_t output_size,
77 size_t *output_length)
78{
Julian Hall7a703402021-08-04 09:20:43 +010079 return crypto_caller_cipher_finish(&psa_crypto_client_instance.base,
80 operation->handle,
81 output, output_size, output_length);
Julian Halld4071382021-07-07 16:45:53 +010082}
83
84psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
85{
Julian Hall7a703402021-08-04 09:20:43 +010086 return crypto_caller_cipher_abort(&psa_crypto_client_instance.base,
87 operation->handle);
Julian Hall188953d2021-07-30 12:11:43 +010088}
89
90static psa_status_t multi_cipher_update(psa_cipher_operation_t *operation,
91 const uint8_t *input,
92 size_t input_length,
93 uint8_t *output,
94 size_t output_size,
95 size_t *output_length)
96{
97 psa_status_t psa_status = PSA_SUCCESS;
Julian Hall7a703402021-08-04 09:20:43 +010098 size_t max_update_size =
99 crypto_caller_cipher_max_update_size(&psa_crypto_client_instance.base);
Julian Hall188953d2021-07-30 12:11:43 +0100100 size_t bytes_input = 0;
101 size_t bytes_output = 0;
102
103 *output_length = 0;
104
105 if (!max_update_size) {
106
107 /* Don't know the max update size so assume that the entire
108 * input and output can be handled in a single update. If
109 * this isn't true, the first cipher update operation will fail
110 * safely.
111 */
112 max_update_size = input_length;
113 }
114
115 while ((bytes_input < input_length) && (bytes_output < output_size)) {
116
117 size_t update_output_len = 0;
118 size_t bytes_remaining = input_length - bytes_input;
119 size_t update_len = (bytes_remaining < max_update_size) ?
120 bytes_remaining :
121 max_update_size;
122
123 psa_status = psa_cipher_update(operation,
124 &input[bytes_input], update_len,
125 &output[bytes_output], output_size - bytes_output, &update_output_len);
126
127 if (psa_status != PSA_SUCCESS) {
128
129 psa_cipher_abort(operation);
130 break;
131 }
132
133 bytes_input += update_len;
134 bytes_output += update_output_len;
135 }
136
137 if (psa_status == PSA_SUCCESS) {
138
139 if (bytes_output < output_size) {
140
141 size_t finish_output_len = 0;
142
143 psa_status = psa_cipher_finish(operation,
144 &output[bytes_output], output_size - bytes_output, &finish_output_len);
145
146 if (psa_status == PSA_SUCCESS) {
147
148 *output_length = bytes_output + finish_output_len;
149 }
150 }
151 else {
152
153 psa_cipher_abort(operation);
154 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
155 }
156 }
157
158 return psa_status;
159}
160
Julian Halld670b412021-07-19 15:16:27 +0100161psa_status_t psa_cipher_encrypt(psa_key_id_t key,
162 psa_algorithm_t alg,
163 const uint8_t *input,
164 size_t input_length,
165 uint8_t *output,
166 size_t output_size,
167 size_t *output_length)
168{
Julian Hall188953d2021-07-30 12:11:43 +0100169 psa_cipher_operation_t operation = psa_cipher_operation_init();
170 psa_status_t psa_status = psa_cipher_encrypt_setup(&operation, key, alg);
171
172 if (psa_status == PSA_SUCCESS) {
173
174 psa_status = multi_cipher_update(&operation,
175 input, input_length,
176 output, output_size, output_length);
177 }
178
179 return psa_status;
Julian Halld670b412021-07-19 15:16:27 +0100180}
181
182psa_status_t psa_cipher_decrypt(psa_key_id_t key,
183 psa_algorithm_t alg,
184 const uint8_t *input,
185 size_t input_length,
186 uint8_t *output,
187 size_t output_size,
188 size_t *output_length)
189{
Julian Hall188953d2021-07-30 12:11:43 +0100190 psa_cipher_operation_t operation = psa_cipher_operation_init();
191 psa_status_t psa_status = psa_cipher_decrypt_setup(&operation, key, alg);
192
193 if (psa_status == PSA_SUCCESS) {
194
195 psa_status = multi_cipher_update(&operation,
196 input, input_length,
197 output, output_size, output_length);
198 }
199
200 return psa_status;
Julian Halld670b412021-07-19 15:16:27 +0100201}