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