Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbedtls by
cipher.c
00001 /** 00002 * \file cipher.c 00003 * 00004 * \brief Generic cipher wrapper for mbed TLS 00005 * 00006 * \author Adriaan de Jong <dejong@fox-it.com> 00007 * 00008 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00009 * SPDX-License-Identifier: Apache-2.0 00010 * 00011 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00012 * not use this file except in compliance with the License. 00013 * You may obtain a copy of the License at 00014 * 00015 * http://www.apache.org/licenses/LICENSE-2.0 00016 * 00017 * Unless required by applicable law or agreed to in writing, software 00018 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00019 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 * See the License for the specific language governing permissions and 00021 * limitations under the License. 00022 * 00023 * This file is part of mbed TLS (https://tls.mbed.org) 00024 */ 00025 00026 #if !defined(MBEDTLS_CONFIG_FILE) 00027 #include "mbedtls/config.h" 00028 #else 00029 #include MBEDTLS_CONFIG_FILE 00030 #endif 00031 00032 #if defined(MBEDTLS_CIPHER_C) 00033 00034 #include "mbedtls/cipher.h" 00035 #include "mbedtls/cipher_internal.h" 00036 00037 #include <stdlib.h> 00038 #include <string.h> 00039 00040 #if defined(MBEDTLS_GCM_C) 00041 #include "mbedtls/gcm.h" 00042 #endif 00043 00044 #if defined(MBEDTLS_CCM_C) 00045 #include "mbedtls/ccm.h" 00046 #endif 00047 00048 #if defined(MBEDTLS_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
