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_STAR_NO_TAG)
73 case PSA_ALG_CCM_STAR_NO_TAG:
74 mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
75 break;
76 #endif
77 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
78 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
79 mode = MBEDTLS_MODE_CCM;
80 break;
81 #endif
82 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
83 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
84 mode = MBEDTLS_MODE_GCM;
85 break;
86 #endif
87 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
88 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
89 mode = MBEDTLS_MODE_CHACHAPOLY;
90 break;
91 #endif
92 default:
93 return NULL;
94 }
95 } else if (alg == PSA_ALG_CMAC) {
96 mode = MBEDTLS_MODE_ECB;
97 } else {
98 return NULL;
99 }
100
101 switch (key_type) {
102 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
103 case PSA_KEY_TYPE_AES:
104 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
105 break;
106 #endif
107 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
108 case PSA_KEY_TYPE_ARIA:
109 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
110 break;
111 #endif
112 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
113 case PSA_KEY_TYPE_DES:
114 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
115 * and 192 for three-key Triple-DES. */
116 if (key_bits == 64) {
117 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
118 } else {
119 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
120 }
121 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
122 * but two-key Triple-DES is functionally three-key Triple-DES
123 * with K1=K3, so that's how we present it to mbedtls. */
124 if (key_bits == 128) {
125 key_bits = 192;
126 }
127 break;
128 #endif
129 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
130 case PSA_KEY_TYPE_CAMELLIA:
131 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
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 = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
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(
471 const psa_key_attributes_t *attributes,
472 const uint8_t *key_buffer,
473 size_t key_buffer_size,
474 psa_algorithm_t alg,
475 const uint8_t *iv,
476 size_t iv_length,
477 const uint8_t *input,
478 size_t input_length,
479 uint8_t *output,
480 size_t output_size,
481 size_t *output_length)
482 {
483 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
484 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
485 size_t update_output_length, finish_output_length;
486
487 status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
488 key_buffer, key_buffer_size,
489 alg);
490 if (status != PSA_SUCCESS) {
491 goto exit;
492 }
493
494 if (iv_length > 0) {
495 status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
496 if (status != PSA_SUCCESS) {
497 goto exit;
498 }
499 }
500
501 status = mbedtls_psa_cipher_update(&operation, input, input_length,
502 output, output_size,
503 &update_output_length);
504 if (status != PSA_SUCCESS) {
505 goto exit;
506 }
507
508 status = mbedtls_psa_cipher_finish(
509 &operation,
510 mbedtls_buffer_offset(output, update_output_length),
511 output_size - update_output_length, &finish_output_length);
512 if (status != PSA_SUCCESS) {
513 goto exit;
514 }
515
516 *output_length = update_output_length + finish_output_length;
517
518 exit:
519 if (status == PSA_SUCCESS) {
520 status = mbedtls_psa_cipher_abort(&operation);
521 } else {
522 mbedtls_psa_cipher_abort(&operation);
523 }
524
525 return status;
526 }
527
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 psa_status_t mbedtls_psa_cipher_decrypt(
529 const psa_key_attributes_t *attributes,
530 const uint8_t *key_buffer,
531 size_t key_buffer_size,
532 psa_algorithm_t alg,
533 const uint8_t *input,
534 size_t input_length,
535 uint8_t *output,
536 size_t output_size,
537 size_t *output_length)
538 {
539 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
540 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
541 size_t olength, accumulated_length;
542
543 status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
544 key_buffer, key_buffer_size,
545 alg);
546 if (status != PSA_SUCCESS) {
547 goto exit;
548 }
549
550 if (operation.iv_length > 0) {
551 status = mbedtls_psa_cipher_set_iv(&operation,
552 input, operation.iv_length);
553 if (status != PSA_SUCCESS) {
554 goto exit;
555 }
556 }
557
558 status = mbedtls_psa_cipher_update(
559 &operation,
560 mbedtls_buffer_offset_const(input, operation.iv_length),
561 input_length - operation.iv_length,
562 output, output_size, &olength);
563 if (status != PSA_SUCCESS) {
564 goto exit;
565 }
566
567 accumulated_length = olength;
568
569 status = mbedtls_psa_cipher_finish(
570 &operation,
571 mbedtls_buffer_offset(output, accumulated_length),
572 output_size - accumulated_length, &olength);
573 if (status != PSA_SUCCESS) {
574 goto exit;
575 }
576
577 *output_length = accumulated_length + olength;
578
579 exit:
580 if (status == PSA_SUCCESS) {
581 status = mbedtls_psa_cipher_abort(&operation);
582 } else {
583 mbedtls_psa_cipher_abort(&operation);
584 }
585
586 return status;
587 }
588 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
589
590 #endif /* MBEDTLS_PSA_CRYPTO_C */
591