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_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
72 mode = MBEDTLS_MODE_CCM;
73 break;
74 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
75 mode = MBEDTLS_MODE_GCM;
76 break;
77 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
78 mode = MBEDTLS_MODE_CHACHAPOLY;
79 break;
80 default:
81 return( NULL );
82 }
83 }
84 else if( alg == PSA_ALG_CMAC )
85 mode = MBEDTLS_MODE_ECB;
86 else
87 return( NULL );
88
89 switch( key_type )
90 {
91 case PSA_KEY_TYPE_AES:
92 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
93 break;
94 case PSA_KEY_TYPE_ARIA:
95 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
96 break;
97 case PSA_KEY_TYPE_DES:
98 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
99 * and 192 for three-key Triple-DES. */
100 if( key_bits == 64 )
101 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
102 else
103 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
104 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
105 * but two-key Triple-DES is functionally three-key Triple-DES
106 * with K1=K3, so that's how we present it to mbedtls. */
107 if( key_bits == 128 )
108 key_bits = 192;
109 break;
110 case PSA_KEY_TYPE_CAMELLIA:
111 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
112 break;
113 case PSA_KEY_TYPE_ARC4:
114 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
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( const psa_key_attributes_t *attributes,
448 const uint8_t *key_buffer,
449 size_t key_buffer_size,
450 psa_algorithm_t alg,
451 const uint8_t *iv,
452 size_t iv_length,
453 const uint8_t *input,
454 size_t input_length,
455 uint8_t *output,
456 size_t output_size,
457 size_t *output_length )
458 {
459 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
460 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
461 size_t update_output_length, finish_output_length;
462
463 status = mbedtls_psa_cipher_encrypt_setup( &operation, attributes,
464 key_buffer, key_buffer_size,
465 alg );
466 if( status != PSA_SUCCESS )
467 goto exit;
468
469 if( iv_length > 0 )
470 {
471 status = mbedtls_psa_cipher_set_iv( &operation, iv, iv_length );
472 if( status != PSA_SUCCESS )
473 goto exit;
474 }
475
476 status = mbedtls_psa_cipher_update( &operation, input, input_length,
477 output, output_size, &update_output_length );
478 if( status != PSA_SUCCESS )
479 goto exit;
480
481 status = mbedtls_psa_cipher_finish( &operation, output + update_output_length,
482 output_size - update_output_length,
483 &finish_output_length );
484 if( status != PSA_SUCCESS )
485 goto exit;
486
487 *output_length = update_output_length + finish_output_length;
488
489 exit:
490 if( status == PSA_SUCCESS )
491 status = mbedtls_psa_cipher_abort( &operation );
492 else
493 mbedtls_psa_cipher_abort( &operation );
494
495 return( status );
496 }
497
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)498 psa_status_t mbedtls_psa_cipher_decrypt(
499 const psa_key_attributes_t *attributes,
500 const uint8_t *key_buffer,
501 size_t key_buffer_size,
502 psa_algorithm_t alg,
503 const uint8_t *input,
504 size_t input_length,
505 uint8_t *output,
506 size_t output_size,
507 size_t *output_length )
508 {
509 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
510 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
511 size_t olength, accumulated_length;
512
513 status = mbedtls_psa_cipher_decrypt_setup( &operation, attributes,
514 key_buffer, key_buffer_size,
515 alg );
516 if( status != PSA_SUCCESS )
517 goto exit;
518
519 if( operation.iv_length > 0 )
520 {
521 status = mbedtls_psa_cipher_set_iv( &operation,
522 input, operation.iv_length );
523 if( status != PSA_SUCCESS )
524 goto exit;
525 }
526
527 status = mbedtls_psa_cipher_update( &operation, input + operation.iv_length,
528 input_length - operation.iv_length,
529 output, output_size, &olength );
530 if( status != PSA_SUCCESS )
531 goto exit;
532
533 accumulated_length = olength;
534
535 status = mbedtls_psa_cipher_finish( &operation, output + accumulated_length,
536 output_size - accumulated_length,
537 &olength );
538 if( status != PSA_SUCCESS )
539 goto exit;
540
541 *output_length = accumulated_length + olength;
542
543 exit:
544 if ( status == PSA_SUCCESS )
545 status = mbedtls_psa_cipher_abort( &operation );
546 else
547 mbedtls_psa_cipher_abort( &operation );
548
549 return( status );
550 }
551 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
552
553 #endif /* MBEDTLS_PSA_CRYPTO_C */
554