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