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: nRF51_Vdd TextLCD BME280
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 #include "mbedtls/platform_util.h" 00037 00038 #include <stdlib.h> 00039 #include <string.h> 00040 00041 #if defined(MBEDTLS_CHACHAPOLY_C) 00042 #include "mbedtls/chachapoly.h" 00043 #endif 00044 00045 #if defined(MBEDTLS_GCM_C) 00046 #include "mbedtls/gcm.h" 00047 #endif 00048 00049 #if defined(MBEDTLS_CCM_C) 00050 #include "mbedtls/ccm.h" 00051 #endif 00052 00053 #if defined(MBEDTLS_CHACHA20_C) 00054 #include "mbedtls/chacha20.h" 00055 #endif 00056 00057 #if defined(MBEDTLS_CMAC_C) 00058 #include "mbedtls/cmac.h" 00059 #endif 00060 00061 #if defined(MBEDTLS_PLATFORM_C) 00062 #include "mbedtls/platform.h" 00063 #else 00064 #define mbedtls_calloc calloc 00065 #define mbedtls_free free 00066 #endif 00067 00068 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) 00069 /* Compare the contents of two buffers in constant time. 00070 * Returns 0 if the contents are bitwise identical, otherwise returns 00071 * a non-zero value. 00072 * This is currently only used by GCM and ChaCha20+Poly1305. 00073 */ 00074 static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len ) 00075 { 00076 const unsigned char *p1 = (const unsigned char*) v1; 00077 const unsigned char *p2 = (const unsigned char*) v2; 00078 size_t i; 00079 unsigned char diff; 00080 00081 for( diff = 0, i = 0; i < len; i++ ) 00082 diff |= p1[i] ^ p2[i]; 00083 00084 return (int)diff; 00085 } 00086 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ 00087 00088 static int supported_init = 0; 00089 00090 const int *mbedtls_cipher_list( void ) 00091 { 00092 const mbedtls_cipher_definition_t *def; 00093 int *type; 00094 00095 if( ! supported_init ) 00096 { 00097 def = mbedtls_cipher_definitions; 00098 type = mbedtls_cipher_supported; 00099 00100 while( def->type != 0 ) 00101 *type++ = (*def++).type; 00102 00103 *type = 0; 00104 00105 supported_init = 1; 00106 } 00107 00108 return( mbedtls_cipher_supported ); 00109 } 00110 00111 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ) 00112 { 00113 const mbedtls_cipher_definition_t *def; 00114 00115 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) 00116 if( def->type == cipher_type ) 00117 return( def->info ); 00118 00119 return( NULL ); 00120 } 00121 00122 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ) 00123 { 00124 const mbedtls_cipher_definition_t *def; 00125 00126 if( NULL == cipher_name ) 00127 return( NULL ); 00128 00129 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) 00130 if( ! strcmp( def->info->name, cipher_name ) ) 00131 return( def->info ); 00132 00133 return( NULL ); 00134 } 00135 00136 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, 00137 int key_bitlen, 00138 const mbedtls_cipher_mode_t mode ) 00139 { 00140 const mbedtls_cipher_definition_t *def; 00141 00142 for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) 00143 if( def->info->base->cipher == cipher_id && 00144 def->info->key_bitlen == (unsigned) key_bitlen && 00145 def->info->mode == mode ) 00146 return( def->info ); 00147 00148 return( NULL ); 00149 } 00150 00151 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) 00152 { 00153 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); 00154 } 00155 00156 void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) 00157 { 00158 if( ctx == NULL ) 00159 return; 00160 00161 #if defined(MBEDTLS_CMAC_C) 00162 if( ctx->cmac_ctx ) 00163 { 00164 mbedtls_platform_zeroize( ctx->cmac_ctx, 00165 sizeof( mbedtls_cmac_context_t ) ); 00166 mbedtls_free( ctx->cmac_ctx ); 00167 } 00168 #endif 00169 00170 if( ctx->cipher_ctx ) 00171 ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); 00172 00173 mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); 00174 } 00175 00176 int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ) 00177 { 00178 if( NULL == cipher_info || NULL == ctx ) 00179 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00180 00181 memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); 00182 00183 if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) 00184 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); 00185 00186 ctx->cipher_info = cipher_info; 00187 00188 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00189 /* 00190 * Ignore possible errors caused by a cipher mode that doesn't use padding 00191 */ 00192 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00193 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); 00194 #else 00195 (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); 00196 #endif 00197 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00198 00199 return( 0 ); 00200 } 00201 00202 int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, 00203 int key_bitlen, const mbedtls_operation_t operation ) 00204 { 00205 if( NULL == ctx || NULL == ctx->cipher_info ) 00206 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00207 00208 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && 00209 (int) ctx->cipher_info->key_bitlen != key_bitlen ) 00210 { 00211 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00212 } 00213 00214 ctx->key_bitlen = key_bitlen; 00215 ctx->operation = operation; 00216 00217 /* 00218 * For OFB, CFB and CTR mode always use the encryption key schedule 00219 */ 00220 if( MBEDTLS_ENCRYPT == operation || 00221 MBEDTLS_MODE_CFB == ctx->cipher_info->mode || 00222 MBEDTLS_MODE_OFB == ctx->cipher_info->mode || 00223 MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) 00224 { 00225 return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, 00226 ctx->key_bitlen ); 00227 } 00228 00229 if( MBEDTLS_DECRYPT == operation ) 00230 return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, 00231 ctx->key_bitlen ); 00232 00233 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00234 } 00235 00236 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, 00237 const unsigned char *iv, size_t iv_len ) 00238 { 00239 size_t actual_iv_size; 00240 00241 if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) 00242 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00243 00244 /* avoid buffer overflow in ctx->iv */ 00245 if( iv_len > MBEDTLS_MAX_IV_LENGTH ) 00246 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00247 00248 if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) 00249 actual_iv_size = iv_len; 00250 else 00251 { 00252 actual_iv_size = ctx->cipher_info->iv_size; 00253 00254 /* avoid reading past the end of input buffer */ 00255 if( actual_iv_size > iv_len ) 00256 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00257 } 00258 00259 #if defined(MBEDTLS_CHACHA20_C) 00260 if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) 00261 { 00262 if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx, 00263 iv, 00264 0U ) ) /* Initial counter value */ 00265 { 00266 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00267 } 00268 } 00269 #endif 00270 00271 memcpy( ctx->iv, iv, actual_iv_size ); 00272 ctx->iv_size = actual_iv_size; 00273 00274 return( 0 ); 00275 } 00276 00277 int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) 00278 { 00279 if( NULL == ctx || NULL == ctx->cipher_info ) 00280 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00281 00282 ctx->unprocessed_len = 0; 00283 00284 return( 0 ); 00285 } 00286 00287 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) 00288 int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, 00289 const unsigned char *ad, size_t ad_len ) 00290 { 00291 if( NULL == ctx || NULL == ctx->cipher_info ) 00292 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00293 00294 #if defined(MBEDTLS_GCM_C) 00295 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00296 { 00297 return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, 00298 ctx->iv, ctx->iv_size, ad, ad_len ); 00299 } 00300 #endif 00301 00302 #if defined(MBEDTLS_CHACHAPOLY_C) 00303 if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) 00304 { 00305 int result; 00306 mbedtls_chachapoly_mode_t mode; 00307 00308 mode = ( ctx->operation == MBEDTLS_ENCRYPT ) 00309 ? MBEDTLS_CHACHAPOLY_ENCRYPT 00310 : MBEDTLS_CHACHAPOLY_DECRYPT; 00311 00312 result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, 00313 ctx->iv, 00314 mode ); 00315 if ( result != 0 ) 00316 return( result ); 00317 00318 return mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, 00319 ad, ad_len ); 00320 } 00321 #endif 00322 00323 return( 0 ); 00324 } 00325 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ 00326 00327 int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, 00328 size_t ilen, unsigned char *output, size_t *olen ) 00329 { 00330 int ret; 00331 size_t block_size = 0; 00332 00333 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 00334 { 00335 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00336 } 00337 00338 *olen = 0; 00339 block_size = mbedtls_cipher_get_block_size( ctx ); 00340 00341 if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) 00342 { 00343 if( ilen != block_size ) 00344 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00345 00346 *olen = ilen; 00347 00348 if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, 00349 ctx->operation, input, output ) ) ) 00350 { 00351 return( ret ); 00352 } 00353 00354 return( 0 ); 00355 } 00356 00357 #if defined(MBEDTLS_GCM_C) 00358 if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) 00359 { 00360 *olen = ilen; 00361 return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, 00362 output ); 00363 } 00364 #endif 00365 00366 #if defined(MBEDTLS_CHACHAPOLY_C) 00367 if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) 00368 { 00369 *olen = ilen; 00370 return mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, 00371 ilen, input, output ); 00372 } 00373 #endif 00374 00375 if ( 0 == block_size ) 00376 { 00377 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; 00378 } 00379 00380 if( input == output && 00381 ( ctx->unprocessed_len != 0 || ilen % block_size ) ) 00382 { 00383 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00384 } 00385 00386 #if defined(MBEDTLS_CIPHER_MODE_CBC) 00387 if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) 00388 { 00389 size_t copy_len = 0; 00390 00391 /* 00392 * If there is not enough data for a full block, cache it. 00393 */ 00394 if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding && 00395 ilen <= block_size - ctx->unprocessed_len ) || 00396 ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding && 00397 ilen < block_size - ctx->unprocessed_len ) || 00398 ( ctx->operation == MBEDTLS_ENCRYPT && 00399 ilen < block_size - ctx->unprocessed_len ) ) 00400 { 00401 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, 00402 ilen ); 00403 00404 ctx->unprocessed_len += ilen; 00405 return( 0 ); 00406 } 00407 00408 /* 00409 * Process cached data first 00410 */ 00411 if( 0 != ctx->unprocessed_len ) 00412 { 00413 copy_len = block_size - ctx->unprocessed_len; 00414 00415 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, 00416 copy_len ); 00417 00418 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00419 ctx->operation, block_size, ctx->iv, 00420 ctx->unprocessed_data, output ) ) ) 00421 { 00422 return( ret ); 00423 } 00424 00425 *olen += block_size; 00426 output += block_size; 00427 ctx->unprocessed_len = 0; 00428 00429 input += copy_len; 00430 ilen -= copy_len; 00431 } 00432 00433 /* 00434 * Cache final, incomplete block 00435 */ 00436 if( 0 != ilen ) 00437 { 00438 if( 0 == block_size ) 00439 { 00440 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; 00441 } 00442 00443 /* Encryption: only cache partial blocks 00444 * Decryption w/ padding: always keep at least one whole block 00445 * Decryption w/o padding: only cache partial blocks 00446 */ 00447 copy_len = ilen % block_size; 00448 if( copy_len == 0 && 00449 ctx->operation == MBEDTLS_DECRYPT && 00450 NULL != ctx->add_padding) 00451 { 00452 copy_len = block_size; 00453 } 00454 00455 memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), 00456 copy_len ); 00457 00458 ctx->unprocessed_len += copy_len; 00459 ilen -= copy_len; 00460 } 00461 00462 /* 00463 * Process remaining full blocks 00464 */ 00465 if( ilen ) 00466 { 00467 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00468 ctx->operation, ilen, ctx->iv, input, output ) ) ) 00469 { 00470 return( ret ); 00471 } 00472 00473 *olen += ilen; 00474 } 00475 00476 return( 0 ); 00477 } 00478 #endif /* MBEDTLS_CIPHER_MODE_CBC */ 00479 00480 #if defined(MBEDTLS_CIPHER_MODE_CFB) 00481 if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) 00482 { 00483 if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, 00484 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, 00485 input, output ) ) ) 00486 { 00487 return( ret ); 00488 } 00489 00490 *olen = ilen; 00491 00492 return( 0 ); 00493 } 00494 #endif /* MBEDTLS_CIPHER_MODE_CFB */ 00495 00496 #if defined(MBEDTLS_CIPHER_MODE_OFB) 00497 if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB ) 00498 { 00499 if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx, 00500 ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) ) 00501 { 00502 return( ret ); 00503 } 00504 00505 *olen = ilen; 00506 00507 return( 0 ); 00508 } 00509 #endif /* MBEDTLS_CIPHER_MODE_OFB */ 00510 00511 #if defined(MBEDTLS_CIPHER_MODE_CTR) 00512 if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) 00513 { 00514 if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, 00515 ilen, &ctx->unprocessed_len, ctx->iv, 00516 ctx->unprocessed_data, input, output ) ) ) 00517 { 00518 return( ret ); 00519 } 00520 00521 *olen = ilen; 00522 00523 return( 0 ); 00524 } 00525 #endif /* MBEDTLS_CIPHER_MODE_CTR */ 00526 00527 #if defined(MBEDTLS_CIPHER_MODE_XTS) 00528 if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS ) 00529 { 00530 if( ctx->unprocessed_len > 0 ) { 00531 /* We can only process an entire data unit at a time. */ 00532 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00533 } 00534 00535 ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx, 00536 ctx->operation, ilen, ctx->iv, input, output ); 00537 if( ret != 0 ) 00538 { 00539 return( ret ); 00540 } 00541 00542 *olen = ilen; 00543 00544 return( 0 ); 00545 } 00546 #endif /* MBEDTLS_CIPHER_MODE_XTS */ 00547 00548 #if defined(MBEDTLS_CIPHER_MODE_STREAM) 00549 if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) 00550 { 00551 if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, 00552 ilen, input, output ) ) ) 00553 { 00554 return( ret ); 00555 } 00556 00557 *olen = ilen; 00558 00559 return( 0 ); 00560 } 00561 #endif /* MBEDTLS_CIPHER_MODE_STREAM */ 00562 00563 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00564 } 00565 00566 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00567 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00568 /* 00569 * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len 00570 */ 00571 static void add_pkcs_padding( unsigned char *output, size_t output_len, 00572 size_t data_len ) 00573 { 00574 size_t padding_len = output_len - data_len; 00575 unsigned char i; 00576 00577 for( i = 0; i < padding_len; i++ ) 00578 output[data_len + i] = (unsigned char) padding_len; 00579 } 00580 00581 static int get_pkcs_padding( unsigned char *input, size_t input_len, 00582 size_t *data_len ) 00583 { 00584 size_t i, pad_idx; 00585 unsigned char padding_len, bad = 0; 00586 00587 if( NULL == input || NULL == data_len ) 00588 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00589 00590 padding_len = input[input_len - 1]; 00591 *data_len = input_len - padding_len; 00592 00593 /* Avoid logical || since it results in a branch */ 00594 bad |= padding_len > input_len; 00595 bad |= padding_len == 0; 00596 00597 /* The number of bytes checked must be independent of padding_len, 00598 * so pick input_len, which is usually 8 or 16 (one block) */ 00599 pad_idx = input_len - padding_len; 00600 for( i = 0; i < input_len; i++ ) 00601 bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); 00602 00603 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00604 } 00605 #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ 00606 00607 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) 00608 /* 00609 * One and zeros padding: fill with 80 00 ... 00 00610 */ 00611 static void add_one_and_zeros_padding( unsigned char *output, 00612 size_t output_len, size_t data_len ) 00613 { 00614 size_t padding_len = output_len - data_len; 00615 unsigned char i = 0; 00616 00617 output[data_len] = 0x80; 00618 for( i = 1; i < padding_len; i++ ) 00619 output[data_len + i] = 0x00; 00620 } 00621 00622 static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, 00623 size_t *data_len ) 00624 { 00625 size_t i; 00626 unsigned char done = 0, prev_done, bad; 00627 00628 if( NULL == input || NULL == data_len ) 00629 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00630 00631 bad = 0x80; 00632 *data_len = 0; 00633 for( i = input_len; i > 0; i-- ) 00634 { 00635 prev_done = done; 00636 done |= ( input[i - 1] != 0 ); 00637 *data_len |= ( i - 1 ) * ( done != prev_done ); 00638 bad ^= input[i - 1] * ( done != prev_done ); 00639 } 00640 00641 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00642 00643 } 00644 #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ 00645 00646 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) 00647 /* 00648 * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length 00649 */ 00650 static void add_zeros_and_len_padding( unsigned char *output, 00651 size_t output_len, size_t data_len ) 00652 { 00653 size_t padding_len = output_len - data_len; 00654 unsigned char i = 0; 00655 00656 for( i = 1; i < padding_len; i++ ) 00657 output[data_len + i - 1] = 0x00; 00658 output[output_len - 1] = (unsigned char) padding_len; 00659 } 00660 00661 static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, 00662 size_t *data_len ) 00663 { 00664 size_t i, pad_idx; 00665 unsigned char padding_len, bad = 0; 00666 00667 if( NULL == input || NULL == data_len ) 00668 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00669 00670 padding_len = input[input_len - 1]; 00671 *data_len = input_len - padding_len; 00672 00673 /* Avoid logical || since it results in a branch */ 00674 bad |= padding_len > input_len; 00675 bad |= padding_len == 0; 00676 00677 /* The number of bytes checked must be independent of padding_len */ 00678 pad_idx = input_len - padding_len; 00679 for( i = 0; i < input_len - 1; i++ ) 00680 bad |= input[i] * ( i >= pad_idx ); 00681 00682 return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); 00683 } 00684 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ 00685 00686 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS) 00687 /* 00688 * Zero padding: fill with 00 ... 00 00689 */ 00690 static void add_zeros_padding( unsigned char *output, 00691 size_t output_len, size_t data_len ) 00692 { 00693 size_t i; 00694 00695 for( i = data_len; i < output_len; i++ ) 00696 output[i] = 0x00; 00697 } 00698 00699 static int get_zeros_padding( unsigned char *input, size_t input_len, 00700 size_t *data_len ) 00701 { 00702 size_t i; 00703 unsigned char done = 0, prev_done; 00704 00705 if( NULL == input || NULL == data_len ) 00706 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00707 00708 *data_len = 0; 00709 for( i = input_len; i > 0; i-- ) 00710 { 00711 prev_done = done; 00712 done |= ( input[i-1] != 0 ); 00713 *data_len |= i * ( done != prev_done ); 00714 } 00715 00716 return( 0 ); 00717 } 00718 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ 00719 00720 /* 00721 * No padding: don't pad :) 00722 * 00723 * There is no add_padding function (check for NULL in mbedtls_cipher_finish) 00724 * but a trivial get_padding function 00725 */ 00726 static int get_no_padding( unsigned char *input, size_t input_len, 00727 size_t *data_len ) 00728 { 00729 if( NULL == input || NULL == data_len ) 00730 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00731 00732 *data_len = input_len; 00733 00734 return( 0 ); 00735 } 00736 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00737 00738 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, 00739 unsigned char *output, size_t *olen ) 00740 { 00741 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 00742 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00743 00744 *olen = 0; 00745 00746 if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || 00747 MBEDTLS_MODE_OFB == ctx->cipher_info->mode || 00748 MBEDTLS_MODE_CTR == ctx->cipher_info->mode || 00749 MBEDTLS_MODE_GCM == ctx->cipher_info->mode || 00750 MBEDTLS_MODE_XTS == ctx->cipher_info->mode || 00751 MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) 00752 { 00753 return( 0 ); 00754 } 00755 00756 if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) || 00757 ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) ) 00758 { 00759 return( 0 ); 00760 } 00761 00762 if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) 00763 { 00764 if( ctx->unprocessed_len != 0 ) 00765 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00766 00767 return( 0 ); 00768 } 00769 00770 #if defined(MBEDTLS_CIPHER_MODE_CBC) 00771 if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) 00772 { 00773 int ret = 0; 00774 00775 if( MBEDTLS_ENCRYPT == ctx->operation ) 00776 { 00777 /* check for 'no padding' mode */ 00778 if( NULL == ctx->add_padding ) 00779 { 00780 if( 0 != ctx->unprocessed_len ) 00781 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00782 00783 return( 0 ); 00784 } 00785 00786 ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), 00787 ctx->unprocessed_len ); 00788 } 00789 else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) 00790 { 00791 /* 00792 * For decrypt operations, expect a full block, 00793 * or an empty block if no padding 00794 */ 00795 if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) 00796 return( 0 ); 00797 00798 return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); 00799 } 00800 00801 /* cipher block */ 00802 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00803 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, 00804 ctx->unprocessed_data, output ) ) ) 00805 { 00806 return( ret ); 00807 } 00808 00809 /* Set output size for decryption */ 00810 if( MBEDTLS_DECRYPT == ctx->operation ) 00811 return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), 00812 olen ); 00813 00814 /* Set output size for encryption */ 00815 *olen = mbedtls_cipher_get_block_size( ctx ); 00816 return( 0 ); 00817 } 00818 #else 00819 ((void) output); 00820 #endif /* MBEDTLS_CIPHER_MODE_CBC */ 00821 00822 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00823 } 00824 00825 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) 00826 int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ) 00827 { 00828 if( NULL == ctx || 00829 MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) 00830 { 00831 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00832 } 00833 00834 switch( mode ) 00835 { 00836 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7) 00837 case MBEDTLS_PADDING_PKCS7: 00838 ctx->add_padding = add_pkcs_padding; 00839 ctx->get_padding = get_pkcs_padding; 00840 break; 00841 #endif 00842 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) 00843 case MBEDTLS_PADDING_ONE_AND_ZEROS: 00844 ctx->add_padding = add_one_and_zeros_padding; 00845 ctx->get_padding = get_one_and_zeros_padding; 00846 break; 00847 #endif 00848 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) 00849 case MBEDTLS_PADDING_ZEROS_AND_LEN: 00850 ctx->add_padding = add_zeros_and_len_padding; 00851 ctx->get_padding = get_zeros_and_len_padding; 00852 break; 00853 #endif 00854 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS) 00855 case MBEDTLS_PADDING_ZEROS: 00856 ctx->add_padding = add_zeros_padding; 00857 ctx->get_padding = get_zeros_padding; 00858 break; 00859 #endif 00860 case MBEDTLS_PADDING_NONE: 00861 ctx->add_padding = NULL; 00862 ctx->get_padding = get_no_padding; 00863 break; 00864 00865 default: 00866 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 00867 } 00868 00869 return( 0 ); 00870 } 00871 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ 00872 00873 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) 00874 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, 00875 unsigned char *tag, size_t tag_len ) 00876 { 00877 if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) 00878 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00879 00880 if( MBEDTLS_ENCRYPT != ctx->operation ) 00881 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00882 00883 #if defined(MBEDTLS_GCM_C) 00884 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00885 return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); 00886 #endif 00887 00888 #if defined(MBEDTLS_CHACHAPOLY_C) 00889 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) 00890 { 00891 /* Don't allow truncated MAC for Poly1305 */ 00892 if ( tag_len != 16U ) 00893 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00894 00895 return mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, 00896 tag ); 00897 } 00898 #endif 00899 00900 return( 0 ); 00901 } 00902 00903 int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, 00904 const unsigned char *tag, size_t tag_len ) 00905 { 00906 unsigned char check_tag[16]; 00907 int ret; 00908 00909 if( NULL == ctx || NULL == ctx->cipher_info || 00910 MBEDTLS_DECRYPT != ctx->operation ) 00911 { 00912 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00913 } 00914 00915 #if defined(MBEDTLS_GCM_C) 00916 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 00917 { 00918 if( tag_len > sizeof( check_tag ) ) 00919 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00920 00921 if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, 00922 check_tag, tag_len ) ) ) 00923 { 00924 return( ret ); 00925 } 00926 00927 /* Check the tag in "constant-time" */ 00928 if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) 00929 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); 00930 00931 return( 0 ); 00932 } 00933 #endif /* MBEDTLS_GCM_C */ 00934 00935 #if defined(MBEDTLS_CHACHAPOLY_C) 00936 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) 00937 { 00938 /* Don't allow truncated MAC for Poly1305 */ 00939 if ( tag_len != sizeof( check_tag ) ) 00940 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 00941 00942 ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, 00943 check_tag ); 00944 if ( ret != 0 ) 00945 { 00946 return( ret ); 00947 } 00948 00949 /* Check the tag in "constant-time" */ 00950 if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) 00951 return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); 00952 00953 return( 0 ); 00954 } 00955 #endif /* MBEDTLS_CHACHAPOLY_C */ 00956 00957 return( 0 ); 00958 } 00959 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ 00960 00961 /* 00962 * Packet-oriented wrapper for non-AEAD modes 00963 */ 00964 int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, 00965 const unsigned char *iv, size_t iv_len, 00966 const unsigned char *input, size_t ilen, 00967 unsigned char *output, size_t *olen ) 00968 { 00969 int ret; 00970 size_t finish_olen; 00971 00972 if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) 00973 return( ret ); 00974 00975 if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) 00976 return( ret ); 00977 00978 if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) 00979 return( ret ); 00980 00981 if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) 00982 return( ret ); 00983 00984 *olen += finish_olen; 00985 00986 return( 0 ); 00987 } 00988 00989 #if defined(MBEDTLS_CIPHER_MODE_AEAD) 00990 /* 00991 * Packet-oriented encryption for AEAD modes 00992 */ 00993 int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, 00994 const unsigned char *iv, size_t iv_len, 00995 const unsigned char *ad, size_t ad_len, 00996 const unsigned char *input, size_t ilen, 00997 unsigned char *output, size_t *olen, 00998 unsigned char *tag, size_t tag_len ) 00999 { 01000 #if defined(MBEDTLS_GCM_C) 01001 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 01002 { 01003 *olen = ilen; 01004 return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen, 01005 iv, iv_len, ad, ad_len, input, output, 01006 tag_len, tag ) ); 01007 } 01008 #endif /* MBEDTLS_GCM_C */ 01009 #if defined(MBEDTLS_CCM_C) 01010 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) 01011 { 01012 *olen = ilen; 01013 return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, 01014 iv, iv_len, ad, ad_len, input, output, 01015 tag, tag_len ) ); 01016 } 01017 #endif /* MBEDTLS_CCM_C */ 01018 #if defined(MBEDTLS_CHACHAPOLY_C) 01019 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) 01020 { 01021 /* ChachaPoly has fixed length nonce and MAC (tag) */ 01022 if ( ( iv_len != ctx->cipher_info->iv_size ) || 01023 ( tag_len != 16U ) ) 01024 { 01025 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 01026 } 01027 01028 *olen = ilen; 01029 return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx, 01030 ilen, iv, ad, ad_len, input, output, tag ) ); 01031 } 01032 #endif /* MBEDTLS_CHACHAPOLY_C */ 01033 01034 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 01035 } 01036 01037 /* 01038 * Packet-oriented decryption for AEAD modes 01039 */ 01040 int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, 01041 const unsigned char *iv, size_t iv_len, 01042 const unsigned char *ad, size_t ad_len, 01043 const unsigned char *input, size_t ilen, 01044 unsigned char *output, size_t *olen, 01045 const unsigned char *tag, size_t tag_len ) 01046 { 01047 #if defined(MBEDTLS_GCM_C) 01048 if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) 01049 { 01050 int ret; 01051 01052 *olen = ilen; 01053 ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, 01054 iv, iv_len, ad, ad_len, 01055 tag, tag_len, input, output ); 01056 01057 if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) 01058 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; 01059 01060 return( ret ); 01061 } 01062 #endif /* MBEDTLS_GCM_C */ 01063 #if defined(MBEDTLS_CCM_C) 01064 if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) 01065 { 01066 int ret; 01067 01068 *olen = ilen; 01069 ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, 01070 iv, iv_len, ad, ad_len, 01071 input, output, tag, tag_len ); 01072 01073 if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) 01074 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; 01075 01076 return( ret ); 01077 } 01078 #endif /* MBEDTLS_CCM_C */ 01079 #if defined(MBEDTLS_CHACHAPOLY_C) 01080 if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) 01081 { 01082 int ret; 01083 01084 /* ChachaPoly has fixed length nonce and MAC (tag) */ 01085 if ( ( iv_len != ctx->cipher_info->iv_size ) || 01086 ( tag_len != 16U ) ) 01087 { 01088 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); 01089 } 01090 01091 *olen = ilen; 01092 ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen, 01093 iv, ad, ad_len, tag, input, output ); 01094 01095 if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) 01096 ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; 01097 01098 return( ret ); 01099 } 01100 #endif /* MBEDTLS_CHACHAPOLY_C */ 01101 01102 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); 01103 } 01104 #endif /* MBEDTLS_CIPHER_MODE_AEAD */ 01105 01106 #endif /* MBEDTLS_CIPHER_C */
Generated on Tue Jul 12 2022 15:15:41 by
