Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
cipher.c
00001 /** 00002 * \file cipher.c 00003 * 00004 * \brief Generic cipher wrapper for mbed TLS 00005 * 00006 * \author Adriaan de Jong <dejong@fox-it.com> 00007 * 00008 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00009 * SPDX-License-Identifier: Apache-2.0 00010 * 00011 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00012 * not use this file except in compliance with the License. 00013 * You may obtain a copy of the License at 00014 * 00015 * http://www.apache.org/licenses/LICENSE-2.0 00016 * 00017 * Unless required by applicable law or agreed to in writing, software 00018 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00019 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 * See the License for the specific language governing permissions and 00021 * limitations under the License. 00022 * 00023 * This file is part of mbed TLS (https://tls.mbed.org) 00024 */ 00025 00026 #if !defined(MBEDTLS_CONFIG_FILE) 00027 #include "mbedtls/config.h" 00028 #else 00029 #include MBEDTLS_CONFIG_FILE 00030 #endif 00031 00032 #if defined(MBEDTLS_CIPHER_C) 00033 00034 #include "mbedtls/cipher.h" 00035 #include "mbedtls/cipher_internal.h" 00036 #include "mbedtls/platform_util.h" 00037 00038 #include <stdlib.h> 00039 #include <string.h> 00040 00041 #if defined(MBEDTLS_CHACHAPOLY_C) 00042 #include "mbedtls/chachapoly.h" 00043 #endif 00044 00045 #if defined(MBEDTLS_GCM_C) 00046 #include "mbedtls/gcm.h" 00047 #endif 00048 00049 #if defined(MBEDTLS_CCM_C) 00050 #include "mbedtls/ccm.h" 00051 #endif 00052 00053 #if defined(MBEDTLS_CHACHA20_C) 00054 #include "mbedtls/chacha20.h" 00055 #endif 00056 00057 #if defined(MBEDTLS_CMAC_C) 00058 #include "mbedtls/cmac.h" 00059 #endif 00060 00061 #if defined(MBEDTLS_PLATFORM_C) 00062 #include "mbedtls/platform.h" 00063 #else 00064 #define mbedtls_calloc calloc 00065 #define mbedtls_free free 00066 #endif 00067 00068 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) 00069 /* Compare the contents of two buffers in constant time. 00070 * Returns 0 if the contents are bitwise identical, otherwise returns 00071 * a non-zero value. 00072 * This is currently only used by GCM and ChaCha20+Poly1305. 00073 */ 00074 static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len ) 00075 { 00076 const unsigned char *p1 = (const unsigned char*) v1; 00077 const unsigned char *p2 = (const unsigned char*) v2; 00078 size_t i; 00079 unsigned char diff; 00080 00081 for( diff = 0, i = 0; i < len; i++ ) 00082 diff |= p1[i] ^ p2[i]; 00083 00084 return (int)diff; 00085 } 00086 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ 00087 00088 static int supported_init = 0; 00089 00090 const int *mbedtls_cipher_list( void ) 00091 { 00092 const mbedtls_cipher_definition_t *def; 00093 int *type; 00094 00095 if( ! supported_init ) 00096 { 00097 def = mbedtls_cipher_definitions; 00098 type = mbedtls_cipher_supported; 00099 00100 while( def->type != 0 ) 00101 *type++ = (*def++).type; 00102 00103 *type = 0; 00104 00105 supported_init = 1; 00106 } 00107 00108 return( mbedtls_cipher_supported ); 00109 } 00110 00111 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ) 00112 { 00113 const mbedtls_cipher_definition_t *def; 00114 00115 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) 00116 if( def->type == cipher_type ) 00117 return( def->info ); 00118 00119 return( NULL ); 00120 } 00121 00122 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ) 00123 { 00124 const mbedtls_cipher_definition_t *def; 00125 00126 if( NULL == cipher_name ) 00127 return( NULL ); 00128 00129 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) 00130 if( ! strcmp( def->info->name, cipher_name ) ) 00131 return( def->info ); 00132 00133 return( NULL ); 00134 } 00135 00136 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, 00137 int key_bitlen, 00138 const mbedtls_cipher_mode_t mode ) 00139 { 00140 const mbedtls_cipher_definition_t *def; 00141 00142 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) 00143 if( def->info->base->cipher == cipher_id && 00144 def->info->key_bitlen == (unsigned) key_bitlen && 00145 def->info->mode == mode ) 00146 return( def->info ); 00147 00148 return( NULL ); 00149 } 00150 00151 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) 00152 { 00153 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); 00154 } 00155 00156 void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) 00157 { 00158 if( ctx == NULL ) 00159 return; 00160 00161 #if defined(MBEDTLS_CMAC_C) 00162 if( ctx->cmac_ctx ) 00163 { 00164 mbedtls_platform_zeroize( ctx->cmac_ctx, 00165 sizeof( mbedtls_cmac_context_t ) ); 00166 mbedtls_free( ctx->cmac_ctx ); 00167 } 00168 #endif 00169 00170 if( ctx->cipher_ctx ) 00171 ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); 00172 00173 mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); 00174 } 00175 00176 int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ) 00177 { 00178 if( NULL == cipher_info || NULL == ctx ) 00179 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00180 00181 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); 00182 00183 if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) 00184 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); 00185 00186 ctx->cipher_info = cipher_info; 00187 00188 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00189 /* 00190 * Ignore possible errors caused by a cipher mode that doesn't use padding 00191 */ 00192 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00193 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); 00194 #else 00195 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); 00196 #endif 00197 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00198 00199 return( 0 ); 00200 } 00201 00202 int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, 00203 int key_bitlen, const mbedtls_operation_t operation ) 00204 { 00205 if( NULL == ctx || NULL == ctx->cipher_info ) 00206 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00207 00208 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && 00209 (int) ctx->cipher_info->key_bitlen != key_bitlen ) 00210 { 00211 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00212 } 00213 00214 ctx->key_bitlen = key_bitlen; 00215 ctx->operation = operation; 00216 00217 /* 00218 * For OFB, CFB and CTR mode always use the encryption key schedule 00219 */ 00220 if( MBEDTLS_ENCRYPT == operation || 00221 MBEDTLS_MODE_CFB == ctx->cipher_info->mode || 00222 MBEDTLS_MODE_OFB == ctx->cipher_info->mode || 00223 MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) 00224 { 00225 return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, 00226 ctx->key_bitlen ); 00227 } 00228 00229 if( MBEDTLS_DECRYPT == operation ) 00230 return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, 00231 ctx->key_bitlen ); 00232 00233 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00234 } 00235 00236 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, 00237 const unsigned char *iv, size_t iv_len ) 00238 { 00239 size_t actual_iv_size; 00240 00241 if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) 00242 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00243 00244 /* avoid buffer overflow in ctx->iv */ 00245 if( iv_len > MBEDTLS_MAX_IV_LENGTH ) 00246 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00247 00248 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) 00249 actual_iv_size = iv_len; 00250 else 00251 { 00252 actual_iv_size = ctx->cipher_info->iv_size; 00253 00254 /* avoid reading past the end of input buffer */ 00255 if( actual_iv_size > iv_len ) 00256 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00257 } 00258 00259 #if defined(MBEDTLS_CHACHA20_C) 00260 if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) 00261 { 00262 if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx, 00263 iv, 00264 0U ) ) /* Initial counter value */ 00265 { 00266 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00267 } 00268 } 00269 #endif 00270 00271 memcpy( ctx->iv, iv, actual_iv_size ); 00272 ctx->iv_size = actual_iv_size; 00273 00274 return( 0 ); 00275 } 00276 00277 int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) 00278 { 00279 if( NULL == ctx || NULL == ctx->cipher_info ) 00280 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00281 00282 ctx->unprocessed_len = 0; 00283 00284 return( 0 ); 00285 } 00286 00287 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) 00288 int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, 00289 const unsigned char *ad, size_t ad_len ) 00290 { 00291 if( NULL == ctx || NULL == ctx->cipher_info ) 00292 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00293 00294 #if defined(MBEDTLS_GCM_C) 00295 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00296 { 00297 return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, 00298 ctx->iv, ctx->iv_size, ad, ad_len ); 00299 } 00300 #endif 00301 00302 #if defined(MBEDTLS_CHACHAPOLY_C) 00303 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) 00304 { 00305 int result; 00306 mbedtls_chachapoly_mode_t mode; 00307 00308 mode = ( ctx->operation == MBEDTLS_ENCRYPT ) 00309 ? MBEDTLS_CHACHAPOLY_ENCRYPT 00310 : MBEDTLS_CHACHAPOLY_DECRYPT; 00311 00312 result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, 00313 ctx->iv, 00314 mode ); 00315 if ( result != 0 ) 00316 return( result ); 00317 00318 return mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, 00319 ad, ad_len ); 00320 } 00321 #endif 00322 00323 return( 0 ); 00324 } 00325 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ 00326 00327 int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, 00328 size_t ilen, unsigned char *output, size_t *olen ) 00329 { 00330 int ret; 00331 size_t block_size = 0; 00332 00333 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 00334 { 00335 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00336 } 00337 00338 *olen = 0; 00339 block_size = mbedtls_cipher_get_block_size( ctx ); 00340 00341 if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) 00342 { 00343 if( ilen != block_size ) 00344 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00345 00346 *olen = ilen; 00347 00348 if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, 00349 ctx->operation, input, output ) ) ) 00350 { 00351 return( ret ); 00352 } 00353 00354 return( 0 ); 00355 } 00356 00357 #if defined(MBEDTLS_GCM_C) 00358 if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) 00359 { 00360 *olen = ilen; 00361 return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, 00362 output ); 00363 } 00364 #endif 00365 00366 #if defined(MBEDTLS_CHACHAPOLY_C) 00367 if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) 00368 { 00369 *olen = ilen; 00370 return mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, 00371 ilen, input, output ); 00372 } 00373 #endif 00374 00375 if ( 0 == block_size ) 00376 { 00377 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; 00378 } 00379 00380 if( input == output && 00381 ( ctx->unprocessed_len != 0 || ilen % block_size ) ) 00382 { 00383 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00384 } 00385 00386 #if defined(MBEDTLS_CIPHER_MODE_CBC) 00387 if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) 00388 { 00389 size_t copy_len = 0; 00390 00391 /* 00392 * If there is not enough data for a full block, cache it. 00393 */ 00394 if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding && 00395 ilen <= block_size - ctx->unprocessed_len ) || 00396 ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding && 00397 ilen < block_size - ctx->unprocessed_len ) || 00398 ( ctx->operation == MBEDTLS_ENCRYPT && 00399 ilen < block_size - ctx->unprocessed_len ) ) 00400 { 00401 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, 00402 ilen ); 00403 00404 ctx->unprocessed_len += ilen; 00405 return( 0 ); 00406 } 00407 00408 /* 00409 * Process cached data first 00410 */ 00411 if( 0 != ctx->unprocessed_len ) 00412 { 00413 copy_len = block_size - ctx->unprocessed_len; 00414 00415 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, 00416 copy_len ); 00417 00418 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00419 ctx->operation, block_size, ctx->iv, 00420 ctx->unprocessed_data, output ) ) ) 00421 { 00422 return( ret ); 00423 } 00424 00425 *olen += block_size; 00426 output += block_size; 00427 ctx->unprocessed_len = 0; 00428 00429 input += copy_len; 00430 ilen -= copy_len; 00431 } 00432 00433 /* 00434 * Cache final, incomplete block 00435 */ 00436 if( 0 != ilen ) 00437 { 00438 if( 0 == block_size ) 00439 { 00440 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; 00441 } 00442 00443 /* Encryption: only cache partial blocks 00444 * Decryption w/ padding: always keep at least one whole block 00445 * Decryption w/o padding: only cache partial blocks 00446 */ 00447 copy_len = ilen % block_size; 00448 if( copy_len == 0 && 00449 ctx->operation == MBEDTLS_DECRYPT && 00450 NULL != ctx->add_padding) 00451 { 00452 copy_len = block_size; 00453 } 00454 00455 memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), 00456 copy_len ); 00457 00458 ctx->unprocessed_len += copy_len; 00459 ilen -= copy_len; 00460 } 00461 00462 /* 00463 * Process remaining full blocks 00464 */ 00465 if( ilen ) 00466 { 00467 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00468 ctx->operation, ilen, ctx->iv, input, output ) ) ) 00469 { 00470 return( ret ); 00471 } 00472 00473 *olen += ilen; 00474 } 00475 00476 return( 0 ); 00477 } 00478 #endif /* MBEDTLS_CIPHER_MODE_CBC */ 00479 00480 #if defined(MBEDTLS_CIPHER_MODE_CFB) 00481 if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) 00482 { 00483 if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, 00484 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, 00485 input, output ) ) ) 00486 { 00487 return( ret ); 00488 } 00489 00490 *olen = ilen; 00491 00492 return( 0 ); 00493 } 00494 #endif /* MBEDTLS_CIPHER_MODE_CFB */ 00495 00496 #if defined(MBEDTLS_CIPHER_MODE_OFB) 00497 if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB ) 00498 { 00499 if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx, 00500 ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) ) 00501 { 00502 return( ret ); 00503 } 00504 00505 *olen = ilen; 00506 00507 return( 0 ); 00508 } 00509 #endif /* MBEDTLS_CIPHER_MODE_OFB */ 00510 00511 #if defined(MBEDTLS_CIPHER_MODE_CTR) 00512 if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) 00513 { 00514 if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, 00515 ilen, &ctx->unprocessed_len, ctx->iv, 00516 ctx->unprocessed_data, input, output ) ) ) 00517 { 00518 return( ret ); 00519 } 00520 00521 *olen = ilen; 00522 00523 return( 0 ); 00524 } 00525 #endif /* MBEDTLS_CIPHER_MODE_CTR */ 00526 00527 #if defined(MBEDTLS_CIPHER_MODE_XTS) 00528 if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS ) 00529 { 00530 if( ctx->unprocessed_len > 0 ) { 00531 /* We can only process an entire data unit at a time. */ 00532 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00533 } 00534 00535 ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx, 00536 ctx->operation, ilen, ctx->iv, input, output ); 00537 if( ret != 0 ) 00538 { 00539 return( ret ); 00540 } 00541 00542 *olen = ilen; 00543 00544 return( 0 ); 00545 } 00546 #endif /* MBEDTLS_CIPHER_MODE_XTS */ 00547 00548 #if defined(MBEDTLS_CIPHER_MODE_STREAM) 00549 if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) 00550 { 00551 if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, 00552 ilen, input, output ) ) ) 00553 { 00554 return( ret ); 00555 } 00556 00557 *olen = ilen; 00558 00559 return( 0 ); 00560 } 00561 #endif /* MBEDTLS_CIPHER_MODE_STREAM */ 00562 00563 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00564 } 00565 00566 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00567 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00568 /* 00569 * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len 00570 */ 00571 static void add_pkcs_padding( unsigned char *output, size_t output_len, 00572 size_t data_len ) 00573 { 00574 size_t padding_len = output_len - data_len; 00575 unsigned char i; 00576 00577 for( i = 0; i < padding_len; i++ ) 00578 output[data_len + i] = (unsigned char) padding_len; 00579 } 00580 00581 static int get_pkcs_padding( unsigned char *input, size_t input_len, 00582 size_t *data_len ) 00583 { 00584 size_t i, pad_idx; 00585 unsigned char padding_len, bad = 0; 00586 00587 if( NULL == input || NULL == data_len ) 00588 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00589 00590 padding_len = input[input_len - 1]; 00591 *data_len = input_len - padding_len; 00592 00593 /* Avoid logical || since it results in a branch */ 00594 bad |= padding_len > input_len; 00595 bad |= padding_len == 0; 00596 00597 /* The number of bytes checked must be independent of padding_len, 00598 * so pick input_len, which is usually 8 or 16 (one block) */ 00599 pad_idx = input_len - padding_len; 00600 for( i = 0; i < input_len; i++ ) 00601 bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); 00602 00603 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00604 } 00605 #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ 00606 00607 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) 00608 /* 00609 * One and zeros padding: fill with 80 00 ... 00 00610 */ 00611 static void add_one_and_zeros_padding( unsigned char *output, 00612 size_t output_len, size_t data_len ) 00613 { 00614 size_t padding_len = output_len - data_len; 00615 unsigned char i = 0; 00616 00617 output[data_len] = 0x80; 00618 for( i = 1; i < padding_len; i++ ) 00619 output[data_len + i] = 0x00; 00620 } 00621 00622 static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, 00623 size_t *data_len ) 00624 { 00625 size_t i; 00626 unsigned char done = 0, prev_done, bad; 00627 00628 if( NULL == input || NULL == data_len ) 00629 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00630 00631 bad = 0x80; 00632 *data_len = 0; 00633 for( i = input_len; i > 0; i-- ) 00634 { 00635 prev_done = done; 00636 done |= ( input[i - 1] != 0 ); 00637 *data_len |= ( i - 1 ) * ( done != prev_done ); 00638 bad ^= input[i - 1] * ( done != prev_done ); 00639 } 00640 00641 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00642 00643 } 00644 #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ 00645 00646 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) 00647 /* 00648 * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length 00649 */ 00650 static void add_zeros_and_len_padding( unsigned char *output, 00651 size_t output_len, size_t data_len ) 00652 { 00653 size_t padding_len = output_len - data_len; 00654 unsigned char i = 0; 00655 00656 for( i = 1; i < padding_len; i++ ) 00657 output[data_len + i - 1] = 0x00; 00658 output[output_len - 1] = (unsigned char) padding_len; 00659 } 00660 00661 static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, 00662 size_t *data_len ) 00663 { 00664 size_t i, pad_idx; 00665 unsigned char padding_len, bad = 0; 00666 00667 if( NULL == input || NULL == data_len ) 00668 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00669 00670 padding_len = input[input_len - 1]; 00671 *data_len = input_len - padding_len; 00672 00673 /* Avoid logical || since it results in a branch */ 00674 bad |= padding_len > input_len; 00675 bad |= padding_len == 0; 00676 00677 /* The number of bytes checked must be independent of padding_len */ 00678 pad_idx = input_len - padding_len; 00679 for( i = 0; i < input_len - 1; i++ ) 00680 bad |= input[i] * ( i >= pad_idx ); 00681 00682 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00683 } 00684 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ 00685 00686 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS) 00687 /* 00688 * Zero padding: fill with 00 ... 00 00689 */ 00690 static void add_zeros_padding( unsigned char *output, 00691 size_t output_len, size_t data_len ) 00692 { 00693 size_t i; 00694 00695 for( i = data_len; i < output_len; i++ ) 00696 output[i] = 0x00; 00697 } 00698 00699 static int get_zeros_padding( unsigned char *input, size_t input_len, 00700 size_t *data_len ) 00701 { 00702 size_t i; 00703 unsigned char done = 0, prev_done; 00704 00705 if( NULL == input || NULL == data_len ) 00706 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00707 00708 *data_len = 0; 00709 for( i = input_len; i > 0; i-- ) 00710 { 00711 prev_done = done; 00712 done |= ( input[i-1] != 0 ); 00713 *data_len |= i * ( done != prev_done ); 00714 } 00715 00716 return( 0 ); 00717 } 00718 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ 00719 00720 /* 00721 * No padding: don't pad :) 00722 * 00723 * There is no add_padding function (check for NULL in mbedtls_cipher_finish) 00724 * but a trivial get_padding function 00725 */ 00726 static int get_no_padding( unsigned char *input, size_t input_len, 00727 size_t *data_len ) 00728 { 00729 if( NULL == input || NULL == data_len ) 00730 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00731 00732 *data_len = input_len; 00733 00734 return( 0 ); 00735 } 00736 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00737 00738 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, 00739 unsigned char *output, size_t *olen ) 00740 { 00741 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 00742 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00743 00744 *olen = 0; 00745 00746 if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || 00747 MBEDTLS_MODE_OFB == ctx->cipher_info->mode || 00748 MBEDTLS_MODE_CTR == ctx->cipher_info->mode || 00749 MBEDTLS_MODE_GCM == ctx->cipher_info->mode || 00750 MBEDTLS_MODE_XTS == ctx->cipher_info->mode || 00751 MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) 00752 { 00753 return( 0 ); 00754 } 00755 00756 if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) || 00757 ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) ) 00758 { 00759 return( 0 ); 00760 } 00761 00762 if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) 00763 { 00764 if( ctx->unprocessed_len != 0 ) 00765 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00766 00767 return( 0 ); 00768 } 00769 00770 #if defined(MBEDTLS_CIPHER_MODE_CBC) 00771 if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) 00772 { 00773 int ret = 0; 00774 00775 if( MBEDTLS_ENCRYPT == ctx->operation ) 00776 { 00777 /* check for 'no padding' mode */ 00778 if( NULL == ctx->add_padding ) 00779 { 00780 if( 0 != ctx->unprocessed_len ) 00781 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00782 00783 return( 0 ); 00784 } 00785 00786 ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), 00787 ctx->unprocessed_len ); 00788 } 00789 else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) 00790 { 00791 /* 00792 * For decrypt operations, expect a full block, 00793 * or an empty block if no padding 00794 */ 00795 if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) 00796 return( 0 ); 00797 00798 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00799 } 00800 00801 /* cipher block */ 00802 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00803 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, 00804 ctx->unprocessed_data, output ) ) ) 00805 { 00806 return( ret ); 00807 } 00808 00809 /* Set output size for decryption */ 00810 if( MBEDTLS_DECRYPT == ctx->operation ) 00811 return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), 00812 olen ); 00813 00814 /* Set output size for encryption */ 00815 *olen = mbedtls_cipher_get_block_size( ctx ); 00816 return( 0 ); 00817 } 00818 #else 00819 ((void) output); 00820 #endif /* MBEDTLS_CIPHER_MODE_CBC */ 00821 00822 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00823 } 00824 00825 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00826 int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ) 00827 { 00828 if( NULL == ctx || 00829 MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) 00830 { 00831 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00832 } 00833 00834 switch( mode ) 00835 { 00836 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00837 case MBEDTLS_PADDING_PKCS7: 00838 ctx->add_padding = add_pkcs_padding; 00839 ctx->get_padding = get_pkcs_padding; 00840 break; 00841 #endif 00842 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) 00843 case MBEDTLS_PADDING_ONE_AND_ZEROS: 00844 ctx->add_padding = add_one_and_zeros_padding; 00845 ctx->get_padding = get_one_and_zeros_padding; 00846 break; 00847 #endif 00848 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) 00849 case MBEDTLS_PADDING_ZEROS_AND_LEN: 00850 ctx->add_padding = add_zeros_and_len_padding; 00851 ctx->get_padding = get_zeros_and_len_padding; 00852 break; 00853 #endif 00854 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS) 00855 case MBEDTLS_PADDING_ZEROS: 00856 ctx->add_padding = add_zeros_padding; 00857 ctx->get_padding = get_zeros_padding; 00858 break; 00859 #endif 00860 case MBEDTLS_PADDING_NONE: 00861 ctx->add_padding = NULL; 00862 ctx->get_padding = get_no_padding; 00863 break; 00864 00865 default: 00866 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00867 } 00868 00869 return( 0 ); 00870 } 00871 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00872 00873 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) 00874 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, 00875 unsigned char *tag, size_t tag_len ) 00876 { 00877 if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) 00878 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00879 00880 if( MBEDTLS_ENCRYPT != ctx->operation ) 00881 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00882 00883 #if defined(MBEDTLS_GCM_C) 00884 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00885 return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); 00886 #endif 00887 00888 #if defined(MBEDTLS_CHACHAPOLY_C) 00889 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) 00890 { 00891 /* Don't allow truncated MAC for Poly1305 */ 00892 if ( tag_len != 16U ) 00893 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00894 00895 return mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, 00896 tag ); 00897 } 00898 #endif 00899 00900 return( 0 ); 00901 } 00902 00903 int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, 00904 const unsigned char *tag, size_t tag_len ) 00905 { 00906 unsigned char check_tag[16]; 00907 int ret; 00908 00909 if( NULL == ctx || NULL == ctx->cipher_info || 00910 MBEDTLS_DECRYPT != ctx->operation ) 00911 { 00912 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00913 } 00914 00915 #if defined(MBEDTLS_GCM_C) 00916 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00917 { 00918 if( tag_len > sizeof( check_tag ) ) 00919 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00920 00921 if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, 00922 check_tag, tag_len ) ) ) 00923 { 00924 return( ret ); 00925 } 00926 00927 /* Check the tag in "constant-time" */ 00928 if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) 00929 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); 00930 00931 return( 0 ); 00932 } 00933 #endif /* MBEDTLS_GCM_C */ 00934 00935 #if defined(MBEDTLS_CHACHAPOLY_C) 00936 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) 00937 { 00938 /* Don't allow truncated MAC for Poly1305 */ 00939 if ( tag_len != sizeof( check_tag ) ) 00940 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00941 00942 ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, 00943 check_tag ); 00944 if ( ret != 0 ) 00945 { 00946 return( ret ); 00947 } 00948 00949 /* Check the tag in "constant-time" */ 00950 if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) 00951 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); 00952 00953 return( 0 ); 00954 } 00955 #endif /* MBEDTLS_CHACHAPOLY_C */ 00956 00957 return( 0 ); 00958 } 00959 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ 00960 00961 /* 00962 * Packet-oriented wrapper for non-AEAD modes 00963 */ 00964 int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, 00965 const unsigned char *iv, size_t iv_len, 00966 const unsigned char *input, size_t ilen, 00967 unsigned char *output, size_t *olen ) 00968 { 00969 int ret; 00970 size_t finish_olen; 00971 00972 if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) 00973 return( ret ); 00974 00975 if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) 00976 return( ret ); 00977 00978 if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) 00979 return( ret ); 00980 00981 if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) 00982 return( ret ); 00983 00984 *olen += finish_olen; 00985 00986 return( 0 ); 00987 } 00988 00989 #if defined(MBEDTLS_CIPHER_MODE_AEAD) 00990 /* 00991 * Packet-oriented encryption for AEAD modes 00992 */ 00993 int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, 00994 const unsigned char *iv, size_t iv_len, 00995 const unsigned char *ad, size_t ad_len, 00996 const unsigned char *input, size_t ilen, 00997 unsigned char *output, size_t *olen, 00998 unsigned char *tag, size_t tag_len ) 00999 { 01000 #if defined(MBEDTLS_GCM_C) 01001 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 01002 { 01003 *olen = ilen; 01004 return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen, 01005 iv, iv_len, ad, ad_len, input, output, 01006 tag_len, tag ) ); 01007 } 01008 #endif /* MBEDTLS_GCM_C */ 01009 #if defined(MBEDTLS_CCM_C) 01010 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) 01011 { 01012 *olen = ilen; 01013 return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, 01014 iv, iv_len, ad, ad_len, input, output, 01015 tag, tag_len ) ); 01016 } 01017 #endif /* MBEDTLS_CCM_C */ 01018 #if defined(MBEDTLS_CHACHAPOLY_C) 01019 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) 01020 { 01021 /* ChachaPoly has fixed length nonce and MAC (tag) */ 01022 if ( ( iv_len != ctx->cipher_info->iv_size ) || 01023 ( tag_len != 16U ) ) 01024 { 01025 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 01026 } 01027 01028 *olen = ilen; 01029 return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx, 01030 ilen, iv, ad, ad_len, input, output, tag ) ); 01031 } 01032 #endif /* MBEDTLS_CHACHAPOLY_C */ 01033 01034 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 01035 } 01036 01037 /* 01038 * Packet-oriented decryption for AEAD modes 01039 */ 01040 int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, 01041 const unsigned char *iv, size_t iv_len, 01042 const unsigned char *ad, size_t ad_len, 01043 const unsigned char *input, size_t ilen, 01044 unsigned char *output, size_t *olen, 01045 const unsigned char *tag, size_t tag_len ) 01046 { 01047 #if defined(MBEDTLS_GCM_C) 01048 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 01049 { 01050 int ret; 01051 01052 *olen = ilen; 01053 ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, 01054 iv, iv_len, ad, ad_len, 01055 tag, tag_len, input, output ); 01056 01057 if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) 01058 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; 01059 01060 return( ret ); 01061 } 01062 #endif /* MBEDTLS_GCM_C */ 01063 #if defined(MBEDTLS_CCM_C) 01064 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) 01065 { 01066 int ret; 01067 01068 *olen = ilen; 01069 ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, 01070 iv, iv_len, ad, ad_len, 01071 input, output, tag, tag_len ); 01072 01073 if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) 01074 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; 01075 01076 return( ret ); 01077 } 01078 #endif /* MBEDTLS_CCM_C */ 01079 #if defined(MBEDTLS_CHACHAPOLY_C) 01080 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) 01081 { 01082 int ret; 01083 01084 /* ChachaPoly has fixed length nonce and MAC (tag) */ 01085 if ( ( iv_len != ctx->cipher_info->iv_size ) || 01086 ( tag_len != 16U ) ) 01087 { 01088 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 01089 } 01090 01091 *olen = ilen; 01092 ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen, 01093 iv, ad, ad_len, tag, input, output ); 01094 01095 if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) 01096 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; 01097 01098 return( ret ); 01099 } 01100 #endif /* MBEDTLS_CHACHAPOLY_C */ 01101 01102 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 01103 } 01104 #endif /* MBEDTLS_CIPHER_MODE_AEAD */ 01105 01106 #endif /* MBEDTLS_CIPHER_C */
Generated on Tue Jul 12 2022 20:52:39 by
