1*62c56f98SSadaf Ebrahimi /*
2*62c56f98SSadaf Ebrahimi * PSA cipher driver entry points
3*62c56f98SSadaf Ebrahimi */
4*62c56f98SSadaf Ebrahimi /*
5*62c56f98SSadaf Ebrahimi * Copyright The Mbed TLS Contributors
6*62c56f98SSadaf Ebrahimi * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7*62c56f98SSadaf Ebrahimi */
8*62c56f98SSadaf Ebrahimi
9*62c56f98SSadaf Ebrahimi #include "common.h"
10*62c56f98SSadaf Ebrahimi
11*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_C)
12*62c56f98SSadaf Ebrahimi
13*62c56f98SSadaf Ebrahimi #include "psa_crypto_cipher.h"
14*62c56f98SSadaf Ebrahimi #include "psa_crypto_core.h"
15*62c56f98SSadaf Ebrahimi #include "psa_crypto_random_impl.h"
16*62c56f98SSadaf Ebrahimi
17*62c56f98SSadaf Ebrahimi #include "mbedtls/cipher.h"
18*62c56f98SSadaf Ebrahimi #include "mbedtls/error.h"
19*62c56f98SSadaf Ebrahimi
20*62c56f98SSadaf Ebrahimi #include <string.h>
21*62c56f98SSadaf Ebrahimi
mbedtls_cipher_info_from_psa(psa_algorithm_t alg,psa_key_type_t key_type,size_t key_bits,mbedtls_cipher_id_t * cipher_id)22*62c56f98SSadaf Ebrahimi const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
23*62c56f98SSadaf Ebrahimi psa_algorithm_t alg,
24*62c56f98SSadaf Ebrahimi psa_key_type_t key_type,
25*62c56f98SSadaf Ebrahimi size_t key_bits,
26*62c56f98SSadaf Ebrahimi mbedtls_cipher_id_t *cipher_id)
27*62c56f98SSadaf Ebrahimi {
28*62c56f98SSadaf Ebrahimi mbedtls_cipher_mode_t mode;
29*62c56f98SSadaf Ebrahimi mbedtls_cipher_id_t cipher_id_tmp;
30*62c56f98SSadaf Ebrahimi
31*62c56f98SSadaf Ebrahimi if (PSA_ALG_IS_AEAD(alg)) {
32*62c56f98SSadaf Ebrahimi alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
33*62c56f98SSadaf Ebrahimi }
34*62c56f98SSadaf Ebrahimi
35*62c56f98SSadaf Ebrahimi if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
36*62c56f98SSadaf Ebrahimi switch (alg) {
37*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
38*62c56f98SSadaf Ebrahimi case PSA_ALG_STREAM_CIPHER:
39*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_STREAM;
40*62c56f98SSadaf Ebrahimi break;
41*62c56f98SSadaf Ebrahimi #endif
42*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
43*62c56f98SSadaf Ebrahimi case PSA_ALG_CTR:
44*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_CTR;
45*62c56f98SSadaf Ebrahimi break;
46*62c56f98SSadaf Ebrahimi #endif
47*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
48*62c56f98SSadaf Ebrahimi case PSA_ALG_CFB:
49*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_CFB;
50*62c56f98SSadaf Ebrahimi break;
51*62c56f98SSadaf Ebrahimi #endif
52*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
53*62c56f98SSadaf Ebrahimi case PSA_ALG_OFB:
54*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_OFB;
55*62c56f98SSadaf Ebrahimi break;
56*62c56f98SSadaf Ebrahimi #endif
57*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
58*62c56f98SSadaf Ebrahimi case PSA_ALG_ECB_NO_PADDING:
59*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_ECB;
60*62c56f98SSadaf Ebrahimi break;
61*62c56f98SSadaf Ebrahimi #endif
62*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
63*62c56f98SSadaf Ebrahimi case PSA_ALG_CBC_NO_PADDING:
64*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_CBC;
65*62c56f98SSadaf Ebrahimi break;
66*62c56f98SSadaf Ebrahimi #endif
67*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
68*62c56f98SSadaf Ebrahimi case PSA_ALG_CBC_PKCS7:
69*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_CBC;
70*62c56f98SSadaf Ebrahimi break;
71*62c56f98SSadaf Ebrahimi #endif
72*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
73*62c56f98SSadaf Ebrahimi case PSA_ALG_CCM_STAR_NO_TAG:
74*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
75*62c56f98SSadaf Ebrahimi break;
76*62c56f98SSadaf Ebrahimi #endif
77*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
78*62c56f98SSadaf Ebrahimi case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
79*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_CCM;
80*62c56f98SSadaf Ebrahimi break;
81*62c56f98SSadaf Ebrahimi #endif
82*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
83*62c56f98SSadaf Ebrahimi case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
84*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_GCM;
85*62c56f98SSadaf Ebrahimi break;
86*62c56f98SSadaf Ebrahimi #endif
87*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
88*62c56f98SSadaf Ebrahimi case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
89*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_CHACHAPOLY;
90*62c56f98SSadaf Ebrahimi break;
91*62c56f98SSadaf Ebrahimi #endif
92*62c56f98SSadaf Ebrahimi default:
93*62c56f98SSadaf Ebrahimi return NULL;
94*62c56f98SSadaf Ebrahimi }
95*62c56f98SSadaf Ebrahimi } else if (alg == PSA_ALG_CMAC) {
96*62c56f98SSadaf Ebrahimi mode = MBEDTLS_MODE_ECB;
97*62c56f98SSadaf Ebrahimi } else {
98*62c56f98SSadaf Ebrahimi return NULL;
99*62c56f98SSadaf Ebrahimi }
100*62c56f98SSadaf Ebrahimi
101*62c56f98SSadaf Ebrahimi switch (key_type) {
102*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
103*62c56f98SSadaf Ebrahimi case PSA_KEY_TYPE_AES:
104*62c56f98SSadaf Ebrahimi cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
105*62c56f98SSadaf Ebrahimi break;
106*62c56f98SSadaf Ebrahimi #endif
107*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
108*62c56f98SSadaf Ebrahimi case PSA_KEY_TYPE_ARIA:
109*62c56f98SSadaf Ebrahimi cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
110*62c56f98SSadaf Ebrahimi break;
111*62c56f98SSadaf Ebrahimi #endif
112*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
113*62c56f98SSadaf Ebrahimi case PSA_KEY_TYPE_DES:
114*62c56f98SSadaf Ebrahimi /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
115*62c56f98SSadaf Ebrahimi * and 192 for three-key Triple-DES. */
116*62c56f98SSadaf Ebrahimi if (key_bits == 64) {
117*62c56f98SSadaf Ebrahimi cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
118*62c56f98SSadaf Ebrahimi } else {
119*62c56f98SSadaf Ebrahimi cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
120*62c56f98SSadaf Ebrahimi }
121*62c56f98SSadaf Ebrahimi /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
122*62c56f98SSadaf Ebrahimi * but two-key Triple-DES is functionally three-key Triple-DES
123*62c56f98SSadaf Ebrahimi * with K1=K3, so that's how we present it to mbedtls. */
124*62c56f98SSadaf Ebrahimi if (key_bits == 128) {
125*62c56f98SSadaf Ebrahimi key_bits = 192;
126*62c56f98SSadaf Ebrahimi }
127*62c56f98SSadaf Ebrahimi break;
128*62c56f98SSadaf Ebrahimi #endif
129*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
130*62c56f98SSadaf Ebrahimi case PSA_KEY_TYPE_CAMELLIA:
131*62c56f98SSadaf Ebrahimi cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
132*62c56f98SSadaf Ebrahimi break;
133*62c56f98SSadaf Ebrahimi #endif
134*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
135*62c56f98SSadaf Ebrahimi case PSA_KEY_TYPE_CHACHA20:
136*62c56f98SSadaf Ebrahimi cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
137*62c56f98SSadaf Ebrahimi break;
138*62c56f98SSadaf Ebrahimi #endif
139*62c56f98SSadaf Ebrahimi default:
140*62c56f98SSadaf Ebrahimi return NULL;
141*62c56f98SSadaf Ebrahimi }
142*62c56f98SSadaf Ebrahimi if (cipher_id != NULL) {
143*62c56f98SSadaf Ebrahimi *cipher_id = cipher_id_tmp;
144*62c56f98SSadaf Ebrahimi }
145*62c56f98SSadaf Ebrahimi
146*62c56f98SSadaf Ebrahimi return mbedtls_cipher_info_from_values(cipher_id_tmp,
147*62c56f98SSadaf Ebrahimi (int) key_bits, mode);
148*62c56f98SSadaf Ebrahimi }
149*62c56f98SSadaf Ebrahimi
150*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
151*62c56f98SSadaf Ebrahimi
psa_cipher_setup(mbedtls_psa_cipher_operation_t * operation,const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg,mbedtls_operation_t cipher_operation)152*62c56f98SSadaf Ebrahimi static psa_status_t psa_cipher_setup(
153*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_operation_t *operation,
154*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *attributes,
155*62c56f98SSadaf Ebrahimi const uint8_t *key_buffer, size_t key_buffer_size,
156*62c56f98SSadaf Ebrahimi psa_algorithm_t alg,
157*62c56f98SSadaf Ebrahimi mbedtls_operation_t cipher_operation)
158*62c56f98SSadaf Ebrahimi {
159*62c56f98SSadaf Ebrahimi int ret = 0;
160*62c56f98SSadaf Ebrahimi size_t key_bits;
161*62c56f98SSadaf Ebrahimi const mbedtls_cipher_info_t *cipher_info = NULL;
162*62c56f98SSadaf Ebrahimi psa_key_type_t key_type = attributes->core.type;
163*62c56f98SSadaf Ebrahimi
164*62c56f98SSadaf Ebrahimi (void) key_buffer_size;
165*62c56f98SSadaf Ebrahimi
166*62c56f98SSadaf Ebrahimi mbedtls_cipher_init(&operation->ctx.cipher);
167*62c56f98SSadaf Ebrahimi
168*62c56f98SSadaf Ebrahimi operation->alg = alg;
169*62c56f98SSadaf Ebrahimi key_bits = attributes->core.bits;
170*62c56f98SSadaf Ebrahimi cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
171*62c56f98SSadaf Ebrahimi key_bits, NULL);
172*62c56f98SSadaf Ebrahimi if (cipher_info == NULL) {
173*62c56f98SSadaf Ebrahimi return PSA_ERROR_NOT_SUPPORTED;
174*62c56f98SSadaf Ebrahimi }
175*62c56f98SSadaf Ebrahimi
176*62c56f98SSadaf Ebrahimi ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
177*62c56f98SSadaf Ebrahimi if (ret != 0) {
178*62c56f98SSadaf Ebrahimi goto exit;
179*62c56f98SSadaf Ebrahimi }
180*62c56f98SSadaf Ebrahimi
181*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
182*62c56f98SSadaf Ebrahimi if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
183*62c56f98SSadaf Ebrahimi /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
184*62c56f98SSadaf Ebrahimi uint8_t keys[24];
185*62c56f98SSadaf Ebrahimi memcpy(keys, key_buffer, 16);
186*62c56f98SSadaf Ebrahimi memcpy(keys + 16, key_buffer, 8);
187*62c56f98SSadaf Ebrahimi ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
188*62c56f98SSadaf Ebrahimi keys,
189*62c56f98SSadaf Ebrahimi 192, cipher_operation);
190*62c56f98SSadaf Ebrahimi } else
191*62c56f98SSadaf Ebrahimi #endif
192*62c56f98SSadaf Ebrahimi {
193*62c56f98SSadaf Ebrahimi ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
194*62c56f98SSadaf Ebrahimi (int) key_bits, cipher_operation);
195*62c56f98SSadaf Ebrahimi }
196*62c56f98SSadaf Ebrahimi if (ret != 0) {
197*62c56f98SSadaf Ebrahimi goto exit;
198*62c56f98SSadaf Ebrahimi }
199*62c56f98SSadaf Ebrahimi
200*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
201*62c56f98SSadaf Ebrahimi defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
202*62c56f98SSadaf Ebrahimi switch (alg) {
203*62c56f98SSadaf Ebrahimi case PSA_ALG_CBC_NO_PADDING:
204*62c56f98SSadaf Ebrahimi ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
205*62c56f98SSadaf Ebrahimi MBEDTLS_PADDING_NONE);
206*62c56f98SSadaf Ebrahimi break;
207*62c56f98SSadaf Ebrahimi case PSA_ALG_CBC_PKCS7:
208*62c56f98SSadaf Ebrahimi ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
209*62c56f98SSadaf Ebrahimi MBEDTLS_PADDING_PKCS7);
210*62c56f98SSadaf Ebrahimi break;
211*62c56f98SSadaf Ebrahimi default:
212*62c56f98SSadaf Ebrahimi /* The algorithm doesn't involve padding. */
213*62c56f98SSadaf Ebrahimi ret = 0;
214*62c56f98SSadaf Ebrahimi break;
215*62c56f98SSadaf Ebrahimi }
216*62c56f98SSadaf Ebrahimi if (ret != 0) {
217*62c56f98SSadaf Ebrahimi goto exit;
218*62c56f98SSadaf Ebrahimi }
219*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
220*62c56f98SSadaf Ebrahimi MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
221*62c56f98SSadaf Ebrahimi
222*62c56f98SSadaf Ebrahimi operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
223*62c56f98SSadaf Ebrahimi PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
224*62c56f98SSadaf Ebrahimi operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
225*62c56f98SSadaf Ebrahimi
226*62c56f98SSadaf Ebrahimi exit:
227*62c56f98SSadaf Ebrahimi return mbedtls_to_psa_error(ret);
228*62c56f98SSadaf Ebrahimi }
229*62c56f98SSadaf Ebrahimi
mbedtls_psa_cipher_encrypt_setup(mbedtls_psa_cipher_operation_t * operation,const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg)230*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_psa_cipher_encrypt_setup(
231*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_operation_t *operation,
232*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *attributes,
233*62c56f98SSadaf Ebrahimi const uint8_t *key_buffer, size_t key_buffer_size,
234*62c56f98SSadaf Ebrahimi psa_algorithm_t alg)
235*62c56f98SSadaf Ebrahimi {
236*62c56f98SSadaf Ebrahimi return psa_cipher_setup(operation, attributes,
237*62c56f98SSadaf Ebrahimi key_buffer, key_buffer_size,
238*62c56f98SSadaf Ebrahimi alg, MBEDTLS_ENCRYPT);
239*62c56f98SSadaf Ebrahimi }
240*62c56f98SSadaf Ebrahimi
mbedtls_psa_cipher_decrypt_setup(mbedtls_psa_cipher_operation_t * operation,const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg)241*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_psa_cipher_decrypt_setup(
242*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_operation_t *operation,
243*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *attributes,
244*62c56f98SSadaf Ebrahimi const uint8_t *key_buffer, size_t key_buffer_size,
245*62c56f98SSadaf Ebrahimi psa_algorithm_t alg)
246*62c56f98SSadaf Ebrahimi {
247*62c56f98SSadaf Ebrahimi return psa_cipher_setup(operation, attributes,
248*62c56f98SSadaf Ebrahimi key_buffer, key_buffer_size,
249*62c56f98SSadaf Ebrahimi alg, MBEDTLS_DECRYPT);
250*62c56f98SSadaf Ebrahimi }
251*62c56f98SSadaf Ebrahimi
mbedtls_psa_cipher_set_iv(mbedtls_psa_cipher_operation_t * operation,const uint8_t * iv,size_t iv_length)252*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_psa_cipher_set_iv(
253*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_operation_t *operation,
254*62c56f98SSadaf Ebrahimi const uint8_t *iv, size_t iv_length)
255*62c56f98SSadaf Ebrahimi {
256*62c56f98SSadaf Ebrahimi if (iv_length != operation->iv_length) {
257*62c56f98SSadaf Ebrahimi return PSA_ERROR_INVALID_ARGUMENT;
258*62c56f98SSadaf Ebrahimi }
259*62c56f98SSadaf Ebrahimi
260*62c56f98SSadaf Ebrahimi return mbedtls_to_psa_error(
261*62c56f98SSadaf Ebrahimi mbedtls_cipher_set_iv(&operation->ctx.cipher,
262*62c56f98SSadaf Ebrahimi iv, iv_length));
263*62c56f98SSadaf Ebrahimi }
264*62c56f98SSadaf Ebrahimi
265*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
266*62c56f98SSadaf Ebrahimi /** Process input for which the algorithm is set to ECB mode.
267*62c56f98SSadaf Ebrahimi *
268*62c56f98SSadaf Ebrahimi * This requires manual processing, since the PSA API is defined as being
269*62c56f98SSadaf Ebrahimi * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
270*62c56f98SSadaf Ebrahimi * but the underlying mbedtls_cipher_update only takes full blocks.
271*62c56f98SSadaf Ebrahimi *
272*62c56f98SSadaf Ebrahimi * \param ctx The mbedtls cipher context to use. It must have been
273*62c56f98SSadaf Ebrahimi * set up for ECB.
274*62c56f98SSadaf Ebrahimi * \param[in] input The input plaintext or ciphertext to process.
275*62c56f98SSadaf Ebrahimi * \param input_length The number of bytes to process from \p input.
276*62c56f98SSadaf Ebrahimi * This does not need to be aligned to a block boundary.
277*62c56f98SSadaf Ebrahimi * If there is a partial block at the end of the input,
278*62c56f98SSadaf Ebrahimi * it is stored in \p ctx for future processing.
279*62c56f98SSadaf Ebrahimi * \param output The buffer where the output is written. It must be
280*62c56f98SSadaf Ebrahimi * at least `BS * floor((p + input_length) / BS)` bytes
281*62c56f98SSadaf Ebrahimi * long, where `p` is the number of bytes in the
282*62c56f98SSadaf Ebrahimi * unprocessed partial block in \p ctx (with
283*62c56f98SSadaf Ebrahimi * `0 <= p <= BS - 1`) and `BS` is the block size.
284*62c56f98SSadaf Ebrahimi * \param output_length On success, the number of bytes written to \p output.
285*62c56f98SSadaf Ebrahimi * \c 0 on error.
286*62c56f98SSadaf Ebrahimi *
287*62c56f98SSadaf Ebrahimi * \return #PSA_SUCCESS or an error from a hardware accelerator
288*62c56f98SSadaf Ebrahimi */
psa_cipher_update_ecb(mbedtls_cipher_context_t * ctx,const uint8_t * input,size_t input_length,uint8_t * output,size_t * output_length)289*62c56f98SSadaf Ebrahimi static psa_status_t psa_cipher_update_ecb(
290*62c56f98SSadaf Ebrahimi mbedtls_cipher_context_t *ctx,
291*62c56f98SSadaf Ebrahimi const uint8_t *input,
292*62c56f98SSadaf Ebrahimi size_t input_length,
293*62c56f98SSadaf Ebrahimi uint8_t *output,
294*62c56f98SSadaf Ebrahimi size_t *output_length)
295*62c56f98SSadaf Ebrahimi {
296*62c56f98SSadaf Ebrahimi psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
297*62c56f98SSadaf Ebrahimi size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
298*62c56f98SSadaf Ebrahimi size_t internal_output_length = 0;
299*62c56f98SSadaf Ebrahimi *output_length = 0;
300*62c56f98SSadaf Ebrahimi
301*62c56f98SSadaf Ebrahimi if (input_length == 0) {
302*62c56f98SSadaf Ebrahimi status = PSA_SUCCESS;
303*62c56f98SSadaf Ebrahimi goto exit;
304*62c56f98SSadaf Ebrahimi }
305*62c56f98SSadaf Ebrahimi
306*62c56f98SSadaf Ebrahimi if (ctx->unprocessed_len > 0) {
307*62c56f98SSadaf Ebrahimi /* Fill up to block size, and run the block if there's a full one. */
308*62c56f98SSadaf Ebrahimi size_t bytes_to_copy = block_size - ctx->unprocessed_len;
309*62c56f98SSadaf Ebrahimi
310*62c56f98SSadaf Ebrahimi if (input_length < bytes_to_copy) {
311*62c56f98SSadaf Ebrahimi bytes_to_copy = input_length;
312*62c56f98SSadaf Ebrahimi }
313*62c56f98SSadaf Ebrahimi
314*62c56f98SSadaf Ebrahimi memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
315*62c56f98SSadaf Ebrahimi input, bytes_to_copy);
316*62c56f98SSadaf Ebrahimi input_length -= bytes_to_copy;
317*62c56f98SSadaf Ebrahimi input += bytes_to_copy;
318*62c56f98SSadaf Ebrahimi ctx->unprocessed_len += bytes_to_copy;
319*62c56f98SSadaf Ebrahimi
320*62c56f98SSadaf Ebrahimi if (ctx->unprocessed_len == block_size) {
321*62c56f98SSadaf Ebrahimi status = mbedtls_to_psa_error(
322*62c56f98SSadaf Ebrahimi mbedtls_cipher_update(ctx,
323*62c56f98SSadaf Ebrahimi ctx->unprocessed_data,
324*62c56f98SSadaf Ebrahimi block_size,
325*62c56f98SSadaf Ebrahimi output, &internal_output_length));
326*62c56f98SSadaf Ebrahimi
327*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
328*62c56f98SSadaf Ebrahimi goto exit;
329*62c56f98SSadaf Ebrahimi }
330*62c56f98SSadaf Ebrahimi
331*62c56f98SSadaf Ebrahimi output += internal_output_length;
332*62c56f98SSadaf Ebrahimi *output_length += internal_output_length;
333*62c56f98SSadaf Ebrahimi ctx->unprocessed_len = 0;
334*62c56f98SSadaf Ebrahimi }
335*62c56f98SSadaf Ebrahimi }
336*62c56f98SSadaf Ebrahimi
337*62c56f98SSadaf Ebrahimi while (input_length >= block_size) {
338*62c56f98SSadaf Ebrahimi /* Run all full blocks we have, one by one */
339*62c56f98SSadaf Ebrahimi status = mbedtls_to_psa_error(
340*62c56f98SSadaf Ebrahimi mbedtls_cipher_update(ctx, input,
341*62c56f98SSadaf Ebrahimi block_size,
342*62c56f98SSadaf Ebrahimi output, &internal_output_length));
343*62c56f98SSadaf Ebrahimi
344*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
345*62c56f98SSadaf Ebrahimi goto exit;
346*62c56f98SSadaf Ebrahimi }
347*62c56f98SSadaf Ebrahimi
348*62c56f98SSadaf Ebrahimi input_length -= block_size;
349*62c56f98SSadaf Ebrahimi input += block_size;
350*62c56f98SSadaf Ebrahimi
351*62c56f98SSadaf Ebrahimi output += internal_output_length;
352*62c56f98SSadaf Ebrahimi *output_length += internal_output_length;
353*62c56f98SSadaf Ebrahimi }
354*62c56f98SSadaf Ebrahimi
355*62c56f98SSadaf Ebrahimi if (input_length > 0) {
356*62c56f98SSadaf Ebrahimi /* Save unprocessed bytes for later processing */
357*62c56f98SSadaf Ebrahimi memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
358*62c56f98SSadaf Ebrahimi input, input_length);
359*62c56f98SSadaf Ebrahimi ctx->unprocessed_len += input_length;
360*62c56f98SSadaf Ebrahimi }
361*62c56f98SSadaf Ebrahimi
362*62c56f98SSadaf Ebrahimi status = PSA_SUCCESS;
363*62c56f98SSadaf Ebrahimi
364*62c56f98SSadaf Ebrahimi exit:
365*62c56f98SSadaf Ebrahimi return status;
366*62c56f98SSadaf Ebrahimi }
367*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
368*62c56f98SSadaf Ebrahimi
mbedtls_psa_cipher_update(mbedtls_psa_cipher_operation_t * operation,const uint8_t * input,size_t input_length,uint8_t * output,size_t output_size,size_t * output_length)369*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_psa_cipher_update(
370*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_operation_t *operation,
371*62c56f98SSadaf Ebrahimi const uint8_t *input, size_t input_length,
372*62c56f98SSadaf Ebrahimi uint8_t *output, size_t output_size, size_t *output_length)
373*62c56f98SSadaf Ebrahimi {
374*62c56f98SSadaf Ebrahimi psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
375*62c56f98SSadaf Ebrahimi size_t expected_output_size;
376*62c56f98SSadaf Ebrahimi
377*62c56f98SSadaf Ebrahimi if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
378*62c56f98SSadaf Ebrahimi /* Take the unprocessed partial block left over from previous
379*62c56f98SSadaf Ebrahimi * update calls, if any, plus the input to this call. Remove
380*62c56f98SSadaf Ebrahimi * the last partial block, if any. You get the data that will be
381*62c56f98SSadaf Ebrahimi * output in this call. */
382*62c56f98SSadaf Ebrahimi expected_output_size =
383*62c56f98SSadaf Ebrahimi (operation->ctx.cipher.unprocessed_len + input_length)
384*62c56f98SSadaf Ebrahimi / operation->block_length * operation->block_length;
385*62c56f98SSadaf Ebrahimi } else {
386*62c56f98SSadaf Ebrahimi expected_output_size = input_length;
387*62c56f98SSadaf Ebrahimi }
388*62c56f98SSadaf Ebrahimi
389*62c56f98SSadaf Ebrahimi if (output_size < expected_output_size) {
390*62c56f98SSadaf Ebrahimi return PSA_ERROR_BUFFER_TOO_SMALL;
391*62c56f98SSadaf Ebrahimi }
392*62c56f98SSadaf Ebrahimi
393*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
394*62c56f98SSadaf Ebrahimi if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
395*62c56f98SSadaf Ebrahimi /* mbedtls_cipher_update has an API inconsistency: it will only
396*62c56f98SSadaf Ebrahimi * process a single block at a time in ECB mode. Abstract away that
397*62c56f98SSadaf Ebrahimi * inconsistency here to match the PSA API behaviour. */
398*62c56f98SSadaf Ebrahimi status = psa_cipher_update_ecb(&operation->ctx.cipher,
399*62c56f98SSadaf Ebrahimi input,
400*62c56f98SSadaf Ebrahimi input_length,
401*62c56f98SSadaf Ebrahimi output,
402*62c56f98SSadaf Ebrahimi output_length);
403*62c56f98SSadaf Ebrahimi } else
404*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
405*62c56f98SSadaf Ebrahimi {
406*62c56f98SSadaf Ebrahimi status = mbedtls_to_psa_error(
407*62c56f98SSadaf Ebrahimi mbedtls_cipher_update(&operation->ctx.cipher, input,
408*62c56f98SSadaf Ebrahimi input_length, output, output_length));
409*62c56f98SSadaf Ebrahimi
410*62c56f98SSadaf Ebrahimi if (*output_length > output_size) {
411*62c56f98SSadaf Ebrahimi return PSA_ERROR_CORRUPTION_DETECTED;
412*62c56f98SSadaf Ebrahimi }
413*62c56f98SSadaf Ebrahimi }
414*62c56f98SSadaf Ebrahimi
415*62c56f98SSadaf Ebrahimi return status;
416*62c56f98SSadaf Ebrahimi }
417*62c56f98SSadaf Ebrahimi
mbedtls_psa_cipher_finish(mbedtls_psa_cipher_operation_t * operation,uint8_t * output,size_t output_size,size_t * output_length)418*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_psa_cipher_finish(
419*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_operation_t *operation,
420*62c56f98SSadaf Ebrahimi uint8_t *output, size_t output_size, size_t *output_length)
421*62c56f98SSadaf Ebrahimi {
422*62c56f98SSadaf Ebrahimi psa_status_t status = PSA_ERROR_GENERIC_ERROR;
423*62c56f98SSadaf Ebrahimi uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
424*62c56f98SSadaf Ebrahimi
425*62c56f98SSadaf Ebrahimi if (operation->ctx.cipher.unprocessed_len != 0) {
426*62c56f98SSadaf Ebrahimi if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
427*62c56f98SSadaf Ebrahimi operation->alg == PSA_ALG_CBC_NO_PADDING) {
428*62c56f98SSadaf Ebrahimi status = PSA_ERROR_INVALID_ARGUMENT;
429*62c56f98SSadaf Ebrahimi goto exit;
430*62c56f98SSadaf Ebrahimi }
431*62c56f98SSadaf Ebrahimi }
432*62c56f98SSadaf Ebrahimi
433*62c56f98SSadaf Ebrahimi status = mbedtls_to_psa_error(
434*62c56f98SSadaf Ebrahimi mbedtls_cipher_finish(&operation->ctx.cipher,
435*62c56f98SSadaf Ebrahimi temp_output_buffer,
436*62c56f98SSadaf Ebrahimi output_length));
437*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
438*62c56f98SSadaf Ebrahimi goto exit;
439*62c56f98SSadaf Ebrahimi }
440*62c56f98SSadaf Ebrahimi
441*62c56f98SSadaf Ebrahimi if (*output_length == 0) {
442*62c56f98SSadaf Ebrahimi ; /* Nothing to copy. Note that output may be NULL in this case. */
443*62c56f98SSadaf Ebrahimi } else if (output_size >= *output_length) {
444*62c56f98SSadaf Ebrahimi memcpy(output, temp_output_buffer, *output_length);
445*62c56f98SSadaf Ebrahimi } else {
446*62c56f98SSadaf Ebrahimi status = PSA_ERROR_BUFFER_TOO_SMALL;
447*62c56f98SSadaf Ebrahimi }
448*62c56f98SSadaf Ebrahimi
449*62c56f98SSadaf Ebrahimi exit:
450*62c56f98SSadaf Ebrahimi mbedtls_platform_zeroize(temp_output_buffer,
451*62c56f98SSadaf Ebrahimi sizeof(temp_output_buffer));
452*62c56f98SSadaf Ebrahimi
453*62c56f98SSadaf Ebrahimi return status;
454*62c56f98SSadaf Ebrahimi }
455*62c56f98SSadaf Ebrahimi
mbedtls_psa_cipher_abort(mbedtls_psa_cipher_operation_t * operation)456*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_psa_cipher_abort(
457*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_operation_t *operation)
458*62c56f98SSadaf Ebrahimi {
459*62c56f98SSadaf Ebrahimi /* Sanity check (shouldn't happen: operation->alg should
460*62c56f98SSadaf Ebrahimi * always have been initialized to a valid value). */
461*62c56f98SSadaf Ebrahimi if (!PSA_ALG_IS_CIPHER(operation->alg)) {
462*62c56f98SSadaf Ebrahimi return PSA_ERROR_BAD_STATE;
463*62c56f98SSadaf Ebrahimi }
464*62c56f98SSadaf Ebrahimi
465*62c56f98SSadaf Ebrahimi mbedtls_cipher_free(&operation->ctx.cipher);
466*62c56f98SSadaf Ebrahimi
467*62c56f98SSadaf Ebrahimi return PSA_SUCCESS;
468*62c56f98SSadaf Ebrahimi }
469*62c56f98SSadaf Ebrahimi
mbedtls_psa_cipher_encrypt(const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg,const uint8_t * iv,size_t iv_length,const uint8_t * input,size_t input_length,uint8_t * output,size_t output_size,size_t * output_length)470*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_psa_cipher_encrypt(
471*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *attributes,
472*62c56f98SSadaf Ebrahimi const uint8_t *key_buffer,
473*62c56f98SSadaf Ebrahimi size_t key_buffer_size,
474*62c56f98SSadaf Ebrahimi psa_algorithm_t alg,
475*62c56f98SSadaf Ebrahimi const uint8_t *iv,
476*62c56f98SSadaf Ebrahimi size_t iv_length,
477*62c56f98SSadaf Ebrahimi const uint8_t *input,
478*62c56f98SSadaf Ebrahimi size_t input_length,
479*62c56f98SSadaf Ebrahimi uint8_t *output,
480*62c56f98SSadaf Ebrahimi size_t output_size,
481*62c56f98SSadaf Ebrahimi size_t *output_length)
482*62c56f98SSadaf Ebrahimi {
483*62c56f98SSadaf Ebrahimi psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
484*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
485*62c56f98SSadaf Ebrahimi size_t update_output_length, finish_output_length;
486*62c56f98SSadaf Ebrahimi
487*62c56f98SSadaf Ebrahimi status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
488*62c56f98SSadaf Ebrahimi key_buffer, key_buffer_size,
489*62c56f98SSadaf Ebrahimi alg);
490*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
491*62c56f98SSadaf Ebrahimi goto exit;
492*62c56f98SSadaf Ebrahimi }
493*62c56f98SSadaf Ebrahimi
494*62c56f98SSadaf Ebrahimi if (iv_length > 0) {
495*62c56f98SSadaf Ebrahimi status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
496*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
497*62c56f98SSadaf Ebrahimi goto exit;
498*62c56f98SSadaf Ebrahimi }
499*62c56f98SSadaf Ebrahimi }
500*62c56f98SSadaf Ebrahimi
501*62c56f98SSadaf Ebrahimi status = mbedtls_psa_cipher_update(&operation, input, input_length,
502*62c56f98SSadaf Ebrahimi output, output_size,
503*62c56f98SSadaf Ebrahimi &update_output_length);
504*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
505*62c56f98SSadaf Ebrahimi goto exit;
506*62c56f98SSadaf Ebrahimi }
507*62c56f98SSadaf Ebrahimi
508*62c56f98SSadaf Ebrahimi status = mbedtls_psa_cipher_finish(
509*62c56f98SSadaf Ebrahimi &operation,
510*62c56f98SSadaf Ebrahimi mbedtls_buffer_offset(output, update_output_length),
511*62c56f98SSadaf Ebrahimi output_size - update_output_length, &finish_output_length);
512*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
513*62c56f98SSadaf Ebrahimi goto exit;
514*62c56f98SSadaf Ebrahimi }
515*62c56f98SSadaf Ebrahimi
516*62c56f98SSadaf Ebrahimi *output_length = update_output_length + finish_output_length;
517*62c56f98SSadaf Ebrahimi
518*62c56f98SSadaf Ebrahimi exit:
519*62c56f98SSadaf Ebrahimi if (status == PSA_SUCCESS) {
520*62c56f98SSadaf Ebrahimi status = mbedtls_psa_cipher_abort(&operation);
521*62c56f98SSadaf Ebrahimi } else {
522*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_abort(&operation);
523*62c56f98SSadaf Ebrahimi }
524*62c56f98SSadaf Ebrahimi
525*62c56f98SSadaf Ebrahimi return status;
526*62c56f98SSadaf Ebrahimi }
527*62c56f98SSadaf Ebrahimi
mbedtls_psa_cipher_decrypt(const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg,const uint8_t * input,size_t input_length,uint8_t * output,size_t output_size,size_t * output_length)528*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_psa_cipher_decrypt(
529*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *attributes,
530*62c56f98SSadaf Ebrahimi const uint8_t *key_buffer,
531*62c56f98SSadaf Ebrahimi size_t key_buffer_size,
532*62c56f98SSadaf Ebrahimi psa_algorithm_t alg,
533*62c56f98SSadaf Ebrahimi const uint8_t *input,
534*62c56f98SSadaf Ebrahimi size_t input_length,
535*62c56f98SSadaf Ebrahimi uint8_t *output,
536*62c56f98SSadaf Ebrahimi size_t output_size,
537*62c56f98SSadaf Ebrahimi size_t *output_length)
538*62c56f98SSadaf Ebrahimi {
539*62c56f98SSadaf Ebrahimi psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
540*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
541*62c56f98SSadaf Ebrahimi size_t olength, accumulated_length;
542*62c56f98SSadaf Ebrahimi
543*62c56f98SSadaf Ebrahimi status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
544*62c56f98SSadaf Ebrahimi key_buffer, key_buffer_size,
545*62c56f98SSadaf Ebrahimi alg);
546*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
547*62c56f98SSadaf Ebrahimi goto exit;
548*62c56f98SSadaf Ebrahimi }
549*62c56f98SSadaf Ebrahimi
550*62c56f98SSadaf Ebrahimi if (operation.iv_length > 0) {
551*62c56f98SSadaf Ebrahimi status = mbedtls_psa_cipher_set_iv(&operation,
552*62c56f98SSadaf Ebrahimi input, operation.iv_length);
553*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
554*62c56f98SSadaf Ebrahimi goto exit;
555*62c56f98SSadaf Ebrahimi }
556*62c56f98SSadaf Ebrahimi }
557*62c56f98SSadaf Ebrahimi
558*62c56f98SSadaf Ebrahimi status = mbedtls_psa_cipher_update(
559*62c56f98SSadaf Ebrahimi &operation,
560*62c56f98SSadaf Ebrahimi mbedtls_buffer_offset_const(input, operation.iv_length),
561*62c56f98SSadaf Ebrahimi input_length - operation.iv_length,
562*62c56f98SSadaf Ebrahimi output, output_size, &olength);
563*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
564*62c56f98SSadaf Ebrahimi goto exit;
565*62c56f98SSadaf Ebrahimi }
566*62c56f98SSadaf Ebrahimi
567*62c56f98SSadaf Ebrahimi accumulated_length = olength;
568*62c56f98SSadaf Ebrahimi
569*62c56f98SSadaf Ebrahimi status = mbedtls_psa_cipher_finish(
570*62c56f98SSadaf Ebrahimi &operation,
571*62c56f98SSadaf Ebrahimi mbedtls_buffer_offset(output, accumulated_length),
572*62c56f98SSadaf Ebrahimi output_size - accumulated_length, &olength);
573*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
574*62c56f98SSadaf Ebrahimi goto exit;
575*62c56f98SSadaf Ebrahimi }
576*62c56f98SSadaf Ebrahimi
577*62c56f98SSadaf Ebrahimi *output_length = accumulated_length + olength;
578*62c56f98SSadaf Ebrahimi
579*62c56f98SSadaf Ebrahimi exit:
580*62c56f98SSadaf Ebrahimi if (status == PSA_SUCCESS) {
581*62c56f98SSadaf Ebrahimi status = mbedtls_psa_cipher_abort(&operation);
582*62c56f98SSadaf Ebrahimi } else {
583*62c56f98SSadaf Ebrahimi mbedtls_psa_cipher_abort(&operation);
584*62c56f98SSadaf Ebrahimi }
585*62c56f98SSadaf Ebrahimi
586*62c56f98SSadaf Ebrahimi return status;
587*62c56f98SSadaf Ebrahimi }
588*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
589*62c56f98SSadaf Ebrahimi
590*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_CRYPTO_C */
591