• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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