joey shelton / LED_Demo

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

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 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 */