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