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 PolarSSL 00005 * 00006 * \author Adriaan de Jong <dejong@fox-it.com> 00007 * 00008 * Copyright (C) 2006-2014, Brainspark B.V. 00009 * 00010 * This file is part of PolarSSL (http://www.polarssl.org) 00011 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00012 * 00013 * All rights reserved. 00014 * 00015 * This program is free software; you can redistribute it and/or modify 00016 * it under the terms of the GNU General Public License as published by 00017 * the Free Software Foundation; either version 2 of the License, or 00018 * (at your option) any later version. 00019 * 00020 * This program is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * You should have received a copy of the GNU General Public License along 00026 * with this program; if not, write to the Free Software Foundation, Inc., 00027 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00028 */ 00029 00030 #if !defined(POLARSSL_CONFIG_FILE) 00031 #include "polarssl/config.h" 00032 #else 00033 #include POLARSSL_CONFIG_FILE 00034 #endif 00035 00036 #if defined(POLARSSL_CIPHER_C) 00037 00038 #include "polarssl/cipher.h" 00039 #include "polarssl/cipher_wrap.h" 00040 00041 #if defined(POLARSSL_GCM_C) 00042 #include "polarssl/gcm.h" 00043 #endif 00044 00045 #include <stdlib.h> 00046 00047 #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) 00048 #define POLARSSL_CIPHER_MODE_STREAM 00049 #endif 00050 00051 #if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ 00052 !defined(EFI32) 00053 #define strcasecmp _stricmp 00054 #endif 00055 00056 static int supported_init = 0; 00057 00058 const int *cipher_list( void ) 00059 { 00060 const cipher_definition_t *def; 00061 int *type; 00062 00063 if( ! supported_init ) 00064 { 00065 def = cipher_definitions; 00066 type = supported_ciphers; 00067 00068 while( def->type != 0 ) 00069 *type++ = (*def++).type; 00070 00071 *type = 0; 00072 00073 supported_init = 1; 00074 } 00075 00076 return supported_ciphers; 00077 } 00078 00079 const cipher_info_t *cipher_info_from_type( const cipher_type_t cipher_type ) 00080 { 00081 const cipher_definition_t *def; 00082 00083 for( def = cipher_definitions; def->info != NULL; def++ ) 00084 if( def->type == cipher_type ) 00085 return( def->info ); 00086 00087 return NULL; 00088 } 00089 00090 const cipher_info_t *cipher_info_from_string( const char *cipher_name ) 00091 { 00092 const cipher_definition_t *def; 00093 00094 if( NULL == cipher_name ) 00095 return NULL; 00096 00097 for( def = cipher_definitions; def->info != NULL; def++ ) 00098 if( ! strcasecmp( def->info->name, cipher_name ) ) 00099 return( def->info ); 00100 00101 return NULL; 00102 } 00103 00104 const cipher_info_t *cipher_info_from_values( const cipher_id_t cipher_id, 00105 int key_length, 00106 const cipher_mode_t mode ) 00107 { 00108 const cipher_definition_t *def; 00109 00110 for( def = cipher_definitions; def->info != NULL; def++ ) 00111 if( def->info->base->cipher == cipher_id && 00112 def->info->key_length == (unsigned) key_length && 00113 def->info->mode == mode ) 00114 return( def->info ); 00115 00116 return NULL; 00117 } 00118 00119 int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info ) 00120 { 00121 if( NULL == cipher_info || NULL == ctx ) 00122 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00123 00124 memset( ctx, 0, sizeof( cipher_context_t ) ); 00125 00126 if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) 00127 return POLARSSL_ERR_CIPHER_ALLOC_FAILED; 00128 00129 ctx->cipher_info = cipher_info; 00130 00131 #if defined(POLARSSL_CIPHER_MODE_WITH_PADDING) 00132 /* 00133 * Ignore possible errors caused by a cipher mode that doesn't use padding 00134 */ 00135 #if defined(POLARSSL_CIPHER_PADDING_PKCS7) 00136 (void) cipher_set_padding_mode( ctx, POLARSSL_PADDING_PKCS7 ); 00137 #else 00138 (void) cipher_set_padding_mode( ctx, POLARSSL_PADDING_NONE ); 00139 #endif 00140 #endif /* POLARSSL_CIPHER_MODE_WITH_PADDING */ 00141 00142 return 0; 00143 } 00144 00145 int cipher_free_ctx( cipher_context_t *ctx ) 00146 { 00147 if( ctx == NULL || ctx->cipher_info == NULL ) 00148 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00149 00150 ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); 00151 00152 return 0; 00153 } 00154 00155 int cipher_setkey( cipher_context_t *ctx, const unsigned char *key, 00156 int key_length, const operation_t operation ) 00157 { 00158 if( NULL == ctx || NULL == ctx->cipher_info ) 00159 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00160 00161 if( (int) ctx->cipher_info->key_length != key_length ) 00162 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00163 00164 ctx->key_length = key_length; 00165 ctx->operation = operation; 00166 00167 /* 00168 * For CFB and CTR mode always use the encryption key schedule 00169 */ 00170 if( POLARSSL_ENCRYPT == operation || 00171 POLARSSL_MODE_CFB == ctx->cipher_info->mode || 00172 POLARSSL_MODE_CTR == ctx->cipher_info->mode ) 00173 { 00174 return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, 00175 ctx->key_length ); 00176 } 00177 00178 if( POLARSSL_DECRYPT == operation ) 00179 return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, 00180 ctx->key_length ); 00181 00182 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00183 } 00184 00185 int cipher_set_iv( cipher_context_t *ctx, 00186 const unsigned char *iv, size_t iv_len ) 00187 { 00188 size_t actual_iv_size; 00189 00190 if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) 00191 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00192 00193 /* avoid buffer overflow in ctx->iv */ 00194 if( iv_len > POLARSSL_MAX_IV_LENGTH ) 00195 return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; 00196 00197 if( ctx->cipher_info->accepts_variable_iv_size ) 00198 actual_iv_size = iv_len; 00199 else 00200 { 00201 actual_iv_size = ctx->cipher_info->iv_size; 00202 00203 /* avoid reading past the end of input buffer */ 00204 if( actual_iv_size > iv_len ) 00205 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00206 } 00207 00208 memcpy( ctx->iv, iv, actual_iv_size ); 00209 ctx->iv_size = actual_iv_size; 00210 00211 return 0; 00212 } 00213 00214 int cipher_reset( cipher_context_t *ctx ) 00215 { 00216 if( NULL == ctx || NULL == ctx->cipher_info ) 00217 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00218 00219 ctx->unprocessed_len = 0; 00220 00221 return 0; 00222 } 00223 00224 #if defined(POLARSSL_CIPHER_MODE_AEAD) 00225 int cipher_update_ad( cipher_context_t *ctx, 00226 const unsigned char *ad, size_t ad_len ) 00227 { 00228 if( NULL == ctx || NULL == ctx->cipher_info ) 00229 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00230 00231 #if defined(POLARSSL_GCM_C) 00232 if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) 00233 { 00234 return gcm_starts( (gcm_context *) ctx->cipher_ctx, ctx->operation, 00235 ctx->iv, ctx->iv_size, ad, ad_len ); 00236 } 00237 #endif 00238 00239 return 0; 00240 } 00241 #endif /* POLARSSL_CIPHER_MODE_AEAD */ 00242 00243 int cipher_update( cipher_context_t *ctx, const unsigned char *input, 00244 size_t ilen, unsigned char *output, size_t *olen ) 00245 { 00246 int ret; 00247 00248 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 00249 { 00250 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00251 } 00252 00253 *olen = 0; 00254 00255 if( ctx->cipher_info->mode == POLARSSL_MODE_ECB ) 00256 { 00257 if( ilen != cipher_get_block_size( ctx ) ) 00258 return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED; 00259 00260 *olen = ilen; 00261 00262 if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, 00263 ctx->operation, input, output ) ) ) 00264 { 00265 return ret; 00266 } 00267 00268 return 0; 00269 } 00270 00271 #if defined(POLARSSL_GCM_C) 00272 if( ctx->cipher_info->mode == POLARSSL_MODE_GCM ) 00273 { 00274 *olen = ilen; 00275 return gcm_update( (gcm_context *) ctx->cipher_ctx, ilen, input, 00276 output ); 00277 } 00278 #endif 00279 00280 if( input == output && 00281 ( ctx->unprocessed_len != 0 || ilen % cipher_get_block_size( ctx ) ) ) 00282 { 00283 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00284 } 00285 00286 #if defined(POLARSSL_CIPHER_MODE_CBC) 00287 if( ctx->cipher_info->mode == POLARSSL_MODE_CBC ) 00288 { 00289 size_t copy_len = 0; 00290 00291 /* 00292 * If there is not enough data for a full block, cache it. 00293 */ 00294 if( ( ctx->operation == POLARSSL_DECRYPT && 00295 ilen + ctx->unprocessed_len <= cipher_get_block_size( ctx ) ) || 00296 ( ctx->operation == POLARSSL_ENCRYPT && 00297 ilen + ctx->unprocessed_len < cipher_get_block_size( ctx ) ) ) 00298 { 00299 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, 00300 ilen ); 00301 00302 ctx->unprocessed_len += ilen; 00303 return 0; 00304 } 00305 00306 /* 00307 * Process cached data first 00308 */ 00309 if( ctx->unprocessed_len != 0 ) 00310 { 00311 copy_len = cipher_get_block_size( ctx ) - ctx->unprocessed_len; 00312 00313 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, 00314 copy_len ); 00315 00316 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00317 ctx->operation, cipher_get_block_size( ctx ), ctx->iv, 00318 ctx->unprocessed_data, output ) ) ) 00319 { 00320 return ret; 00321 } 00322 00323 *olen += cipher_get_block_size( ctx ); 00324 output += cipher_get_block_size( ctx ); 00325 ctx->unprocessed_len = 0; 00326 00327 input += copy_len; 00328 ilen -= copy_len; 00329 } 00330 00331 /* 00332 * Cache final, incomplete block 00333 */ 00334 if( 0 != ilen ) 00335 { 00336 copy_len = ilen % cipher_get_block_size( ctx ); 00337 if( copy_len == 0 && ctx->operation == POLARSSL_DECRYPT ) 00338 copy_len = cipher_get_block_size(ctx); 00339 00340 memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), 00341 copy_len ); 00342 00343 ctx->unprocessed_len += copy_len; 00344 ilen -= copy_len; 00345 } 00346 00347 /* 00348 * Process remaining full blocks 00349 */ 00350 if( ilen ) 00351 { 00352 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00353 ctx->operation, ilen, ctx->iv, input, output ) ) ) 00354 { 00355 return ret; 00356 } 00357 00358 *olen += ilen; 00359 } 00360 00361 return 0; 00362 } 00363 #endif /* POLARSSL_CIPHER_MODE_CBC */ 00364 00365 #if defined(POLARSSL_CIPHER_MODE_CFB) 00366 if( ctx->cipher_info->mode == POLARSSL_MODE_CFB ) 00367 { 00368 if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, 00369 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, 00370 input, output ) ) ) 00371 { 00372 return ret; 00373 } 00374 00375 *olen = ilen; 00376 00377 return 0; 00378 } 00379 #endif /* POLARSSL_CIPHER_MODE_CFB */ 00380 00381 #if defined(POLARSSL_CIPHER_MODE_CTR) 00382 if( ctx->cipher_info->mode == POLARSSL_MODE_CTR ) 00383 { 00384 if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, 00385 ilen, &ctx->unprocessed_len, ctx->iv, 00386 ctx->unprocessed_data, input, output ) ) ) 00387 { 00388 return ret; 00389 } 00390 00391 *olen = ilen; 00392 00393 return 0; 00394 } 00395 #endif /* POLARSSL_CIPHER_MODE_CTR */ 00396 00397 #if defined(POLARSSL_CIPHER_MODE_STREAM) 00398 if( ctx->cipher_info->mode == POLARSSL_MODE_STREAM ) 00399 { 00400 if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, 00401 ilen, input, output ) ) ) 00402 { 00403 return ret; 00404 } 00405 00406 *olen = ilen; 00407 00408 return 0; 00409 } 00410 #endif /* POLARSSL_CIPHER_MODE_STREAM */ 00411 00412 return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; 00413 } 00414 00415 #if defined(POLARSSL_CIPHER_MODE_WITH_PADDING) 00416 #if defined(POLARSSL_CIPHER_PADDING_PKCS7) 00417 /* 00418 * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len 00419 */ 00420 static void add_pkcs_padding( unsigned char *output, size_t output_len, 00421 size_t data_len ) 00422 { 00423 size_t padding_len = output_len - data_len; 00424 unsigned char i; 00425 00426 for( i = 0; i < padding_len; i++ ) 00427 output[data_len + i] = (unsigned char) padding_len; 00428 } 00429 00430 static int get_pkcs_padding( unsigned char *input, size_t input_len, 00431 size_t *data_len ) 00432 { 00433 size_t i, pad_idx; 00434 unsigned char padding_len, bad = 0; 00435 00436 if( NULL == input || NULL == data_len ) 00437 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00438 00439 padding_len = input[input_len - 1]; 00440 *data_len = input_len - padding_len; 00441 00442 /* Avoid logical || since it results in a branch */ 00443 bad |= padding_len > input_len; 00444 bad |= padding_len == 0; 00445 00446 /* The number of bytes checked must be independent of padding_len, 00447 * so pick input_len, which is usually 8 or 16 (one block) */ 00448 pad_idx = input_len - padding_len; 00449 for( i = 0; i < input_len; i++ ) 00450 bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); 00451 00452 return POLARSSL_ERR_CIPHER_INVALID_PADDING * (bad != 0); 00453 } 00454 #endif /* POLARSSL_CIPHER_PADDING_PKCS7 */ 00455 00456 #if defined(POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS) 00457 /* 00458 * One and zeros padding: fill with 80 00 ... 00 00459 */ 00460 static void add_one_and_zeros_padding( unsigned char *output, 00461 size_t output_len, size_t data_len ) 00462 { 00463 size_t padding_len = output_len - data_len; 00464 unsigned char i = 0; 00465 00466 output[data_len] = 0x80; 00467 for( i = 1; i < padding_len; i++ ) 00468 output[data_len + i] = 0x00; 00469 } 00470 00471 static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, 00472 size_t *data_len ) 00473 { 00474 size_t i; 00475 unsigned char done = 0, prev_done, bad; 00476 00477 if( NULL == input || NULL == data_len ) 00478 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00479 00480 bad = 0xFF; 00481 *data_len = 0; 00482 for( i = input_len; i > 0; i-- ) 00483 { 00484 prev_done = done; 00485 done |= ( input[i-1] != 0 ); 00486 *data_len |= ( i - 1 ) * ( done != prev_done ); 00487 bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); 00488 } 00489 00490 return POLARSSL_ERR_CIPHER_INVALID_PADDING * (bad != 0); 00491 00492 } 00493 #endif /* POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS */ 00494 00495 #if defined(POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN) 00496 /* 00497 * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length 00498 */ 00499 static void add_zeros_and_len_padding( unsigned char *output, 00500 size_t output_len, size_t data_len ) 00501 { 00502 size_t padding_len = output_len - data_len; 00503 unsigned char i = 0; 00504 00505 for( i = 1; i < padding_len; i++ ) 00506 output[data_len + i - 1] = 0x00; 00507 output[output_len - 1] = (unsigned char) padding_len; 00508 } 00509 00510 static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, 00511 size_t *data_len ) 00512 { 00513 size_t i, pad_idx; 00514 unsigned char padding_len, bad = 0; 00515 00516 if( NULL == input || NULL == data_len ) 00517 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00518 00519 padding_len = input[input_len - 1]; 00520 *data_len = input_len - padding_len; 00521 00522 /* Avoid logical || since it results in a branch */ 00523 bad |= padding_len > input_len; 00524 bad |= padding_len == 0; 00525 00526 /* The number of bytes checked must be independent of padding_len */ 00527 pad_idx = input_len - padding_len; 00528 for( i = 0; i < input_len - 1; i++ ) 00529 bad |= input[i] * ( i >= pad_idx ); 00530 00531 return POLARSSL_ERR_CIPHER_INVALID_PADDING * (bad != 0); 00532 } 00533 #endif /* POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN */ 00534 00535 #if defined(POLARSSL_CIPHER_PADDING_ZEROS) 00536 /* 00537 * Zero padding: fill with 00 ... 00 00538 */ 00539 static void add_zeros_padding( unsigned char *output, 00540 size_t output_len, size_t data_len ) 00541 { 00542 size_t i; 00543 00544 for( i = data_len; i < output_len; i++ ) 00545 output[i] = 0x00; 00546 } 00547 00548 static int get_zeros_padding( unsigned char *input, size_t input_len, 00549 size_t *data_len ) 00550 { 00551 size_t i; 00552 unsigned char done = 0, prev_done; 00553 00554 if( NULL == input || NULL == data_len ) 00555 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00556 00557 *data_len = 0; 00558 for( i = input_len; i > 0; i-- ) 00559 { 00560 prev_done = done; 00561 done |= ( input[i-1] != 0 ); 00562 *data_len |= i * ( done != prev_done ); 00563 } 00564 00565 return 0; 00566 } 00567 #endif /* POLARSSL_CIPHER_PADDING_ZEROS */ 00568 00569 /* 00570 * No padding: don't pad :) 00571 * 00572 * There is no add_padding function (check for NULL in cipher_finish) 00573 * but a trivial get_padding function 00574 */ 00575 static int get_no_padding( unsigned char *input, size_t input_len, 00576 size_t *data_len ) 00577 { 00578 if( NULL == input || NULL == data_len ) 00579 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00580 00581 *data_len = input_len; 00582 00583 return 0; 00584 } 00585 #endif /* POLARSSL_CIPHER_MODE_WITH_PADDING */ 00586 00587 int cipher_finish( cipher_context_t *ctx, 00588 unsigned char *output, size_t *olen ) 00589 { 00590 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 00591 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00592 00593 *olen = 0; 00594 00595 if( POLARSSL_MODE_CFB == ctx->cipher_info->mode || 00596 POLARSSL_MODE_CTR == ctx->cipher_info->mode || 00597 POLARSSL_MODE_GCM == ctx->cipher_info->mode || 00598 POLARSSL_MODE_STREAM == ctx->cipher_info->mode ) 00599 { 00600 return 0; 00601 } 00602 00603 if( POLARSSL_MODE_ECB == ctx->cipher_info->mode ) 00604 { 00605 if( ctx->unprocessed_len != 0 ) 00606 return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED; 00607 00608 return 0; 00609 } 00610 00611 #if defined(POLARSSL_CIPHER_MODE_CBC) 00612 if( POLARSSL_MODE_CBC == ctx->cipher_info->mode ) 00613 { 00614 int ret = 0; 00615 00616 if( POLARSSL_ENCRYPT == ctx->operation ) 00617 { 00618 /* check for 'no padding' mode */ 00619 if( NULL == ctx->add_padding ) 00620 { 00621 if( 0 != ctx->unprocessed_len ) 00622 return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED; 00623 00624 return 0; 00625 } 00626 00627 ctx->add_padding( ctx->unprocessed_data, cipher_get_iv_size( ctx ), 00628 ctx->unprocessed_len ); 00629 } 00630 else if ( cipher_get_block_size( ctx ) != ctx->unprocessed_len ) 00631 { 00632 /* 00633 * For decrypt operations, expect a full block, 00634 * or an empty block if no padding 00635 */ 00636 if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) 00637 return 0; 00638 00639 return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED; 00640 } 00641 00642 /* cipher block */ 00643 if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 00644 ctx->operation, cipher_get_block_size( ctx ), ctx->iv, 00645 ctx->unprocessed_data, output ) ) ) 00646 { 00647 return ret; 00648 } 00649 00650 /* Set output size for decryption */ 00651 if( POLARSSL_DECRYPT == ctx->operation ) 00652 return ctx->get_padding( output, cipher_get_block_size( ctx ), 00653 olen ); 00654 00655 /* Set output size for encryption */ 00656 *olen = cipher_get_block_size( ctx ); 00657 return 0; 00658 } 00659 #else 00660 ((void) output); 00661 #endif /* POLARSSL_CIPHER_MODE_CBC */ 00662 00663 return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; 00664 } 00665 00666 #if defined(POLARSSL_CIPHER_MODE_WITH_PADDING) 00667 int cipher_set_padding_mode( cipher_context_t *ctx, cipher_padding_t mode ) 00668 { 00669 if( NULL == ctx || 00670 POLARSSL_MODE_CBC != ctx->cipher_info->mode ) 00671 { 00672 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00673 } 00674 00675 switch( mode ) 00676 { 00677 #if defined(POLARSSL_CIPHER_PADDING_PKCS7) 00678 case POLARSSL_PADDING_PKCS7: 00679 ctx->add_padding = add_pkcs_padding; 00680 ctx->get_padding = get_pkcs_padding; 00681 break; 00682 #endif 00683 #if defined(POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS) 00684 case POLARSSL_PADDING_ONE_AND_ZEROS: 00685 ctx->add_padding = add_one_and_zeros_padding; 00686 ctx->get_padding = get_one_and_zeros_padding; 00687 break; 00688 #endif 00689 #if defined(POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN) 00690 case POLARSSL_PADDING_ZEROS_AND_LEN: 00691 ctx->add_padding = add_zeros_and_len_padding; 00692 ctx->get_padding = get_zeros_and_len_padding; 00693 break; 00694 #endif 00695 #if defined(POLARSSL_CIPHER_PADDING_ZEROS) 00696 case POLARSSL_PADDING_ZEROS: 00697 ctx->add_padding = add_zeros_padding; 00698 ctx->get_padding = get_zeros_padding; 00699 break; 00700 #endif 00701 case POLARSSL_PADDING_NONE: 00702 ctx->add_padding = NULL; 00703 ctx->get_padding = get_no_padding; 00704 break; 00705 00706 default: 00707 return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE; 00708 } 00709 00710 return 0; 00711 } 00712 #endif /* POLARSSL_CIPHER_MODE_WITH_PADDING */ 00713 00714 #if defined(POLARSSL_CIPHER_MODE_AEAD) 00715 int cipher_write_tag( cipher_context_t *ctx, 00716 unsigned char *tag, size_t tag_len ) 00717 { 00718 if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) 00719 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00720 00721 if( POLARSSL_ENCRYPT != ctx->operation ) 00722 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00723 00724 #if defined(POLARSSL_GCM_C) 00725 if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) 00726 return gcm_finish( (gcm_context *) ctx->cipher_ctx, tag, tag_len ); 00727 #endif 00728 00729 return 0; 00730 } 00731 00732 int cipher_check_tag( cipher_context_t *ctx, 00733 const unsigned char *tag, size_t tag_len ) 00734 { 00735 int ret; 00736 00737 if( NULL == ctx || NULL == ctx->cipher_info || 00738 POLARSSL_DECRYPT != ctx->operation ) 00739 { 00740 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00741 } 00742 00743 #if defined(POLARSSL_GCM_C) 00744 if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) 00745 { 00746 unsigned char check_tag[16]; 00747 size_t i; 00748 int diff; 00749 00750 if( tag_len > sizeof( check_tag ) ) 00751 return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; 00752 00753 if( 0 != ( ret = gcm_finish( (gcm_context *) ctx->cipher_ctx, 00754 check_tag, tag_len ) ) ) 00755 { 00756 return( ret ); 00757 } 00758 00759 /* Check the tag in "constant-time" */ 00760 for( diff = 0, i = 0; i < tag_len; i++ ) 00761 diff |= tag[i] ^ check_tag[i]; 00762 00763 if( diff != 0 ) 00764 return( POLARSSL_ERR_CIPHER_AUTH_FAILED ); 00765 00766 return( 0 ); 00767 } 00768 #endif /* POLARSSL_GCM_C */ 00769 00770 return( 0 ); 00771 } 00772 #endif /* POLARSSL_CIPHER_MODE_AEAD */ 00773 00774 #if defined(POLARSSL_SELF_TEST) 00775 00776 /* 00777 * Checkup routine 00778 */ 00779 int cipher_self_test( int verbose ) 00780 { 00781 ((void) verbose); 00782 00783 return( 0 ); 00784 } 00785 00786 #endif /* POLARSSL_SELF_TEST */ 00787 00788 #endif /* POLARSSL_CIPHER_C */ 00789 00790
Generated on Tue Jul 12 2022 19:40:15 by
1.7.2