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