Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cipher.c Source File

cipher.c

Go to the documentation of this file.
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