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