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 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 = (unsigned char*)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 size_t block_size = 0; 00256 00257 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 00258 { 00259 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00260 } 00261 00262 *olen = 0; 00263 block_size = mbedtls_cipher_get_block_size( ctx ); 00264 00265 if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) 00266 { 00267 if( ilen != block_size ) 00268 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00269 00270 *olen = ilen; 00271 00272 if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, 00273 ctx->operation, input, output ) ) ) 00274 { 00275 return( ret ); 00276 } 00277 00278 return( 0 ); 00279 } 00280 00281 #if defined(MBEDTLS_GCM_C) 00282 if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) 00283 { 00284 *olen = ilen; 00285 return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, 00286 output ); 00287 } 00288 #endif 00289 00290 if ( 0 == block_size ) 00291 { 00292 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; 00293 } 00294 00295 if( input == output && 00296 ( ctx->unprocessed_len != 0 || ilen % block_size ) ) 00297 { 00298 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00299 } 00300 00301 #if defined(MBEDTLS_CIPHER_MODE_CBC) 00302 if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) 00303 { 00304 size_t copy_len = 0; 00305 00306 /* 00307 * If there is not enough data for a full block, cache it. 00308 */ 00309 if( ( ctx->operation == MBEDTLS_DECRYPT && 00310 ilen + ctx->unprocessed_len <= block_size ) || 00311 ( ctx->operation == MBEDTLS_ENCRYPT && 00312 ilen + ctx->unprocessed_len < block_size ) ) 00313 { 00314 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, 00315 ilen ); 00316 00317 ctx->unprocessed_len += ilen; 00318 return( 0 ); 00319 } 00320 00321 /* 00322 * Process cached data first 00323 */ 00324 if( 0 != ctx->unprocessed_len ) 00325 { 00326 copy_len = block_size - ctx->unprocessed_len; 00327 00328 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, 00329 copy_len ); 00330 00331 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00332 ctx->operation, block_size, ctx->iv, 00333 ctx->unprocessed_data, output ) ) ) 00334 { 00335 return( ret ); 00336 } 00337 00338 *olen += block_size; 00339 output += block_size; 00340 ctx->unprocessed_len = 0; 00341 00342 input += copy_len; 00343 ilen -= copy_len; 00344 } 00345 00346 /* 00347 * Cache final, incomplete block 00348 */ 00349 if( 0 != ilen ) 00350 { 00351 if( 0 == block_size ) 00352 { 00353 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; 00354 } 00355 00356 copy_len = ilen % block_size; 00357 if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT ) 00358 copy_len = block_size; 00359 00360 memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), 00361 copy_len ); 00362 00363 ctx->unprocessed_len += copy_len; 00364 ilen -= copy_len; 00365 } 00366 00367 /* 00368 * Process remaining full blocks 00369 */ 00370 if( ilen ) 00371 { 00372 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00373 ctx->operation, ilen, ctx->iv, input, output ) ) ) 00374 { 00375 return( ret ); 00376 } 00377 00378 *olen += ilen; 00379 } 00380 00381 return( 0 ); 00382 } 00383 #endif /* MBEDTLS_CIPHER_MODE_CBC */ 00384 00385 #if defined(MBEDTLS_CIPHER_MODE_CFB) 00386 if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) 00387 { 00388 if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, 00389 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, 00390 input, output ) ) ) 00391 { 00392 return( ret ); 00393 } 00394 00395 *olen = ilen; 00396 00397 return( 0 ); 00398 } 00399 #endif /* MBEDTLS_CIPHER_MODE_CFB */ 00400 00401 #if defined(MBEDTLS_CIPHER_MODE_CTR) 00402 if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) 00403 { 00404 if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, 00405 ilen, &ctx->unprocessed_len, ctx->iv, 00406 ctx->unprocessed_data, input, output ) ) ) 00407 { 00408 return( ret ); 00409 } 00410 00411 *olen = ilen; 00412 00413 return( 0 ); 00414 } 00415 #endif /* MBEDTLS_CIPHER_MODE_CTR */ 00416 00417 #if defined(MBEDTLS_CIPHER_MODE_STREAM) 00418 if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) 00419 { 00420 if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, 00421 ilen, input, output ) ) ) 00422 { 00423 return( ret ); 00424 } 00425 00426 *olen = ilen; 00427 00428 return( 0 ); 00429 } 00430 #endif /* MBEDTLS_CIPHER_MODE_STREAM */ 00431 00432 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00433 } 00434 00435 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00436 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00437 /* 00438 * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len 00439 */ 00440 static void add_pkcs_padding( unsigned char *output, size_t output_len, 00441 size_t data_len ) 00442 { 00443 size_t padding_len = output_len - data_len; 00444 unsigned char i; 00445 00446 for( i = 0; i < padding_len; i++ ) 00447 output[data_len + i] = (unsigned char) padding_len; 00448 } 00449 00450 static int get_pkcs_padding( unsigned char *input, size_t input_len, 00451 size_t *data_len ) 00452 { 00453 size_t i, pad_idx; 00454 unsigned char padding_len, bad = 0; 00455 00456 if( NULL == input || NULL == data_len ) 00457 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00458 00459 padding_len = input[input_len - 1]; 00460 *data_len = input_len - padding_len; 00461 00462 /* Avoid logical || since it results in a branch */ 00463 bad |= padding_len > input_len; 00464 bad |= padding_len == 0; 00465 00466 /* The number of bytes checked must be independent of padding_len, 00467 * so pick input_len, which is usually 8 or 16 (one block) */ 00468 pad_idx = input_len - padding_len; 00469 for( i = 0; i < input_len; i++ ) 00470 bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); 00471 00472 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00473 } 00474 #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ 00475 00476 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) 00477 /* 00478 * One and zeros padding: fill with 80 00 ... 00 00479 */ 00480 static void add_one_and_zeros_padding( unsigned char *output, 00481 size_t output_len, size_t data_len ) 00482 { 00483 size_t padding_len = output_len - data_len; 00484 unsigned char i = 0; 00485 00486 output[data_len] = 0x80; 00487 for( i = 1; i < padding_len; i++ ) 00488 output[data_len + i] = 0x00; 00489 } 00490 00491 static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, 00492 size_t *data_len ) 00493 { 00494 size_t i; 00495 unsigned char done = 0, prev_done, bad; 00496 00497 if( NULL == input || NULL == data_len ) 00498 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00499 00500 bad = 0xFF; 00501 *data_len = 0; 00502 for( i = input_len; i > 0; i-- ) 00503 { 00504 prev_done = done; 00505 done |= ( input[i-1] != 0 ); 00506 *data_len |= ( i - 1 ) * ( done != prev_done ); 00507 bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); 00508 } 00509 00510 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00511 00512 } 00513 #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ 00514 00515 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) 00516 /* 00517 * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length 00518 */ 00519 static void add_zeros_and_len_padding( unsigned char *output, 00520 size_t output_len, size_t data_len ) 00521 { 00522 size_t padding_len = output_len - data_len; 00523 unsigned char i = 0; 00524 00525 for( i = 1; i < padding_len; i++ ) 00526 output[data_len + i - 1] = 0x00; 00527 output[output_len - 1] = (unsigned char) padding_len; 00528 } 00529 00530 static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, 00531 size_t *data_len ) 00532 { 00533 size_t i, pad_idx; 00534 unsigned char padding_len, bad = 0; 00535 00536 if( NULL == input || NULL == data_len ) 00537 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00538 00539 padding_len = input[input_len - 1]; 00540 *data_len = input_len - padding_len; 00541 00542 /* Avoid logical || since it results in a branch */ 00543 bad |= padding_len > input_len; 00544 bad |= padding_len == 0; 00545 00546 /* The number of bytes checked must be independent of padding_len */ 00547 pad_idx = input_len - padding_len; 00548 for( i = 0; i < input_len - 1; i++ ) 00549 bad |= input[i] * ( i >= pad_idx ); 00550 00551 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00552 } 00553 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ 00554 00555 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS) 00556 /* 00557 * Zero padding: fill with 00 ... 00 00558 */ 00559 static void add_zeros_padding( unsigned char *output, 00560 size_t output_len, size_t data_len ) 00561 { 00562 size_t i; 00563 00564 for( i = data_len; i < output_len; i++ ) 00565 output[i] = 0x00; 00566 } 00567 00568 static int get_zeros_padding( unsigned char *input, size_t input_len, 00569 size_t *data_len ) 00570 { 00571 size_t i; 00572 unsigned char done = 0, prev_done; 00573 00574 if( NULL == input || NULL == data_len ) 00575 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00576 00577 *data_len = 0; 00578 for( i = input_len; i > 0; i-- ) 00579 { 00580 prev_done = done; 00581 done |= ( input[i-1] != 0 ); 00582 *data_len |= i * ( done != prev_done ); 00583 } 00584 00585 return( 0 ); 00586 } 00587 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ 00588 00589 /* 00590 * No padding: don't pad :) 00591 * 00592 * There is no add_padding function (check for NULL in mbedtls_cipher_finish) 00593 * but a trivial get_padding function 00594 */ 00595 static int get_no_padding( unsigned char *input, size_t input_len, 00596 size_t *data_len ) 00597 { 00598 if( NULL == input || NULL == data_len ) 00599 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00600 00601 *data_len = input_len; 00602 00603 return( 0 ); 00604 } 00605 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00606 00607 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, 00608 unsigned char *output, size_t *olen ) 00609 { 00610 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 00611 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00612 00613 *olen = 0; 00614 00615 if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || 00616 MBEDTLS_MODE_CTR == ctx->cipher_info->mode || 00617 MBEDTLS_MODE_GCM == ctx->cipher_info->mode || 00618 MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) 00619 { 00620 return( 0 ); 00621 } 00622 00623 if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) 00624 { 00625 if( ctx->unprocessed_len != 0 ) 00626 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00627 00628 return( 0 ); 00629 } 00630 00631 #if defined(MBEDTLS_CIPHER_MODE_CBC) 00632 if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) 00633 { 00634 int ret = 0; 00635 00636 if( MBEDTLS_ENCRYPT == ctx->operation ) 00637 { 00638 /* check for 'no padding' mode */ 00639 if( NULL == ctx->add_padding ) 00640 { 00641 if( 0 != ctx->unprocessed_len ) 00642 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00643 00644 return( 0 ); 00645 } 00646 00647 ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), 00648 ctx->unprocessed_len ); 00649 } 00650 else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) 00651 { 00652 /* 00653 * For decrypt operations, expect a full block, 00654 * or an empty block if no padding 00655 */ 00656 if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) 00657 return( 0 ); 00658 00659 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00660 } 00661 00662 /* cipher block */ 00663 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00664 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, 00665 ctx->unprocessed_data, output ) ) ) 00666 { 00667 return( ret ); 00668 } 00669 00670 /* Set output size for decryption */ 00671 if( MBEDTLS_DECRYPT == ctx->operation ) 00672 return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), 00673 olen ); 00674 00675 /* Set output size for encryption */ 00676 *olen = mbedtls_cipher_get_block_size( ctx ); 00677 return( 0 ); 00678 } 00679 #else 00680 ((void) output); 00681 #endif /* MBEDTLS_CIPHER_MODE_CBC */ 00682 00683 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00684 } 00685 00686 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00687 int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ) 00688 { 00689 if( NULL == ctx || 00690 MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) 00691 { 00692 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00693 } 00694 00695 switch( mode ) 00696 { 00697 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00698 case MBEDTLS_PADDING_PKCS7: 00699 ctx->add_padding = add_pkcs_padding; 00700 ctx->get_padding = get_pkcs_padding; 00701 break; 00702 #endif 00703 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) 00704 case MBEDTLS_PADDING_ONE_AND_ZEROS: 00705 ctx->add_padding = add_one_and_zeros_padding; 00706 ctx->get_padding = get_one_and_zeros_padding; 00707 break; 00708 #endif 00709 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) 00710 case MBEDTLS_PADDING_ZEROS_AND_LEN: 00711 ctx->add_padding = add_zeros_and_len_padding; 00712 ctx->get_padding = get_zeros_and_len_padding; 00713 break; 00714 #endif 00715 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS) 00716 case MBEDTLS_PADDING_ZEROS: 00717 ctx->add_padding = add_zeros_padding; 00718 ctx->get_padding = get_zeros_padding; 00719 break; 00720 #endif 00721 case MBEDTLS_PADDING_NONE: 00722 ctx->add_padding = NULL; 00723 ctx->get_padding = get_no_padding; 00724 break; 00725 00726 default: 00727 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00728 } 00729 00730 return( 0 ); 00731 } 00732 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00733 00734 #if defined(MBEDTLS_GCM_C) 00735 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, 00736 unsigned char *tag, size_t tag_len ) 00737 { 00738 if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) 00739 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00740 00741 if( MBEDTLS_ENCRYPT != ctx->operation ) 00742 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00743 00744 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00745 return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); 00746 00747 return( 0 ); 00748 } 00749 00750 int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, 00751 const unsigned char *tag, size_t tag_len ) 00752 { 00753 int ret; 00754 00755 if( NULL == ctx || NULL == ctx->cipher_info || 00756 MBEDTLS_DECRYPT != ctx->operation ) 00757 { 00758 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00759 } 00760 00761 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00762 { 00763 unsigned char check_tag[16]; 00764 size_t i; 00765 int diff; 00766 00767 if( tag_len > sizeof( check_tag ) ) 00768 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00769 00770 if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, 00771 check_tag, tag_len ) ) ) 00772 { 00773 return( ret ); 00774 } 00775 00776 /* Check the tag in "constant-time" */ 00777 for( diff = 0, i = 0; i < tag_len; i++ ) 00778 diff |= tag[i] ^ check_tag[i]; 00779 00780 if( diff != 0 ) 00781 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); 00782 00783 return( 0 ); 00784 } 00785 00786 return( 0 ); 00787 } 00788 #endif /* MBEDTLS_GCM_C */ 00789 00790 /* 00791 * Packet-oriented wrapper for non-AEAD modes 00792 */ 00793 int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, 00794 const unsigned char *iv, size_t iv_len, 00795 const unsigned char *input, size_t ilen, 00796 unsigned char *output, size_t *olen ) 00797 { 00798 int ret; 00799 size_t finish_olen; 00800 00801 if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) 00802 return( ret ); 00803 00804 if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) 00805 return( ret ); 00806 00807 if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) 00808 return( ret ); 00809 00810 if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) 00811 return( ret ); 00812 00813 *olen += finish_olen; 00814 00815 return( 0 ); 00816 } 00817 00818 #if defined(MBEDTLS_CIPHER_MODE_AEAD) 00819 /* 00820 * Packet-oriented encryption for AEAD modes 00821 */ 00822 int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, 00823 const unsigned char *iv, size_t iv_len, 00824 const unsigned char *ad, size_t ad_len, 00825 const unsigned char *input, size_t ilen, 00826 unsigned char *output, size_t *olen, 00827 unsigned char *tag, size_t tag_len ) 00828 { 00829 #if defined(MBEDTLS_GCM_C) 00830 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00831 { 00832 *olen = ilen; 00833 return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen, 00834 iv, iv_len, ad, ad_len, input, output, 00835 tag_len, tag ) ); 00836 } 00837 #endif /* MBEDTLS_GCM_C */ 00838 #if defined(MBEDTLS_CCM_C) 00839 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) 00840 { 00841 *olen = ilen; 00842 return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, 00843 iv, iv_len, ad, ad_len, input, output, 00844 tag, tag_len ) ); 00845 } 00846 #endif /* MBEDTLS_CCM_C */ 00847 00848 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00849 } 00850 00851 /* 00852 * Packet-oriented decryption for AEAD modes 00853 */ 00854 int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, 00855 const unsigned char *iv, size_t iv_len, 00856 const unsigned char *ad, size_t ad_len, 00857 const unsigned char *input, size_t ilen, 00858 unsigned char *output, size_t *olen, 00859 const unsigned char *tag, size_t tag_len ) 00860 { 00861 #if defined(MBEDTLS_GCM_C) 00862 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00863 { 00864 int ret; 00865 00866 *olen = ilen; 00867 ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, 00868 iv, iv_len, ad, ad_len, 00869 tag, tag_len, input, output ); 00870 00871 if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) 00872 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; 00873 00874 return( ret ); 00875 } 00876 #endif /* MBEDTLS_GCM_C */ 00877 #if defined(MBEDTLS_CCM_C) 00878 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) 00879 { 00880 int ret; 00881 00882 *olen = ilen; 00883 ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, 00884 iv, iv_len, ad, ad_len, 00885 input, output, tag, tag_len ); 00886 00887 if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) 00888 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; 00889 00890 return( ret ); 00891 } 00892 #endif /* MBEDTLS_CCM_C */ 00893 00894 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00895 } 00896 #endif /* MBEDTLS_CIPHER_MODE_AEAD */ 00897 00898 #endif /* MBEDTLS_CIPHER_C */
Generated on Tue Jul 12 2022 13:04:54 by
1.7.2