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