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