Marco Zecchini
/
Example_RTOS
Rtos API example
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_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 Sun Jul 17 2022 08:25:21 by 1.7.2