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.
Fork of mbedtls by
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 00037 #include <stdlib.h> 00038 #include <string.h> 00039 00040 #if defined(MBEDTLS_GCM_C) 00041 #include "mbedtls/gcm.h" 00042 #endif 00043 00044 #if defined(MBEDTLS_CCM_C) 00045 #include "mbedtls/ccm.h" 00046 #endif 00047 00048 #if defined(MBEDTLS_CMAC_C) 00049 #include "mbedtls/cmac.h" 00050 #endif 00051 00052 #if defined(MBEDTLS_PLATFORM_C) 00053 #include "mbedtls/platform.h" 00054 #else 00055 #define mbedtls_calloc calloc 00056 #define mbedtls_free free 00057 #endif 00058 00059 #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) 00060 #define MBEDTLS_CIPHER_MODE_STREAM 00061 #endif 00062 00063 /* Implementation that should never be optimized out by the compiler */ 00064 static void mbedtls_zeroize( void *v, size_t n ) { 00065 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; 00066 } 00067 00068 static int supported_init = 0; 00069 00070 const int *mbedtls_cipher_list( void ) 00071 { 00072 const mbedtls_cipher_definition_t *def; 00073 int *type; 00074 00075 if( ! supported_init ) 00076 { 00077 def = mbedtls_cipher_definitions; 00078 type = mbedtls_cipher_supported; 00079 00080 while( def->type != 0 ) 00081 *type++ = (*def++).type; 00082 00083 *type = 0; 00084 00085 supported_init = 1; 00086 } 00087 00088 return( mbedtls_cipher_supported ); 00089 } 00090 00091 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ) 00092 { 00093 const mbedtls_cipher_definition_t *def; 00094 00095 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) 00096 if( def->type == cipher_type ) 00097 return( def->info ); 00098 00099 return( NULL ); 00100 } 00101 00102 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ) 00103 { 00104 const mbedtls_cipher_definition_t *def; 00105 00106 if( NULL == cipher_name ) 00107 return( NULL ); 00108 00109 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) 00110 if( ! strcmp( def->info->name, cipher_name ) ) 00111 return( def->info ); 00112 00113 return( NULL ); 00114 } 00115 00116 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, 00117 int key_bitlen, 00118 const mbedtls_cipher_mode_t mode ) 00119 { 00120 const mbedtls_cipher_definition_t *def; 00121 00122 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) 00123 if( def->info->base->cipher == cipher_id && 00124 def->info->key_bitlen == (unsigned) key_bitlen && 00125 def->info->mode == mode ) 00126 return( def->info ); 00127 00128 return( NULL ); 00129 } 00130 00131 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) 00132 { 00133 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); 00134 } 00135 00136 void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) 00137 { 00138 if( ctx == NULL ) 00139 return; 00140 00141 #if defined(MBEDTLS_CMAC_C) 00142 if( ctx->cmac_ctx ) 00143 { 00144 mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) ); 00145 mbedtls_free( ctx->cmac_ctx ); 00146 } 00147 #endif 00148 00149 if( ctx->cipher_ctx ) 00150 ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); 00151 00152 mbedtls_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); 00153 } 00154 00155 int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ) 00156 { 00157 if( NULL == cipher_info || NULL == ctx ) 00158 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00159 00160 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); 00161 00162 if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) 00163 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); 00164 00165 ctx->cipher_info = cipher_info; 00166 00167 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00168 /* 00169 * Ignore possible errors caused by a cipher mode that doesn't use padding 00170 */ 00171 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00172 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); 00173 #else 00174 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); 00175 #endif 00176 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00177 00178 return( 0 ); 00179 } 00180 00181 int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, 00182 int key_bitlen, const mbedtls_operation_t operation ) 00183 { 00184 if( NULL == ctx || NULL == ctx->cipher_info ) 00185 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00186 00187 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && 00188 (int) ctx->cipher_info->key_bitlen != key_bitlen ) 00189 { 00190 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00191 } 00192 00193 ctx->key_bitlen = key_bitlen; 00194 ctx->operation = operation; 00195 00196 /* 00197 * For CFB and CTR mode always use the encryption key schedule 00198 */ 00199 if( MBEDTLS_ENCRYPT == operation || 00200 MBEDTLS_MODE_CFB == ctx->cipher_info->mode || 00201 MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) 00202 { 00203 return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, 00204 ctx->key_bitlen ); 00205 } 00206 00207 if( MBEDTLS_DECRYPT == operation ) 00208 return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, 00209 ctx->key_bitlen ); 00210 00211 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00212 } 00213 00214 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, 00215 const unsigned char *iv, size_t iv_len ) 00216 { 00217 size_t actual_iv_size; 00218 00219 if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) 00220 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00221 00222 /* avoid buffer overflow in ctx->iv */ 00223 if( iv_len > MBEDTLS_MAX_IV_LENGTH ) 00224 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00225 00226 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) 00227 actual_iv_size = iv_len; 00228 else 00229 { 00230 actual_iv_size = ctx->cipher_info->iv_size; 00231 00232 /* avoid reading past the end of input buffer */ 00233 if( actual_iv_size > iv_len ) 00234 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00235 } 00236 00237 memcpy( ctx->iv, iv, actual_iv_size ); 00238 ctx->iv_size = actual_iv_size; 00239 00240 return( 0 ); 00241 } 00242 00243 int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) 00244 { 00245 if( NULL == ctx || NULL == ctx->cipher_info ) 00246 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00247 00248 ctx->unprocessed_len = 0; 00249 00250 return( 0 ); 00251 } 00252 00253 #if defined(MBEDTLS_GCM_C) 00254 int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, 00255 const unsigned char *ad, size_t ad_len ) 00256 { 00257 if( NULL == ctx || NULL == ctx->cipher_info ) 00258 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00259 00260 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00261 { 00262 return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, 00263 ctx->iv, ctx->iv_size, ad, ad_len ); 00264 } 00265 00266 return( 0 ); 00267 } 00268 #endif /* MBEDTLS_GCM_C */ 00269 00270 int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, 00271 size_t ilen, unsigned char *output, size_t *olen ) 00272 { 00273 int ret; 00274 size_t block_size = 0; 00275 00276 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 00277 { 00278 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00279 } 00280 00281 *olen = 0; 00282 block_size = mbedtls_cipher_get_block_size( ctx ); 00283 00284 if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) 00285 { 00286 if( ilen != block_size ) 00287 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00288 00289 *olen = ilen; 00290 00291 if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, 00292 ctx->operation, input, output ) ) ) 00293 { 00294 return( ret ); 00295 } 00296 00297 return( 0 ); 00298 } 00299 00300 #if defined(MBEDTLS_GCM_C) 00301 if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) 00302 { 00303 *olen = ilen; 00304 return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, 00305 output ); 00306 } 00307 #endif 00308 00309 if ( 0 == block_size ) 00310 { 00311 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; 00312 } 00313 00314 if( input == output && 00315 ( ctx->unprocessed_len != 0 || ilen % block_size ) ) 00316 { 00317 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00318 } 00319 00320 #if defined(MBEDTLS_CIPHER_MODE_CBC) 00321 if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) 00322 { 00323 size_t copy_len = 0; 00324 00325 /* 00326 * If there is not enough data for a full block, cache it. 00327 */ 00328 if( ( ctx->operation == MBEDTLS_DECRYPT && 00329 ilen <= block_size - ctx->unprocessed_len ) || 00330 ( ctx->operation == MBEDTLS_ENCRYPT && 00331 ilen < block_size - ctx->unprocessed_len ) ) 00332 { 00333 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, 00334 ilen ); 00335 00336 ctx->unprocessed_len += ilen; 00337 return( 0 ); 00338 } 00339 00340 /* 00341 * Process cached data first 00342 */ 00343 if( 0 != ctx->unprocessed_len ) 00344 { 00345 copy_len = block_size - ctx->unprocessed_len; 00346 00347 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, 00348 copy_len ); 00349 00350 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00351 ctx->operation, block_size, ctx->iv, 00352 ctx->unprocessed_data, output ) ) ) 00353 { 00354 return( ret ); 00355 } 00356 00357 *olen += block_size; 00358 output += block_size; 00359 ctx->unprocessed_len = 0; 00360 00361 input += copy_len; 00362 ilen -= copy_len; 00363 } 00364 00365 /* 00366 * Cache final, incomplete block 00367 */ 00368 if( 0 != ilen ) 00369 { 00370 if( 0 == block_size ) 00371 { 00372 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; 00373 } 00374 00375 copy_len = ilen % block_size; 00376 if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT ) 00377 copy_len = block_size; 00378 00379 memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), 00380 copy_len ); 00381 00382 ctx->unprocessed_len += copy_len; 00383 ilen -= copy_len; 00384 } 00385 00386 /* 00387 * Process remaining full blocks 00388 */ 00389 if( ilen ) 00390 { 00391 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00392 ctx->operation, ilen, ctx->iv, input, output ) ) ) 00393 { 00394 return( ret ); 00395 } 00396 00397 *olen += ilen; 00398 } 00399 00400 return( 0 ); 00401 } 00402 #endif /* MBEDTLS_CIPHER_MODE_CBC */ 00403 00404 #if defined(MBEDTLS_CIPHER_MODE_CFB) 00405 if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) 00406 { 00407 if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, 00408 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, 00409 input, output ) ) ) 00410 { 00411 return( ret ); 00412 } 00413 00414 *olen = ilen; 00415 00416 return( 0 ); 00417 } 00418 #endif /* MBEDTLS_CIPHER_MODE_CFB */ 00419 00420 #if defined(MBEDTLS_CIPHER_MODE_CTR) 00421 if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) 00422 { 00423 if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, 00424 ilen, &ctx->unprocessed_len, ctx->iv, 00425 ctx->unprocessed_data, input, output ) ) ) 00426 { 00427 return( ret ); 00428 } 00429 00430 *olen = ilen; 00431 00432 return( 0 ); 00433 } 00434 #endif /* MBEDTLS_CIPHER_MODE_CTR */ 00435 00436 #if defined(MBEDTLS_CIPHER_MODE_STREAM) 00437 if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) 00438 { 00439 if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, 00440 ilen, input, output ) ) ) 00441 { 00442 return( ret ); 00443 } 00444 00445 *olen = ilen; 00446 00447 return( 0 ); 00448 } 00449 #endif /* MBEDTLS_CIPHER_MODE_STREAM */ 00450 00451 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00452 } 00453 00454 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00455 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00456 /* 00457 * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len 00458 */ 00459 static void add_pkcs_padding( unsigned char *output, size_t output_len, 00460 size_t data_len ) 00461 { 00462 size_t padding_len = output_len - data_len; 00463 unsigned char i; 00464 00465 for( i = 0; i < padding_len; i++ ) 00466 output[data_len + i] = (unsigned char) padding_len; 00467 } 00468 00469 static int get_pkcs_padding( unsigned char *input, size_t input_len, 00470 size_t *data_len ) 00471 { 00472 size_t i, pad_idx; 00473 unsigned char padding_len, bad = 0; 00474 00475 if( NULL == input || NULL == data_len ) 00476 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00477 00478 padding_len = input[input_len - 1]; 00479 *data_len = input_len - padding_len; 00480 00481 /* Avoid logical || since it results in a branch */ 00482 bad |= padding_len > input_len; 00483 bad |= padding_len == 0; 00484 00485 /* The number of bytes checked must be independent of padding_len, 00486 * so pick input_len, which is usually 8 or 16 (one block) */ 00487 pad_idx = input_len - padding_len; 00488 for( i = 0; i < input_len; i++ ) 00489 bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); 00490 00491 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00492 } 00493 #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ 00494 00495 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) 00496 /* 00497 * One and zeros padding: fill with 80 00 ... 00 00498 */ 00499 static void add_one_and_zeros_padding( unsigned char *output, 00500 size_t output_len, size_t data_len ) 00501 { 00502 size_t padding_len = output_len - data_len; 00503 unsigned char i = 0; 00504 00505 output[data_len] = 0x80; 00506 for( i = 1; i < padding_len; i++ ) 00507 output[data_len + i] = 0x00; 00508 } 00509 00510 static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, 00511 size_t *data_len ) 00512 { 00513 size_t i; 00514 unsigned char done = 0, prev_done, bad; 00515 00516 if( NULL == input || NULL == data_len ) 00517 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00518 00519 bad = 0xFF; 00520 *data_len = 0; 00521 for( i = input_len; i > 0; i-- ) 00522 { 00523 prev_done = done; 00524 done |= ( input[i-1] != 0 ); 00525 *data_len |= ( i - 1 ) * ( done != prev_done ); 00526 bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); 00527 } 00528 00529 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00530 00531 } 00532 #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ 00533 00534 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) 00535 /* 00536 * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length 00537 */ 00538 static void add_zeros_and_len_padding( unsigned char *output, 00539 size_t output_len, size_t data_len ) 00540 { 00541 size_t padding_len = output_len - data_len; 00542 unsigned char i = 0; 00543 00544 for( i = 1; i < padding_len; i++ ) 00545 output[data_len + i - 1] = 0x00; 00546 output[output_len - 1] = (unsigned char) padding_len; 00547 } 00548 00549 static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, 00550 size_t *data_len ) 00551 { 00552 size_t i, pad_idx; 00553 unsigned char padding_len, bad = 0; 00554 00555 if( NULL == input || NULL == data_len ) 00556 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00557 00558 padding_len = input[input_len - 1]; 00559 *data_len = input_len - padding_len; 00560 00561 /* Avoid logical || since it results in a branch */ 00562 bad |= padding_len > input_len; 00563 bad |= padding_len == 0; 00564 00565 /* The number of bytes checked must be independent of padding_len */ 00566 pad_idx = input_len - padding_len; 00567 for( i = 0; i < input_len - 1; i++ ) 00568 bad |= input[i] * ( i >= pad_idx ); 00569 00570 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00571 } 00572 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ 00573 00574 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS) 00575 /* 00576 * Zero padding: fill with 00 ... 00 00577 */ 00578 static void add_zeros_padding( unsigned char *output, 00579 size_t output_len, size_t data_len ) 00580 { 00581 size_t i; 00582 00583 for( i = data_len; i < output_len; i++ ) 00584 output[i] = 0x00; 00585 } 00586 00587 static int get_zeros_padding( unsigned char *input, size_t input_len, 00588 size_t *data_len ) 00589 { 00590 size_t i; 00591 unsigned char done = 0, prev_done; 00592 00593 if( NULL == input || NULL == data_len ) 00594 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00595 00596 *data_len = 0; 00597 for( i = input_len; i > 0; i-- ) 00598 { 00599 prev_done = done; 00600 done |= ( input[i-1] != 0 ); 00601 *data_len |= i * ( done != prev_done ); 00602 } 00603 00604 return( 0 ); 00605 } 00606 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ 00607 00608 /* 00609 * No padding: don't pad :) 00610 * 00611 * There is no add_padding function (check for NULL in mbedtls_cipher_finish) 00612 * but a trivial get_padding function 00613 */ 00614 static int get_no_padding( unsigned char *input, size_t input_len, 00615 size_t *data_len ) 00616 { 00617 if( NULL == input || NULL == data_len ) 00618 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00619 00620 *data_len = input_len; 00621 00622 return( 0 ); 00623 } 00624 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00625 00626 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, 00627 unsigned char *output, size_t *olen ) 00628 { 00629 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 00630 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00631 00632 *olen = 0; 00633 00634 if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || 00635 MBEDTLS_MODE_CTR == ctx->cipher_info->mode || 00636 MBEDTLS_MODE_GCM == ctx->cipher_info->mode || 00637 MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) 00638 { 00639 return( 0 ); 00640 } 00641 00642 if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) 00643 { 00644 if( ctx->unprocessed_len != 0 ) 00645 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00646 00647 return( 0 ); 00648 } 00649 00650 #if defined(MBEDTLS_CIPHER_MODE_CBC) 00651 if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) 00652 { 00653 int ret = 0; 00654 00655 if( MBEDTLS_ENCRYPT == ctx->operation ) 00656 { 00657 /* check for 'no padding' mode */ 00658 if( NULL == ctx->add_padding ) 00659 { 00660 if( 0 != ctx->unprocessed_len ) 00661 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00662 00663 return( 0 ); 00664 } 00665 00666 ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), 00667 ctx->unprocessed_len ); 00668 } 00669 else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) 00670 { 00671 /* 00672 * For decrypt operations, expect a full block, 00673 * or an empty block if no padding 00674 */ 00675 if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) 00676 return( 0 ); 00677 00678 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00679 } 00680 00681 /* cipher block */ 00682 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00683 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, 00684 ctx->unprocessed_data, output ) ) ) 00685 { 00686 return( ret ); 00687 } 00688 00689 /* Set output size for decryption */ 00690 if( MBEDTLS_DECRYPT == ctx->operation ) 00691 return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), 00692 olen ); 00693 00694 /* Set output size for encryption */ 00695 *olen = mbedtls_cipher_get_block_size( ctx ); 00696 return( 0 ); 00697 } 00698 #else 00699 ((void) output); 00700 #endif /* MBEDTLS_CIPHER_MODE_CBC */ 00701 00702 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00703 } 00704 00705 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00706 int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ) 00707 { 00708 if( NULL == ctx || 00709 MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) 00710 { 00711 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00712 } 00713 00714 switch( mode ) 00715 { 00716 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00717 case MBEDTLS_PADDING_PKCS7: 00718 ctx->add_padding = add_pkcs_padding; 00719 ctx->get_padding = get_pkcs_padding; 00720 break; 00721 #endif 00722 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) 00723 case MBEDTLS_PADDING_ONE_AND_ZEROS: 00724 ctx->add_padding = add_one_and_zeros_padding; 00725 ctx->get_padding = get_one_and_zeros_padding; 00726 break; 00727 #endif 00728 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) 00729 case MBEDTLS_PADDING_ZEROS_AND_LEN: 00730 ctx->add_padding = add_zeros_and_len_padding; 00731 ctx->get_padding = get_zeros_and_len_padding; 00732 break; 00733 #endif 00734 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS) 00735 case MBEDTLS_PADDING_ZEROS: 00736 ctx->add_padding = add_zeros_padding; 00737 ctx->get_padding = get_zeros_padding; 00738 break; 00739 #endif 00740 case MBEDTLS_PADDING_NONE: 00741 ctx->add_padding = NULL; 00742 ctx->get_padding = get_no_padding; 00743 break; 00744 00745 default: 00746 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00747 } 00748 00749 return( 0 ); 00750 } 00751 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00752 00753 #if defined(MBEDTLS_GCM_C) 00754 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, 00755 unsigned char *tag, size_t tag_len ) 00756 { 00757 if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) 00758 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00759 00760 if( MBEDTLS_ENCRYPT != ctx->operation ) 00761 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00762 00763 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00764 return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); 00765 00766 return( 0 ); 00767 } 00768 00769 int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, 00770 const unsigned char *tag, size_t tag_len ) 00771 { 00772 int ret; 00773 00774 if( NULL == ctx || NULL == ctx->cipher_info || 00775 MBEDTLS_DECRYPT != ctx->operation ) 00776 { 00777 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00778 } 00779 00780 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00781 { 00782 unsigned char check_tag[16]; 00783 size_t i; 00784 int diff; 00785 00786 if( tag_len > sizeof( check_tag ) ) 00787 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00788 00789 if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, 00790 check_tag, tag_len ) ) ) 00791 { 00792 return( ret ); 00793 } 00794 00795 /* Check the tag in "constant-time" */ 00796 for( diff = 0, i = 0; i < tag_len; i++ ) 00797 diff |= tag[i] ^ check_tag[i]; 00798 00799 if( diff != 0 ) 00800 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); 00801 00802 return( 0 ); 00803 } 00804 00805 return( 0 ); 00806 } 00807 #endif /* MBEDTLS_GCM_C */ 00808 00809 /* 00810 * Packet-oriented wrapper for non-AEAD modes 00811 */ 00812 int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, 00813 const unsigned char *iv, size_t iv_len, 00814 const unsigned char *input, size_t ilen, 00815 unsigned char *output, size_t *olen ) 00816 { 00817 int ret; 00818 size_t finish_olen; 00819 00820 if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) 00821 return( ret ); 00822 00823 if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) 00824 return( ret ); 00825 00826 if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) 00827 return( ret ); 00828 00829 if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) 00830 return( ret ); 00831 00832 *olen += finish_olen; 00833 00834 return( 0 ); 00835 } 00836 00837 #if defined(MBEDTLS_CIPHER_MODE_AEAD) 00838 /* 00839 * Packet-oriented encryption for AEAD modes 00840 */ 00841 int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, 00842 const unsigned char *iv, size_t iv_len, 00843 const unsigned char *ad, size_t ad_len, 00844 const unsigned char *input, size_t ilen, 00845 unsigned char *output, size_t *olen, 00846 unsigned char *tag, size_t tag_len ) 00847 { 00848 #if defined(MBEDTLS_GCM_C) 00849 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00850 { 00851 *olen = ilen; 00852 return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen, 00853 iv, iv_len, ad, ad_len, input, output, 00854 tag_len, tag ) ); 00855 } 00856 #endif /* MBEDTLS_GCM_C */ 00857 #if defined(MBEDTLS_CCM_C) 00858 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) 00859 { 00860 *olen = ilen; 00861 return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, 00862 iv, iv_len, ad, ad_len, input, output, 00863 tag, tag_len ) ); 00864 } 00865 #endif /* MBEDTLS_CCM_C */ 00866 00867 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00868 } 00869 00870 /* 00871 * Packet-oriented decryption for AEAD modes 00872 */ 00873 int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, 00874 const unsigned char *iv, size_t iv_len, 00875 const unsigned char *ad, size_t ad_len, 00876 const unsigned char *input, size_t ilen, 00877 unsigned char *output, size_t *olen, 00878 const unsigned char *tag, size_t tag_len ) 00879 { 00880 #if defined(MBEDTLS_GCM_C) 00881 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00882 { 00883 int ret; 00884 00885 *olen = ilen; 00886 ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, 00887 iv, iv_len, ad, ad_len, 00888 tag, tag_len, input, output ); 00889 00890 if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) 00891 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; 00892 00893 return( ret ); 00894 } 00895 #endif /* MBEDTLS_GCM_C */ 00896 #if defined(MBEDTLS_CCM_C) 00897 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) 00898 { 00899 int ret; 00900 00901 *olen = ilen; 00902 ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, 00903 iv, iv_len, ad, ad_len, 00904 input, output, tag, tag_len ); 00905 00906 if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) 00907 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; 00908 00909 return( ret ); 00910 } 00911 #endif /* MBEDTLS_CCM_C */ 00912 00913 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00914 } 00915 #endif /* MBEDTLS_CIPHER_MODE_AEAD */ 00916 00917 #endif /* MBEDTLS_CIPHER_C */
Generated on Tue Jul 12 2022 17:25:41 by
