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