[MBEDTLS]
[reactos.git] / reactos / dll / 3rdparty / mbedtls / cipher.c
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 (C) 2006-2015, ARM Limited, All Rights Reserved
9 * SPDX-License-Identifier: GPL-2.0
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 *
25 * This file is part of mbed TLS (https://tls.mbed.org)
26 */
27
28 #if !defined(MBEDTLS_CONFIG_FILE)
29 #include "mbedtls/config.h"
30 #else
31 #include MBEDTLS_CONFIG_FILE
32 #endif
33
34 #if defined(MBEDTLS_CIPHER_C)
35
36 #include "mbedtls/cipher.h"
37 #include "mbedtls/cipher_internal.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41
42 #if defined(MBEDTLS_GCM_C)
43 #include "mbedtls/gcm.h"
44 #endif
45
46 #if defined(MBEDTLS_CCM_C)
47 #include "mbedtls/ccm.h"
48 #endif
49
50 #if defined(MBEDTLS_CMAC_C)
51 #include "mbedtls/cmac.h"
52 #endif
53
54 #if defined(MBEDTLS_PLATFORM_C)
55 #include "mbedtls/platform.h"
56 #else
57 #define mbedtls_calloc calloc
58 #define mbedtls_free free
59 #endif
60
61 #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
62 #define MBEDTLS_CIPHER_MODE_STREAM
63 #endif
64
65 /* Implementation that should never be optimized out by the compiler */
66 static void mbedtls_zeroize( void *v, size_t n ) {
67 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
68 }
69
70 static int supported_init = 0;
71
72 const int *mbedtls_cipher_list( void )
73 {
74 const mbedtls_cipher_definition_t *def;
75 int *type;
76
77 if( ! supported_init )
78 {
79 def = mbedtls_cipher_definitions;
80 type = mbedtls_cipher_supported;
81
82 while( def->type != 0 )
83 *type++ = (*def++).type;
84
85 *type = 0;
86
87 supported_init = 1;
88 }
89
90 return( mbedtls_cipher_supported );
91 }
92
93 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type )
94 {
95 const mbedtls_cipher_definition_t *def;
96
97 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
98 if( def->type == cipher_type )
99 return( def->info );
100
101 return( NULL );
102 }
103
104 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name )
105 {
106 const mbedtls_cipher_definition_t *def;
107
108 if( NULL == cipher_name )
109 return( NULL );
110
111 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
112 if( ! strcmp( def->info->name, cipher_name ) )
113 return( def->info );
114
115 return( NULL );
116 }
117
118 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
119 int key_bitlen,
120 const mbedtls_cipher_mode_t mode )
121 {
122 const mbedtls_cipher_definition_t *def;
123
124 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
125 if( def->info->base->cipher == cipher_id &&
126 def->info->key_bitlen == (unsigned) key_bitlen &&
127 def->info->mode == mode )
128 return( def->info );
129
130 return( NULL );
131 }
132
133 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
134 {
135 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
136 }
137
138 void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
139 {
140 if( ctx == NULL )
141 return;
142
143 #if defined(MBEDTLS_CMAC_C)
144 if( ctx->cmac_ctx )
145 {
146 mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) );
147 mbedtls_free( ctx->cmac_ctx );
148 }
149 #endif
150
151 if( ctx->cipher_ctx )
152 ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
153
154 mbedtls_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
155 }
156
157 int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
158 {
159 if( NULL == cipher_info || NULL == ctx )
160 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
161
162 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
163
164 if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
165 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
166
167 ctx->cipher_info = cipher_info;
168
169 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
170 /*
171 * Ignore possible errors caused by a cipher mode that doesn't use padding
172 */
173 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
174 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
175 #else
176 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
177 #endif
178 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
179
180 return( 0 );
181 }
182
183 int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
184 int key_bitlen, const mbedtls_operation_t operation )
185 {
186 if( NULL == ctx || NULL == ctx->cipher_info )
187 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
188
189 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
190 (int) ctx->cipher_info->key_bitlen != key_bitlen )
191 {
192 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
193 }
194
195 ctx->key_bitlen = key_bitlen;
196 ctx->operation = operation;
197
198 /*
199 * For CFB and CTR mode always use the encryption key schedule
200 */
201 if( MBEDTLS_ENCRYPT == operation ||
202 MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
203 MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
204 {
205 return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
206 ctx->key_bitlen );
207 }
208
209 if( MBEDTLS_DECRYPT == operation )
210 return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
211 ctx->key_bitlen );
212
213 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
214 }
215
216 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
217 const unsigned char *iv, size_t iv_len )
218 {
219 size_t actual_iv_size;
220
221 if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
222 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
223
224 /* avoid buffer overflow in ctx->iv */
225 if( iv_len > MBEDTLS_MAX_IV_LENGTH )
226 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
227
228 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
229 actual_iv_size = iv_len;
230 else
231 {
232 actual_iv_size = ctx->cipher_info->iv_size;
233
234 /* avoid reading past the end of input buffer */
235 if( actual_iv_size > iv_len )
236 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
237 }
238
239 memcpy( ctx->iv, iv, actual_iv_size );
240 ctx->iv_size = actual_iv_size;
241
242 return( 0 );
243 }
244
245 int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
246 {
247 if( NULL == ctx || NULL == ctx->cipher_info )
248 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
249
250 ctx->unprocessed_len = 0;
251
252 return( 0 );
253 }
254
255 #if defined(MBEDTLS_GCM_C)
256 int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
257 const unsigned char *ad, size_t ad_len )
258 {
259 if( NULL == ctx || NULL == ctx->cipher_info )
260 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
261
262 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
263 {
264 return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
265 ctx->iv, ctx->iv_size, ad, ad_len );
266 }
267
268 return( 0 );
269 }
270 #endif /* MBEDTLS_GCM_C */
271
272 int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
273 size_t ilen, unsigned char *output, size_t *olen )
274 {
275 int ret;
276 size_t block_size = 0;
277
278 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
279 {
280 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
281 }
282
283 *olen = 0;
284 block_size = mbedtls_cipher_get_block_size( ctx );
285
286 if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
287 {
288 if( ilen != block_size )
289 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
290
291 *olen = ilen;
292
293 if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
294 ctx->operation, input, output ) ) )
295 {
296 return( ret );
297 }
298
299 return( 0 );
300 }
301
302 #if defined(MBEDTLS_GCM_C)
303 if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
304 {
305 *olen = ilen;
306 return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
307 output );
308 }
309 #endif
310
311 if ( 0 == block_size )
312 {
313 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
314 }
315
316 if( input == output &&
317 ( ctx->unprocessed_len != 0 || ilen % block_size ) )
318 {
319 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
320 }
321
322 #if defined(MBEDTLS_CIPHER_MODE_CBC)
323 if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
324 {
325 size_t copy_len = 0;
326
327 /*
328 * If there is not enough data for a full block, cache it.
329 */
330 if( ( ctx->operation == MBEDTLS_DECRYPT &&
331 ilen <= block_size - ctx->unprocessed_len ) ||
332 ( ctx->operation == MBEDTLS_ENCRYPT &&
333 ilen < block_size - ctx->unprocessed_len ) )
334 {
335 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
336 ilen );
337
338 ctx->unprocessed_len += ilen;
339 return( 0 );
340 }
341
342 /*
343 * Process cached data first
344 */
345 if( 0 != ctx->unprocessed_len )
346 {
347 copy_len = block_size - ctx->unprocessed_len;
348
349 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
350 copy_len );
351
352 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
353 ctx->operation, block_size, ctx->iv,
354 ctx->unprocessed_data, output ) ) )
355 {
356 return( ret );
357 }
358
359 *olen += block_size;
360 output += block_size;
361 ctx->unprocessed_len = 0;
362
363 input += copy_len;
364 ilen -= copy_len;
365 }
366
367 /*
368 * Cache final, incomplete block
369 */
370 if( 0 != ilen )
371 {
372 if( 0 == block_size )
373 {
374 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
375 }
376
377 copy_len = ilen % block_size;
378 if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT )
379 copy_len = block_size;
380
381 memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
382 copy_len );
383
384 ctx->unprocessed_len += copy_len;
385 ilen -= copy_len;
386 }
387
388 /*
389 * Process remaining full blocks
390 */
391 if( ilen )
392 {
393 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
394 ctx->operation, ilen, ctx->iv, input, output ) ) )
395 {
396 return( ret );
397 }
398
399 *olen += ilen;
400 }
401
402 return( 0 );
403 }
404 #endif /* MBEDTLS_CIPHER_MODE_CBC */
405
406 #if defined(MBEDTLS_CIPHER_MODE_CFB)
407 if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
408 {
409 if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
410 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
411 input, output ) ) )
412 {
413 return( ret );
414 }
415
416 *olen = ilen;
417
418 return( 0 );
419 }
420 #endif /* MBEDTLS_CIPHER_MODE_CFB */
421
422 #if defined(MBEDTLS_CIPHER_MODE_CTR)
423 if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
424 {
425 if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
426 ilen, &ctx->unprocessed_len, ctx->iv,
427 ctx->unprocessed_data, input, output ) ) )
428 {
429 return( ret );
430 }
431
432 *olen = ilen;
433
434 return( 0 );
435 }
436 #endif /* MBEDTLS_CIPHER_MODE_CTR */
437
438 #if defined(MBEDTLS_CIPHER_MODE_STREAM)
439 if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
440 {
441 if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
442 ilen, input, output ) ) )
443 {
444 return( ret );
445 }
446
447 *olen = ilen;
448
449 return( 0 );
450 }
451 #endif /* MBEDTLS_CIPHER_MODE_STREAM */
452
453 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
454 }
455
456 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
457 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
458 /*
459 * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
460 */
461 static void add_pkcs_padding( unsigned char *output, size_t output_len,
462 size_t data_len )
463 {
464 size_t padding_len = output_len - data_len;
465 unsigned char i;
466
467 for( i = 0; i < padding_len; i++ )
468 output[data_len + i] = (unsigned char) padding_len;
469 }
470
471 static int get_pkcs_padding( unsigned char *input, size_t input_len,
472 size_t *data_len )
473 {
474 size_t i, pad_idx;
475 unsigned char padding_len, bad = 0;
476
477 if( NULL == input || NULL == data_len )
478 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
479
480 padding_len = input[input_len - 1];
481 *data_len = input_len - padding_len;
482
483 /* Avoid logical || since it results in a branch */
484 bad |= padding_len > input_len;
485 bad |= padding_len == 0;
486
487 /* The number of bytes checked must be independent of padding_len,
488 * so pick input_len, which is usually 8 or 16 (one block) */
489 pad_idx = input_len - padding_len;
490 for( i = 0; i < input_len; i++ )
491 bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
492
493 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
494 }
495 #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
496
497 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
498 /*
499 * One and zeros padding: fill with 80 00 ... 00
500 */
501 static void add_one_and_zeros_padding( unsigned char *output,
502 size_t output_len, size_t data_len )
503 {
504 size_t padding_len = output_len - data_len;
505 unsigned char i = 0;
506
507 output[data_len] = 0x80;
508 for( i = 1; i < padding_len; i++ )
509 output[data_len + i] = 0x00;
510 }
511
512 static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
513 size_t *data_len )
514 {
515 size_t i;
516 unsigned char done = 0, prev_done, bad;
517
518 if( NULL == input || NULL == data_len )
519 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
520
521 bad = 0xFF;
522 *data_len = 0;
523 for( i = input_len; i > 0; i-- )
524 {
525 prev_done = done;
526 done |= ( input[i-1] != 0 );
527 *data_len |= ( i - 1 ) * ( done != prev_done );
528 bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done );
529 }
530
531 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
532
533 }
534 #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
535
536 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
537 /*
538 * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
539 */
540 static void add_zeros_and_len_padding( unsigned char *output,
541 size_t output_len, size_t data_len )
542 {
543 size_t padding_len = output_len - data_len;
544 unsigned char i = 0;
545
546 for( i = 1; i < padding_len; i++ )
547 output[data_len + i - 1] = 0x00;
548 output[output_len - 1] = (unsigned char) padding_len;
549 }
550
551 static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
552 size_t *data_len )
553 {
554 size_t i, pad_idx;
555 unsigned char padding_len, bad = 0;
556
557 if( NULL == input || NULL == data_len )
558 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
559
560 padding_len = input[input_len - 1];
561 *data_len = input_len - padding_len;
562
563 /* Avoid logical || since it results in a branch */
564 bad |= padding_len > input_len;
565 bad |= padding_len == 0;
566
567 /* The number of bytes checked must be independent of padding_len */
568 pad_idx = input_len - padding_len;
569 for( i = 0; i < input_len - 1; i++ )
570 bad |= input[i] * ( i >= pad_idx );
571
572 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
573 }
574 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
575
576 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
577 /*
578 * Zero padding: fill with 00 ... 00
579 */
580 static void add_zeros_padding( unsigned char *output,
581 size_t output_len, size_t data_len )
582 {
583 size_t i;
584
585 for( i = data_len; i < output_len; i++ )
586 output[i] = 0x00;
587 }
588
589 static int get_zeros_padding( unsigned char *input, size_t input_len,
590 size_t *data_len )
591 {
592 size_t i;
593 unsigned char done = 0, prev_done;
594
595 if( NULL == input || NULL == data_len )
596 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
597
598 *data_len = 0;
599 for( i = input_len; i > 0; i-- )
600 {
601 prev_done = done;
602 done |= ( input[i-1] != 0 );
603 *data_len |= i * ( done != prev_done );
604 }
605
606 return( 0 );
607 }
608 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
609
610 /*
611 * No padding: don't pad :)
612 *
613 * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
614 * but a trivial get_padding function
615 */
616 static int get_no_padding( unsigned char *input, size_t input_len,
617 size_t *data_len )
618 {
619 if( NULL == input || NULL == data_len )
620 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
621
622 *data_len = input_len;
623
624 return( 0 );
625 }
626 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
627
628 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
629 unsigned char *output, size_t *olen )
630 {
631 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
632 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
633
634 *olen = 0;
635
636 if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
637 MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
638 MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
639 MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
640 {
641 return( 0 );
642 }
643
644 if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
645 {
646 if( ctx->unprocessed_len != 0 )
647 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
648
649 return( 0 );
650 }
651
652 #if defined(MBEDTLS_CIPHER_MODE_CBC)
653 if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
654 {
655 int ret = 0;
656
657 if( MBEDTLS_ENCRYPT == ctx->operation )
658 {
659 /* check for 'no padding' mode */
660 if( NULL == ctx->add_padding )
661 {
662 if( 0 != ctx->unprocessed_len )
663 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
664
665 return( 0 );
666 }
667
668 ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
669 ctx->unprocessed_len );
670 }
671 else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
672 {
673 /*
674 * For decrypt operations, expect a full block,
675 * or an empty block if no padding
676 */
677 if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
678 return( 0 );
679
680 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
681 }
682
683 /* cipher block */
684 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
685 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
686 ctx->unprocessed_data, output ) ) )
687 {
688 return( ret );
689 }
690
691 /* Set output size for decryption */
692 if( MBEDTLS_DECRYPT == ctx->operation )
693 return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
694 olen );
695
696 /* Set output size for encryption */
697 *olen = mbedtls_cipher_get_block_size( ctx );
698 return( 0 );
699 }
700 #else
701 ((void) output);
702 #endif /* MBEDTLS_CIPHER_MODE_CBC */
703
704 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
705 }
706
707 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
708 int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode )
709 {
710 if( NULL == ctx ||
711 MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
712 {
713 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
714 }
715
716 switch( mode )
717 {
718 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
719 case MBEDTLS_PADDING_PKCS7:
720 ctx->add_padding = add_pkcs_padding;
721 ctx->get_padding = get_pkcs_padding;
722 break;
723 #endif
724 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
725 case MBEDTLS_PADDING_ONE_AND_ZEROS:
726 ctx->add_padding = add_one_and_zeros_padding;
727 ctx->get_padding = get_one_and_zeros_padding;
728 break;
729 #endif
730 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
731 case MBEDTLS_PADDING_ZEROS_AND_LEN:
732 ctx->add_padding = add_zeros_and_len_padding;
733 ctx->get_padding = get_zeros_and_len_padding;
734 break;
735 #endif
736 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
737 case MBEDTLS_PADDING_ZEROS:
738 ctx->add_padding = add_zeros_padding;
739 ctx->get_padding = get_zeros_padding;
740 break;
741 #endif
742 case MBEDTLS_PADDING_NONE:
743 ctx->add_padding = NULL;
744 ctx->get_padding = get_no_padding;
745 break;
746
747 default:
748 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
749 }
750
751 return( 0 );
752 }
753 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
754
755 #if defined(MBEDTLS_GCM_C)
756 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
757 unsigned char *tag, size_t tag_len )
758 {
759 if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag )
760 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
761
762 if( MBEDTLS_ENCRYPT != ctx->operation )
763 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
764
765 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
766 return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len );
767
768 return( 0 );
769 }
770
771 int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
772 const unsigned char *tag, size_t tag_len )
773 {
774 int ret;
775
776 if( NULL == ctx || NULL == ctx->cipher_info ||
777 MBEDTLS_DECRYPT != ctx->operation )
778 {
779 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
780 }
781
782 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
783 {
784 unsigned char check_tag[16];
785 size_t i;
786 int diff;
787
788 if( tag_len > sizeof( check_tag ) )
789 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
790
791 if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
792 check_tag, tag_len ) ) )
793 {
794 return( ret );
795 }
796
797 /* Check the tag in "constant-time" */
798 for( diff = 0, i = 0; i < tag_len; i++ )
799 diff |= tag[i] ^ check_tag[i];
800
801 if( diff != 0 )
802 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
803
804 return( 0 );
805 }
806
807 return( 0 );
808 }
809 #endif /* MBEDTLS_GCM_C */
810
811 /*
812 * Packet-oriented wrapper for non-AEAD modes
813 */
814 int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
815 const unsigned char *iv, size_t iv_len,
816 const unsigned char *input, size_t ilen,
817 unsigned char *output, size_t *olen )
818 {
819 int ret;
820 size_t finish_olen;
821
822 if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
823 return( ret );
824
825 if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
826 return( ret );
827
828 if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 )
829 return( ret );
830
831 if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 )
832 return( ret );
833
834 *olen += finish_olen;
835
836 return( 0 );
837 }
838
839 #if defined(MBEDTLS_CIPHER_MODE_AEAD)
840 /*
841 * Packet-oriented encryption for AEAD modes
842 */
843 int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
844 const unsigned char *iv, size_t iv_len,
845 const unsigned char *ad, size_t ad_len,
846 const unsigned char *input, size_t ilen,
847 unsigned char *output, size_t *olen,
848 unsigned char *tag, size_t tag_len )
849 {
850 #if defined(MBEDTLS_GCM_C)
851 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
852 {
853 *olen = ilen;
854 return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen,
855 iv, iv_len, ad, ad_len, input, output,
856 tag_len, tag ) );
857 }
858 #endif /* MBEDTLS_GCM_C */
859 #if defined(MBEDTLS_CCM_C)
860 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
861 {
862 *olen = ilen;
863 return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
864 iv, iv_len, ad, ad_len, input, output,
865 tag, tag_len ) );
866 }
867 #endif /* MBEDTLS_CCM_C */
868
869 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
870 }
871
872 /*
873 * Packet-oriented decryption for AEAD modes
874 */
875 int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
876 const unsigned char *iv, size_t iv_len,
877 const unsigned char *ad, size_t ad_len,
878 const unsigned char *input, size_t ilen,
879 unsigned char *output, size_t *olen,
880 const unsigned char *tag, size_t tag_len )
881 {
882 #if defined(MBEDTLS_GCM_C)
883 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
884 {
885 int ret;
886
887 *olen = ilen;
888 ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
889 iv, iv_len, ad, ad_len,
890 tag, tag_len, input, output );
891
892 if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
893 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
894
895 return( ret );
896 }
897 #endif /* MBEDTLS_GCM_C */
898 #if defined(MBEDTLS_CCM_C)
899 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
900 {
901 int ret;
902
903 *olen = ilen;
904 ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
905 iv, iv_len, ad, ad_len,
906 input, output, tag, tag_len );
907
908 if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
909 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
910
911 return( ret );
912 }
913 #endif /* MBEDTLS_CCM_C */
914
915 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
916 }
917 #endif /* MBEDTLS_CIPHER_MODE_AEAD */
918
919 #endif /* MBEDTLS_CIPHER_C */