xref: /reactos/dll/3rdparty/mbedtls/cipher.c (revision cbda039f)
1 /**
2  * \file cipher.c
3  *
4  * \brief Generic cipher wrapper for mbed TLS
5  *
6  * \author Adriaan de Jong <dejong@fox-it.com>
7  *
8  *  Copyright The Mbed TLS Contributors
9  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
10  *
11  *  This file is provided under the Apache License 2.0, or the
12  *  GNU General Public License v2.0 or later.
13  *
14  *  **********
15  *  Apache License 2.0:
16  *
17  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
18  *  not use this file except in compliance with the License.
19  *  You may obtain a copy of the License at
20  *
21  *  http://www.apache.org/licenses/LICENSE-2.0
22  *
23  *  Unless required by applicable law or agreed to in writing, software
24  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
25  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26  *  See the License for the specific language governing permissions and
27  *  limitations under the License.
28  *
29  *  **********
30  *
31  *  **********
32  *  GNU General Public License v2.0 or later:
33  *
34  *  This program is free software; you can redistribute it and/or modify
35  *  it under the terms of the GNU General Public License as published by
36  *  the Free Software Foundation; either version 2 of the License, or
37  *  (at your option) any later version.
38  *
39  *  This program is distributed in the hope that it will be useful,
40  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
41  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42  *  GNU General Public License for more details.
43  *
44  *  You should have received a copy of the GNU General Public License along
45  *  with this program; if not, write to the Free Software Foundation, Inc.,
46  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
47  *
48  *  **********
49  */
50 
51 #if !defined(MBEDTLS_CONFIG_FILE)
52 #include "mbedtls/config.h"
53 #else
54 #include MBEDTLS_CONFIG_FILE
55 #endif
56 
57 #if defined(MBEDTLS_CIPHER_C)
58 
59 #include "mbedtls/cipher.h"
60 #include "mbedtls/cipher_internal.h"
61 #include "mbedtls/platform_util.h"
62 
63 #include <stdlib.h>
64 #include <string.h>
65 
66 #if defined(MBEDTLS_CHACHAPOLY_C)
67 #include "mbedtls/chachapoly.h"
68 #endif
69 
70 #if defined(MBEDTLS_GCM_C)
71 #include "mbedtls/gcm.h"
72 #endif
73 
74 #if defined(MBEDTLS_CCM_C)
75 #include "mbedtls/ccm.h"
76 #endif
77 
78 #if defined(MBEDTLS_CHACHA20_C)
79 #include "mbedtls/chacha20.h"
80 #endif
81 
82 #if defined(MBEDTLS_CMAC_C)
83 #include "mbedtls/cmac.h"
84 #endif
85 
86 #if defined(MBEDTLS_PLATFORM_C)
87 #include "mbedtls/platform.h"
88 #else
89 #define mbedtls_calloc calloc
90 #define mbedtls_free   free
91 #endif
92 
93 #define CIPHER_VALIDATE_RET( cond )    \
94     MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
95 #define CIPHER_VALIDATE( cond )        \
96     MBEDTLS_INTERNAL_VALIDATE( cond )
97 
98 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
99 /* Compare the contents of two buffers in constant time.
100  * Returns 0 if the contents are bitwise identical, otherwise returns
101  * a non-zero value.
102  * This is currently only used by GCM and ChaCha20+Poly1305.
103  */
mbedtls_constant_time_memcmp(const void * v1,const void * v2,size_t len)104 static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len )
105 {
106     const unsigned char *p1 = (const unsigned char*) v1;
107     const unsigned char *p2 = (const unsigned char*) v2;
108     size_t i;
109     unsigned char diff;
110 
111     for( diff = 0, i = 0; i < len; i++ )
112         diff |= p1[i] ^ p2[i];
113 
114     return( (int)diff );
115 }
116 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
117 
118 static int supported_init = 0;
119 
mbedtls_cipher_list(void)120 const int *mbedtls_cipher_list( void )
121 {
122     const mbedtls_cipher_definition_t *def;
123     int *type;
124 
125     if( ! supported_init )
126     {
127         def = mbedtls_cipher_definitions;
128         type = mbedtls_cipher_supported;
129 
130         while( def->type != 0 )
131             *type++ = (*def++).type;
132 
133         *type = 0;
134 
135         supported_init = 1;
136     }
137 
138     return( mbedtls_cipher_supported );
139 }
140 
mbedtls_cipher_info_from_type(const mbedtls_cipher_type_t cipher_type)141 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type )
142 {
143     const mbedtls_cipher_definition_t *def;
144 
145     for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
146         if( def->type == cipher_type )
147             return( def->info );
148 
149     return( NULL );
150 }
151 
mbedtls_cipher_info_from_string(const char * cipher_name)152 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name )
153 {
154     const mbedtls_cipher_definition_t *def;
155 
156     if( NULL == cipher_name )
157         return( NULL );
158 
159     for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
160         if( !  strcmp( def->info->name, cipher_name ) )
161             return( def->info );
162 
163     return( NULL );
164 }
165 
mbedtls_cipher_info_from_values(const mbedtls_cipher_id_t cipher_id,int key_bitlen,const mbedtls_cipher_mode_t mode)166 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
167                                               int key_bitlen,
168                                               const mbedtls_cipher_mode_t mode )
169 {
170     const mbedtls_cipher_definition_t *def;
171 
172     for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
173         if( def->info->base->cipher == cipher_id &&
174             def->info->key_bitlen == (unsigned) key_bitlen &&
175             def->info->mode == mode )
176             return( def->info );
177 
178     return( NULL );
179 }
180 
mbedtls_cipher_init(mbedtls_cipher_context_t * ctx)181 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
182 {
183     CIPHER_VALIDATE( ctx != NULL );
184     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
185 }
186 
mbedtls_cipher_free(mbedtls_cipher_context_t * ctx)187 void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
188 {
189     if( ctx == NULL )
190         return;
191 
192 #if defined(MBEDTLS_CMAC_C)
193     if( ctx->cmac_ctx )
194     {
195        mbedtls_platform_zeroize( ctx->cmac_ctx,
196                                  sizeof( mbedtls_cmac_context_t ) );
197        mbedtls_free( ctx->cmac_ctx );
198     }
199 #endif
200 
201     if( ctx->cipher_ctx )
202         ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
203 
204     mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
205 }
206 
mbedtls_cipher_setup(mbedtls_cipher_context_t * ctx,const mbedtls_cipher_info_t * cipher_info)207 int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
208 {
209     CIPHER_VALIDATE_RET( ctx != NULL );
210     if( cipher_info == NULL )
211         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
212 
213     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
214 
215     if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
216         return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
217 
218     ctx->cipher_info = cipher_info;
219 
220 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
221     /*
222      * Ignore possible errors caused by a cipher mode that doesn't use padding
223      */
224 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
225     (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
226 #else
227     (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
228 #endif
229 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
230 
231     return( 0 );
232 }
233 
mbedtls_cipher_setkey(mbedtls_cipher_context_t * ctx,const unsigned char * key,int key_bitlen,const mbedtls_operation_t operation)234 int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
235                            const unsigned char *key,
236                            int key_bitlen,
237                            const mbedtls_operation_t operation )
238 {
239     CIPHER_VALIDATE_RET( ctx != NULL );
240     CIPHER_VALIDATE_RET( key != NULL );
241     CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
242                          operation == MBEDTLS_DECRYPT );
243     if( ctx->cipher_info == NULL )
244         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
245 
246     if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
247         (int) ctx->cipher_info->key_bitlen != key_bitlen )
248     {
249         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
250     }
251 
252     ctx->key_bitlen = key_bitlen;
253     ctx->operation = operation;
254 
255     /*
256      * For OFB, CFB and CTR mode always use the encryption key schedule
257      */
258     if( MBEDTLS_ENCRYPT == operation ||
259         MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
260         MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
261         MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
262     {
263         return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
264                                                          ctx->key_bitlen ) );
265     }
266 
267     if( MBEDTLS_DECRYPT == operation )
268         return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
269                                                          ctx->key_bitlen ) );
270 
271     return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
272 }
273 
mbedtls_cipher_set_iv(mbedtls_cipher_context_t * ctx,const unsigned char * iv,size_t iv_len)274 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
275                            const unsigned char *iv,
276                            size_t iv_len )
277 {
278     size_t actual_iv_size;
279 
280     CIPHER_VALIDATE_RET( ctx != NULL );
281     CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
282     if( ctx->cipher_info == NULL )
283         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
284 
285     /* avoid buffer overflow in ctx->iv */
286     if( iv_len > MBEDTLS_MAX_IV_LENGTH )
287         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
288 
289     if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
290         actual_iv_size = iv_len;
291     else
292     {
293         actual_iv_size = ctx->cipher_info->iv_size;
294 
295         /* avoid reading past the end of input buffer */
296         if( actual_iv_size > iv_len )
297             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
298     }
299 
300 #if defined(MBEDTLS_CHACHA20_C)
301     if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
302     {
303         if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
304                                            iv,
305                                            0U ) ) /* Initial counter value */
306         {
307             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
308         }
309     }
310 #endif
311 
312     if ( actual_iv_size != 0 )
313     {
314         memcpy( ctx->iv, iv, actual_iv_size );
315         ctx->iv_size = actual_iv_size;
316     }
317 
318     return( 0 );
319 }
320 
mbedtls_cipher_reset(mbedtls_cipher_context_t * ctx)321 int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
322 {
323     CIPHER_VALIDATE_RET( ctx != NULL );
324     if( ctx->cipher_info == NULL )
325         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
326 
327     ctx->unprocessed_len = 0;
328 
329     return( 0 );
330 }
331 
332 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
mbedtls_cipher_update_ad(mbedtls_cipher_context_t * ctx,const unsigned char * ad,size_t ad_len)333 int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
334                       const unsigned char *ad, size_t ad_len )
335 {
336     CIPHER_VALIDATE_RET( ctx != NULL );
337     CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
338     if( ctx->cipher_info == NULL )
339         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
340 
341 #if defined(MBEDTLS_GCM_C)
342     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
343     {
344         return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
345                                     ctx->iv, ctx->iv_size, ad, ad_len ) );
346     }
347 #endif
348 
349 #if defined(MBEDTLS_CHACHAPOLY_C)
350     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
351     {
352         int result;
353         mbedtls_chachapoly_mode_t mode;
354 
355         mode = ( ctx->operation == MBEDTLS_ENCRYPT )
356                 ? MBEDTLS_CHACHAPOLY_ENCRYPT
357                 : MBEDTLS_CHACHAPOLY_DECRYPT;
358 
359         result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
360                                                         ctx->iv,
361                                                         mode );
362         if ( result != 0 )
363             return( result );
364 
365         return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
366                                                ad, ad_len ) );
367     }
368 #endif
369 
370     return( 0 );
371 }
372 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
373 
mbedtls_cipher_update(mbedtls_cipher_context_t * ctx,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen)374 int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
375                    size_t ilen, unsigned char *output, size_t *olen )
376 {
377     int ret;
378     size_t block_size;
379 
380     CIPHER_VALIDATE_RET( ctx != NULL );
381     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
382     CIPHER_VALIDATE_RET( output != NULL );
383     CIPHER_VALIDATE_RET( olen != NULL );
384     if( ctx->cipher_info == NULL )
385         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
386 
387     *olen = 0;
388     block_size = mbedtls_cipher_get_block_size( ctx );
389     if ( 0 == block_size )
390     {
391         return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
392     }
393 
394     if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
395     {
396         if( ilen != block_size )
397             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
398 
399         *olen = ilen;
400 
401         if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
402                     ctx->operation, input, output ) ) )
403         {
404             return( ret );
405         }
406 
407         return( 0 );
408     }
409 
410 #if defined(MBEDTLS_GCM_C)
411     if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
412     {
413         *olen = ilen;
414         return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
415                                     output ) );
416     }
417 #endif
418 
419 #if defined(MBEDTLS_CHACHAPOLY_C)
420     if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
421     {
422         *olen = ilen;
423         return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
424                                            ilen, input, output ) );
425     }
426 #endif
427 
428     if( input == output &&
429        ( ctx->unprocessed_len != 0 || ilen % block_size ) )
430     {
431         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
432     }
433 
434 #if defined(MBEDTLS_CIPHER_MODE_CBC)
435     if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
436     {
437         size_t copy_len = 0;
438 
439         /*
440          * If there is not enough data for a full block, cache it.
441          */
442         if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
443                 ilen <= block_size - ctx->unprocessed_len ) ||
444             ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
445                 ilen < block_size - ctx->unprocessed_len ) ||
446              ( ctx->operation == MBEDTLS_ENCRYPT &&
447                 ilen < block_size - ctx->unprocessed_len ) )
448         {
449             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
450                     ilen );
451 
452             ctx->unprocessed_len += ilen;
453             return( 0 );
454         }
455 
456         /*
457          * Process cached data first
458          */
459         if( 0 != ctx->unprocessed_len )
460         {
461             copy_len = block_size - ctx->unprocessed_len;
462 
463             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
464                     copy_len );
465 
466             if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
467                     ctx->operation, block_size, ctx->iv,
468                     ctx->unprocessed_data, output ) ) )
469             {
470                 return( ret );
471             }
472 
473             *olen += block_size;
474             output += block_size;
475             ctx->unprocessed_len = 0;
476 
477             input += copy_len;
478             ilen -= copy_len;
479         }
480 
481         /*
482          * Cache final, incomplete block
483          */
484         if( 0 != ilen )
485         {
486             /* Encryption: only cache partial blocks
487              * Decryption w/ padding: always keep at least one whole block
488              * Decryption w/o padding: only cache partial blocks
489              */
490             copy_len = ilen % block_size;
491             if( copy_len == 0 &&
492                 ctx->operation == MBEDTLS_DECRYPT &&
493                 NULL != ctx->add_padding)
494             {
495                 copy_len = block_size;
496             }
497 
498             memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
499                     copy_len );
500 
501             ctx->unprocessed_len += copy_len;
502             ilen -= copy_len;
503         }
504 
505         /*
506          * Process remaining full blocks
507          */
508         if( ilen )
509         {
510             if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
511                     ctx->operation, ilen, ctx->iv, input, output ) ) )
512             {
513                 return( ret );
514             }
515 
516             *olen += ilen;
517         }
518 
519         return( 0 );
520     }
521 #endif /* MBEDTLS_CIPHER_MODE_CBC */
522 
523 #if defined(MBEDTLS_CIPHER_MODE_CFB)
524     if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
525     {
526         if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
527                 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
528                 input, output ) ) )
529         {
530             return( ret );
531         }
532 
533         *olen = ilen;
534 
535         return( 0 );
536     }
537 #endif /* MBEDTLS_CIPHER_MODE_CFB */
538 
539 #if defined(MBEDTLS_CIPHER_MODE_OFB)
540     if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
541     {
542         if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
543                 ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
544         {
545             return( ret );
546         }
547 
548         *olen = ilen;
549 
550         return( 0 );
551     }
552 #endif /* MBEDTLS_CIPHER_MODE_OFB */
553 
554 #if defined(MBEDTLS_CIPHER_MODE_CTR)
555     if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
556     {
557         if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
558                 ilen, &ctx->unprocessed_len, ctx->iv,
559                 ctx->unprocessed_data, input, output ) ) )
560         {
561             return( ret );
562         }
563 
564         *olen = ilen;
565 
566         return( 0 );
567     }
568 #endif /* MBEDTLS_CIPHER_MODE_CTR */
569 
570 #if defined(MBEDTLS_CIPHER_MODE_XTS)
571     if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
572     {
573         if( ctx->unprocessed_len > 0 ) {
574             /* We can only process an entire data unit at a time. */
575             return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
576         }
577 
578         ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
579                 ctx->operation, ilen, ctx->iv, input, output );
580         if( ret != 0 )
581         {
582             return( ret );
583         }
584 
585         *olen = ilen;
586 
587         return( 0 );
588     }
589 #endif /* MBEDTLS_CIPHER_MODE_XTS */
590 
591 #if defined(MBEDTLS_CIPHER_MODE_STREAM)
592     if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
593     {
594         if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
595                                                     ilen, input, output ) ) )
596         {
597             return( ret );
598         }
599 
600         *olen = ilen;
601 
602         return( 0 );
603     }
604 #endif /* MBEDTLS_CIPHER_MODE_STREAM */
605 
606     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
607 }
608 
609 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
610 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
611 /*
612  * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
613  */
add_pkcs_padding(unsigned char * output,size_t output_len,size_t data_len)614 static void add_pkcs_padding( unsigned char *output, size_t output_len,
615         size_t data_len )
616 {
617     size_t padding_len = output_len - data_len;
618     unsigned char i;
619 
620     for( i = 0; i < padding_len; i++ )
621         output[data_len + i] = (unsigned char) padding_len;
622 }
623 
get_pkcs_padding(unsigned char * input,size_t input_len,size_t * data_len)624 static int get_pkcs_padding( unsigned char *input, size_t input_len,
625         size_t *data_len )
626 {
627     size_t i, pad_idx;
628     unsigned char padding_len, bad = 0;
629 
630     if( NULL == input || NULL == data_len )
631         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
632 
633     padding_len = input[input_len - 1];
634     *data_len = input_len - padding_len;
635 
636     /* Avoid logical || since it results in a branch */
637     bad |= padding_len > input_len;
638     bad |= padding_len == 0;
639 
640     /* The number of bytes checked must be independent of padding_len,
641      * so pick input_len, which is usually 8 or 16 (one block) */
642     pad_idx = input_len - padding_len;
643     for( i = 0; i < input_len; i++ )
644         bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
645 
646     return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
647 }
648 #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
649 
650 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
651 /*
652  * One and zeros padding: fill with 80 00 ... 00
653  */
add_one_and_zeros_padding(unsigned char * output,size_t output_len,size_t data_len)654 static void add_one_and_zeros_padding( unsigned char *output,
655                                        size_t output_len, size_t data_len )
656 {
657     size_t padding_len = output_len - data_len;
658     unsigned char i = 0;
659 
660     output[data_len] = 0x80;
661     for( i = 1; i < padding_len; i++ )
662         output[data_len + i] = 0x00;
663 }
664 
get_one_and_zeros_padding(unsigned char * input,size_t input_len,size_t * data_len)665 static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
666                                       size_t *data_len )
667 {
668     size_t i;
669     unsigned char done = 0, prev_done, bad;
670 
671     if( NULL == input || NULL == data_len )
672         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
673 
674     bad = 0x80;
675     *data_len = 0;
676     for( i = input_len; i > 0; i-- )
677     {
678         prev_done = done;
679         done |= ( input[i - 1] != 0 );
680         *data_len |= ( i - 1 ) * ( done != prev_done );
681         bad ^= input[i - 1] * ( done != prev_done );
682     }
683 
684     return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
685 
686 }
687 #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
688 
689 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
690 /*
691  * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
692  */
add_zeros_and_len_padding(unsigned char * output,size_t output_len,size_t data_len)693 static void add_zeros_and_len_padding( unsigned char *output,
694                                        size_t output_len, size_t data_len )
695 {
696     size_t padding_len = output_len - data_len;
697     unsigned char i = 0;
698 
699     for( i = 1; i < padding_len; i++ )
700         output[data_len + i - 1] = 0x00;
701     output[output_len - 1] = (unsigned char) padding_len;
702 }
703 
get_zeros_and_len_padding(unsigned char * input,size_t input_len,size_t * data_len)704 static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
705                                       size_t *data_len )
706 {
707     size_t i, pad_idx;
708     unsigned char padding_len, bad = 0;
709 
710     if( NULL == input || NULL == data_len )
711         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
712 
713     padding_len = input[input_len - 1];
714     *data_len = input_len - padding_len;
715 
716     /* Avoid logical || since it results in a branch */
717     bad |= padding_len > input_len;
718     bad |= padding_len == 0;
719 
720     /* The number of bytes checked must be independent of padding_len */
721     pad_idx = input_len - padding_len;
722     for( i = 0; i < input_len - 1; i++ )
723         bad |= input[i] * ( i >= pad_idx );
724 
725     return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
726 }
727 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
728 
729 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
730 /*
731  * Zero padding: fill with 00 ... 00
732  */
add_zeros_padding(unsigned char * output,size_t output_len,size_t data_len)733 static void add_zeros_padding( unsigned char *output,
734                                size_t output_len, size_t data_len )
735 {
736     size_t i;
737 
738     for( i = data_len; i < output_len; i++ )
739         output[i] = 0x00;
740 }
741 
get_zeros_padding(unsigned char * input,size_t input_len,size_t * data_len)742 static int get_zeros_padding( unsigned char *input, size_t input_len,
743                               size_t *data_len )
744 {
745     size_t i;
746     unsigned char done = 0, prev_done;
747 
748     if( NULL == input || NULL == data_len )
749         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
750 
751     *data_len = 0;
752     for( i = input_len; i > 0; i-- )
753     {
754         prev_done = done;
755         done |= ( input[i-1] != 0 );
756         *data_len |= i * ( done != prev_done );
757     }
758 
759     return( 0 );
760 }
761 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
762 
763 /*
764  * No padding: don't pad :)
765  *
766  * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
767  * but a trivial get_padding function
768  */
get_no_padding(unsigned char * input,size_t input_len,size_t * data_len)769 static int get_no_padding( unsigned char *input, size_t input_len,
770                               size_t *data_len )
771 {
772     if( NULL == input || NULL == data_len )
773         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
774 
775     *data_len = input_len;
776 
777     return( 0 );
778 }
779 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
780 
mbedtls_cipher_finish(mbedtls_cipher_context_t * ctx,unsigned char * output,size_t * olen)781 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
782                    unsigned char *output, size_t *olen )
783 {
784     CIPHER_VALIDATE_RET( ctx != NULL );
785     CIPHER_VALIDATE_RET( output != NULL );
786     CIPHER_VALIDATE_RET( olen != NULL );
787     if( ctx->cipher_info == NULL )
788         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
789 
790     *olen = 0;
791 
792     if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
793         MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
794         MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
795         MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
796         MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
797         MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
798     {
799         return( 0 );
800     }
801 
802     if ( ( MBEDTLS_CIPHER_CHACHA20          == ctx->cipher_info->type ) ||
803          ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
804     {
805         return( 0 );
806     }
807 
808     if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
809     {
810         if( ctx->unprocessed_len != 0 )
811             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
812 
813         return( 0 );
814     }
815 
816 #if defined(MBEDTLS_CIPHER_MODE_CBC)
817     if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
818     {
819         int ret = 0;
820 
821         if( MBEDTLS_ENCRYPT == ctx->operation )
822         {
823             /* check for 'no padding' mode */
824             if( NULL == ctx->add_padding )
825             {
826                 if( 0 != ctx->unprocessed_len )
827                     return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
828 
829                 return( 0 );
830             }
831 
832             ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
833                     ctx->unprocessed_len );
834         }
835         else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
836         {
837             /*
838              * For decrypt operations, expect a full block,
839              * or an empty block if no padding
840              */
841             if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
842                 return( 0 );
843 
844             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
845         }
846 
847         /* cipher block */
848         if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
849                 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
850                 ctx->unprocessed_data, output ) ) )
851         {
852             return( ret );
853         }
854 
855         /* Set output size for decryption */
856         if( MBEDTLS_DECRYPT == ctx->operation )
857             return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
858                                       olen ) );
859 
860         /* Set output size for encryption */
861         *olen = mbedtls_cipher_get_block_size( ctx );
862         return( 0 );
863     }
864 #else
865     ((void) output);
866 #endif /* MBEDTLS_CIPHER_MODE_CBC */
867 
868     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
869 }
870 
871 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t * ctx,mbedtls_cipher_padding_t mode)872 int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
873                                      mbedtls_cipher_padding_t mode )
874 {
875     CIPHER_VALIDATE_RET( ctx != NULL );
876 
877     if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
878     {
879         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
880     }
881 
882     switch( mode )
883     {
884 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
885     case MBEDTLS_PADDING_PKCS7:
886         ctx->add_padding = add_pkcs_padding;
887         ctx->get_padding = get_pkcs_padding;
888         break;
889 #endif
890 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
891     case MBEDTLS_PADDING_ONE_AND_ZEROS:
892         ctx->add_padding = add_one_and_zeros_padding;
893         ctx->get_padding = get_one_and_zeros_padding;
894         break;
895 #endif
896 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
897     case MBEDTLS_PADDING_ZEROS_AND_LEN:
898         ctx->add_padding = add_zeros_and_len_padding;
899         ctx->get_padding = get_zeros_and_len_padding;
900         break;
901 #endif
902 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
903     case MBEDTLS_PADDING_ZEROS:
904         ctx->add_padding = add_zeros_padding;
905         ctx->get_padding = get_zeros_padding;
906         break;
907 #endif
908     case MBEDTLS_PADDING_NONE:
909         ctx->add_padding = NULL;
910         ctx->get_padding = get_no_padding;
911         break;
912 
913     default:
914         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
915     }
916 
917     return( 0 );
918 }
919 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
920 
921 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
mbedtls_cipher_write_tag(mbedtls_cipher_context_t * ctx,unsigned char * tag,size_t tag_len)922 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
923                       unsigned char *tag, size_t tag_len )
924 {
925     CIPHER_VALIDATE_RET( ctx != NULL );
926     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
927     if( ctx->cipher_info == NULL )
928         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
929 
930     if( MBEDTLS_ENCRYPT != ctx->operation )
931         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
932 
933 #if defined(MBEDTLS_GCM_C)
934     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
935         return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
936                                     tag, tag_len ) );
937 #endif
938 
939 #if defined(MBEDTLS_CHACHAPOLY_C)
940     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
941     {
942         /* Don't allow truncated MAC for Poly1305 */
943         if ( tag_len != 16U )
944             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
945 
946         return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
947                                            tag ) );
948     }
949 #endif
950 
951     return( 0 );
952 }
953 
mbedtls_cipher_check_tag(mbedtls_cipher_context_t * ctx,const unsigned char * tag,size_t tag_len)954 int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
955                       const unsigned char *tag, size_t tag_len )
956 {
957     unsigned char check_tag[16];
958     int ret;
959 
960     CIPHER_VALIDATE_RET( ctx != NULL );
961     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
962     if( ctx->cipher_info == NULL )
963         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
964 
965     if( MBEDTLS_DECRYPT != ctx->operation )
966     {
967         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
968     }
969 
970 #if defined(MBEDTLS_GCM_C)
971     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
972     {
973         if( tag_len > sizeof( check_tag ) )
974             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
975 
976         if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
977                                      check_tag, tag_len ) ) )
978         {
979             return( ret );
980         }
981 
982         /* Check the tag in "constant-time" */
983         if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
984             return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
985 
986         return( 0 );
987     }
988 #endif /* MBEDTLS_GCM_C */
989 
990 #if defined(MBEDTLS_CHACHAPOLY_C)
991     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
992     {
993         /* Don't allow truncated MAC for Poly1305 */
994         if ( tag_len != sizeof( check_tag ) )
995             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
996 
997         ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
998                                                      check_tag );
999         if ( ret != 0 )
1000         {
1001             return( ret );
1002         }
1003 
1004         /* Check the tag in "constant-time" */
1005         if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
1006             return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
1007 
1008         return( 0 );
1009     }
1010 #endif /* MBEDTLS_CHACHAPOLY_C */
1011 
1012     return( 0 );
1013 }
1014 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
1015 
1016 /*
1017  * Packet-oriented wrapper for non-AEAD modes
1018  */
mbedtls_cipher_crypt(mbedtls_cipher_context_t * ctx,const unsigned char * iv,size_t iv_len,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen)1019 int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
1020                   const unsigned char *iv, size_t iv_len,
1021                   const unsigned char *input, size_t ilen,
1022                   unsigned char *output, size_t *olen )
1023 {
1024     int ret;
1025     size_t finish_olen;
1026 
1027     CIPHER_VALIDATE_RET( ctx != NULL );
1028     CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
1029     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
1030     CIPHER_VALIDATE_RET( output != NULL );
1031     CIPHER_VALIDATE_RET( olen != NULL );
1032 
1033     if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
1034         return( ret );
1035 
1036     if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
1037         return( ret );
1038 
1039     if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 )
1040         return( ret );
1041 
1042     if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 )
1043         return( ret );
1044 
1045     *olen += finish_olen;
1046 
1047     return( 0 );
1048 }
1049 
1050 #if defined(MBEDTLS_CIPHER_MODE_AEAD)
1051 /*
1052  * Packet-oriented encryption for AEAD modes
1053  */
mbedtls_cipher_auth_encrypt(mbedtls_cipher_context_t * ctx,const unsigned char * iv,size_t iv_len,const unsigned char * ad,size_t ad_len,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,unsigned char * tag,size_t tag_len)1054 int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
1055                          const unsigned char *iv, size_t iv_len,
1056                          const unsigned char *ad, size_t ad_len,
1057                          const unsigned char *input, size_t ilen,
1058                          unsigned char *output, size_t *olen,
1059                          unsigned char *tag, size_t tag_len )
1060 {
1061     CIPHER_VALIDATE_RET( ctx != NULL );
1062     CIPHER_VALIDATE_RET( iv != NULL );
1063     CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
1064     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
1065     CIPHER_VALIDATE_RET( output != NULL );
1066     CIPHER_VALIDATE_RET( olen != NULL );
1067     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
1068 
1069 #if defined(MBEDTLS_GCM_C)
1070     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
1071     {
1072         *olen = ilen;
1073         return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen,
1074                                    iv, iv_len, ad, ad_len, input, output,
1075                                    tag_len, tag ) );
1076     }
1077 #endif /* MBEDTLS_GCM_C */
1078 #if defined(MBEDTLS_CCM_C)
1079     if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
1080     {
1081         *olen = ilen;
1082         return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
1083                                      iv, iv_len, ad, ad_len, input, output,
1084                                      tag, tag_len ) );
1085     }
1086 #endif /* MBEDTLS_CCM_C */
1087 #if defined(MBEDTLS_CHACHAPOLY_C)
1088     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1089     {
1090         /* ChachaPoly has fixed length nonce and MAC (tag) */
1091         if ( ( iv_len != ctx->cipher_info->iv_size ) ||
1092              ( tag_len != 16U ) )
1093         {
1094             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1095         }
1096 
1097         *olen = ilen;
1098         return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
1099                                 ilen, iv, ad, ad_len, input, output, tag ) );
1100     }
1101 #endif /* MBEDTLS_CHACHAPOLY_C */
1102 
1103     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1104 }
1105 
1106 /*
1107  * Packet-oriented decryption for AEAD modes
1108  */
mbedtls_cipher_auth_decrypt(mbedtls_cipher_context_t * ctx,const unsigned char * iv,size_t iv_len,const unsigned char * ad,size_t ad_len,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,const unsigned char * tag,size_t tag_len)1109 int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
1110                          const unsigned char *iv, size_t iv_len,
1111                          const unsigned char *ad, size_t ad_len,
1112                          const unsigned char *input, size_t ilen,
1113                          unsigned char *output, size_t *olen,
1114                          const unsigned char *tag, size_t tag_len )
1115 {
1116     CIPHER_VALIDATE_RET( ctx != NULL );
1117     CIPHER_VALIDATE_RET( iv != NULL );
1118     CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
1119     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
1120     CIPHER_VALIDATE_RET( output != NULL );
1121     CIPHER_VALIDATE_RET( olen != NULL );
1122     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
1123 
1124 #if defined(MBEDTLS_GCM_C)
1125     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
1126     {
1127         int ret;
1128 
1129         *olen = ilen;
1130         ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
1131                                 iv, iv_len, ad, ad_len,
1132                                 tag, tag_len, input, output );
1133 
1134         if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
1135             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
1136 
1137         return( ret );
1138     }
1139 #endif /* MBEDTLS_GCM_C */
1140 #if defined(MBEDTLS_CCM_C)
1141     if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
1142     {
1143         int ret;
1144 
1145         *olen = ilen;
1146         ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
1147                                 iv, iv_len, ad, ad_len,
1148                                 input, output, tag, tag_len );
1149 
1150         if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
1151             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
1152 
1153         return( ret );
1154     }
1155 #endif /* MBEDTLS_CCM_C */
1156 #if defined(MBEDTLS_CHACHAPOLY_C)
1157     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
1158     {
1159         int ret;
1160 
1161         /* ChachaPoly has fixed length nonce and MAC (tag) */
1162         if ( ( iv_len != ctx->cipher_info->iv_size ) ||
1163              ( tag_len != 16U ) )
1164         {
1165             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
1166         }
1167 
1168         *olen = ilen;
1169         ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
1170                                 iv, ad, ad_len, tag, input, output );
1171 
1172         if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
1173             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
1174 
1175         return( ret );
1176     }
1177 #endif /* MBEDTLS_CHACHAPOLY_C */
1178 
1179     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
1180 }
1181 #endif /* MBEDTLS_CIPHER_MODE_AEAD */
1182 
1183 #endif /* MBEDTLS_CIPHER_C */
1184