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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo 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 = (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 12:28:27 by
