Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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 #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_USE_PSA_CRYPTO)
00062 #include "psa/crypto.h"
00063 #include "mbedtls/psa_util.h"
00064 #endif /* MBEDTLS_USE_PSA_CRYPTO */
00065 
00066 #if defined(MBEDTLS_NIST_KW_C)
00067 #include "mbedtls/nist_kw.h"
00068 #endif
00069 
00070 #if defined(MBEDTLS_PLATFORM_C)
00071 #include "mbedtls/platform.h"
00072 #else
00073 #define mbedtls_calloc calloc
00074 #define mbedtls_free   free
00075 #endif
00076 
00077 #define CIPHER_VALIDATE_RET( cond )    \
00078     MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
00079 #define CIPHER_VALIDATE( cond )        \
00080     MBEDTLS_INTERNAL_VALIDATE( cond )
00081 
00082 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
00083 /* Compare the contents of two buffers in constant time.
00084  * Returns 0 if the contents are bitwise identical, otherwise returns
00085  * a non-zero value.
00086  * This is currently only used by GCM and ChaCha20+Poly1305.
00087  */
00088 static int mbedtls_constant_time_memcmp( const void *v1, const void *v2,
00089                                          size_t len )
00090 {
00091     const unsigned char *p1 = (const unsigned char*) v1;
00092     const unsigned char *p2 = (const unsigned char*) v2;
00093     size_t i;
00094     unsigned char diff;
00095 
00096     for( diff = 0, i = 0; i < len; i++ )
00097         diff |= p1[i] ^ p2[i];
00098 
00099     return( (int)diff );
00100 }
00101 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
00102 
00103 static int supported_init = 0;
00104 
00105 const int *mbedtls_cipher_list( void )
00106 {
00107     const mbedtls_cipher_definition_t *def;
00108     int *type;
00109 
00110     if( ! supported_init )
00111     {
00112         def = mbedtls_cipher_definitions;
00113         type = mbedtls_cipher_supported;
00114 
00115         while( def->type != 0 )
00116             *type++ = (*def++).type;
00117 
00118         *type = 0;
00119 
00120         supported_init = 1;
00121     }
00122 
00123     return( mbedtls_cipher_supported );
00124 }
00125 
00126 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
00127     const mbedtls_cipher_type_t cipher_type )
00128 {
00129     const mbedtls_cipher_definition_t *def;
00130 
00131     for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
00132         if( def->type == cipher_type )
00133             return( def->info );
00134 
00135     return( NULL );
00136 }
00137 
00138 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
00139     const char *cipher_name )
00140 {
00141     const mbedtls_cipher_definition_t *def;
00142 
00143     if( NULL == cipher_name )
00144         return( NULL );
00145 
00146     for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
00147         if( !  strcmp( def->info->name, cipher_name ) )
00148             return( def->info );
00149 
00150     return( NULL );
00151 }
00152 
00153 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
00154     const mbedtls_cipher_id_t cipher_id,
00155     int key_bitlen,
00156     const mbedtls_cipher_mode_t mode )
00157 {
00158     const mbedtls_cipher_definition_t *def;
00159 
00160     for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
00161         if( def->info->base->cipher == cipher_id &&
00162             def->info->key_bitlen == (unsigned) key_bitlen &&
00163             def->info->mode == mode )
00164             return( def->info );
00165 
00166     return( NULL );
00167 }
00168 
00169 void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
00170 {
00171     CIPHER_VALIDATE( ctx != NULL );
00172     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
00173 }
00174 
00175 void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
00176 {
00177     if( ctx == NULL )
00178         return;
00179 
00180 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00181     if( ctx->psa_enabled == 1 )
00182     {
00183         if( ctx->cipher_ctx != NULL )
00184         {
00185             mbedtls_cipher_context_psa * const cipher_psa =
00186                 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
00187 
00188             if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED )
00189             {
00190                 /* xxx_free() doesn't allow to return failures. */
00191                 (void) psa_destroy_key( cipher_psa->slot );
00192             }
00193 
00194             mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) );
00195             mbedtls_free( cipher_psa );
00196         }
00197 
00198         mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
00199         return;
00200     }
00201 #endif /* MBEDTLS_USE_PSA_CRYPTO */
00202 
00203 #if defined(MBEDTLS_CMAC_C)
00204     if( ctx->cmac_ctx )
00205     {
00206        mbedtls_platform_zeroize( ctx->cmac_ctx,
00207                                  sizeof( mbedtls_cmac_context_t ) );
00208        mbedtls_free( ctx->cmac_ctx );
00209     }
00210 #endif
00211 
00212     if( ctx->cipher_ctx )
00213         ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
00214 
00215     mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
00216 }
00217 
00218 int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
00219                           const mbedtls_cipher_info_t *cipher_info )
00220 {
00221     CIPHER_VALIDATE_RET( ctx != NULL );
00222     if( cipher_info == NULL )
00223         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00224 
00225     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
00226 
00227     if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
00228         return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
00229 
00230     ctx->cipher_info = cipher_info;
00231 
00232 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
00233     /*
00234      * Ignore possible errors caused by a cipher mode that doesn't use padding
00235      */
00236 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
00237     (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
00238 #else
00239     (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
00240 #endif
00241 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
00242 
00243     return( 0 );
00244 }
00245 
00246 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00247 int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
00248                               const mbedtls_cipher_info_t *cipher_info,
00249                               size_t taglen )
00250 {
00251     psa_algorithm_t alg;
00252     mbedtls_cipher_context_psa *cipher_psa;
00253 
00254     if( NULL == cipher_info || NULL == ctx )
00255         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00256 
00257     /* Check that the underlying cipher mode and cipher type are
00258      * supported by the underlying PSA Crypto implementation. */
00259     alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen );
00260     if( alg == 0 )
00261         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00262     if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 )
00263         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00264 
00265     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
00266 
00267     cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) );
00268     if( cipher_psa == NULL )
00269         return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
00270     cipher_psa->alg  = alg;
00271     ctx->cipher_ctx  = cipher_psa;
00272     ctx->cipher_info = cipher_info;
00273     ctx->psa_enabled = 1;
00274     return( 0 );
00275 }
00276 #endif /* MBEDTLS_USE_PSA_CRYPTO */
00277 
00278 int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
00279                            const unsigned char *key,
00280                            int key_bitlen,
00281                            const mbedtls_operation_t operation )
00282 {
00283     CIPHER_VALIDATE_RET( ctx != NULL );
00284     CIPHER_VALIDATE_RET( key != NULL );
00285     CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
00286                          operation == MBEDTLS_DECRYPT );
00287     if( ctx->cipher_info == NULL )
00288         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00289 
00290 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00291     if( ctx->psa_enabled == 1 )
00292     {
00293         mbedtls_cipher_context_psa * const cipher_psa =
00294             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
00295 
00296         size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8;
00297 
00298         psa_status_t status;
00299         psa_key_type_t key_type;
00300         psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
00301 
00302         /* PSA Crypto API only accepts byte-aligned keys. */
00303         if( key_bitlen % 8 != 0 )
00304             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00305 
00306         /* Don't allow keys to be set multiple times. */
00307         if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET )
00308             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00309 
00310         key_type = mbedtls_psa_translate_cipher_type(
00311             ctx->cipher_info->type );
00312         if( key_type == 0 )
00313             return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00314         psa_set_key_type( &attributes, key_type );
00315 
00316         /* Mbed TLS' cipher layer doesn't enforce the mode of operation
00317          * (encrypt vs. decrypt): it is possible to setup a key for encryption
00318          * and use it for AEAD decryption. Until tests relying on this
00319          * are changed, allow any usage in PSA. */
00320         psa_set_key_usage_flags( &attributes,
00321                                  /* mbedtls_psa_translate_cipher_operation( operation ); */
00322                                  PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
00323         psa_set_key_algorithm( &attributes, cipher_psa->alg );
00324 
00325         status = psa_import_key( &attributes, key, key_bytelen,
00326                                  &cipher_psa->slot );
00327         switch( status )
00328         {
00329             case PSA_SUCCESS:
00330                 break;
00331             case PSA_ERROR_INSUFFICIENT_MEMORY:
00332                 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
00333             case PSA_ERROR_NOT_SUPPORTED:
00334                 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00335             default:
00336                 return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
00337         }
00338         /* Indicate that we own the key slot and need to
00339          * destroy it in mbedtls_cipher_free(). */
00340         cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
00341 
00342         ctx->key_bitlen = key_bitlen;
00343         ctx->operation = operation;
00344         return( 0 );
00345     }
00346 #endif /* MBEDTLS_USE_PSA_CRYPTO */
00347 
00348     if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
00349         (int) ctx->cipher_info->key_bitlen != key_bitlen )
00350     {
00351         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00352     }
00353 
00354     ctx->key_bitlen = key_bitlen;
00355     ctx->operation = operation;
00356 
00357     /*
00358      * For OFB, CFB and CTR mode always use the encryption key schedule
00359      */
00360     if( MBEDTLS_ENCRYPT == operation ||
00361         MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
00362         MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
00363         MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
00364     {
00365         return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
00366                                                          ctx->key_bitlen ) );
00367     }
00368 
00369     if( MBEDTLS_DECRYPT == operation )
00370         return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
00371                                                          ctx->key_bitlen ) );
00372 
00373     return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00374 }
00375 
00376 int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
00377                            const unsigned char *iv,
00378                            size_t iv_len )
00379 {
00380     size_t actual_iv_size;
00381 
00382     CIPHER_VALIDATE_RET( ctx != NULL );
00383     CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
00384     if( ctx->cipher_info == NULL )
00385         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00386 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00387     if( ctx->psa_enabled == 1 )
00388     {
00389         /* While PSA Crypto has an API for multipart
00390          * operations, we currently don't make it
00391          * accessible through the cipher layer. */
00392         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00393     }
00394 #endif /* MBEDTLS_USE_PSA_CRYPTO */
00395 
00396     /* avoid buffer overflow in ctx->iv */
00397     if( iv_len > MBEDTLS_MAX_IV_LENGTH )
00398         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00399 
00400     if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
00401         actual_iv_size = iv_len;
00402     else
00403     {
00404         actual_iv_size = ctx->cipher_info->iv_size;
00405 
00406         /* avoid reading past the end of input buffer */
00407         if( actual_iv_size > iv_len )
00408             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00409     }
00410 
00411 #if defined(MBEDTLS_CHACHA20_C)
00412     if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
00413     {
00414         if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
00415                                            iv,
00416                                            0U ) ) /* Initial counter value */
00417         {
00418             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00419         }
00420     }
00421 #endif
00422 
00423     if ( actual_iv_size != 0 )
00424     {
00425         memcpy( ctx->iv, iv, actual_iv_size );
00426         ctx->iv_size = actual_iv_size;
00427     }
00428 
00429     return( 0 );
00430 }
00431 
00432 int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
00433 {
00434     CIPHER_VALIDATE_RET( ctx != NULL );
00435     if( ctx->cipher_info == NULL )
00436         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00437 
00438 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00439     if( ctx->psa_enabled == 1 )
00440     {
00441         /* We don't support resetting PSA-based
00442          * cipher contexts, yet. */
00443         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00444     }
00445 #endif /* MBEDTLS_USE_PSA_CRYPTO */
00446 
00447     ctx->unprocessed_len = 0;
00448 
00449     return( 0 );
00450 }
00451 
00452 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
00453 int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
00454                       const unsigned char *ad, size_t ad_len )
00455 {
00456     CIPHER_VALIDATE_RET( ctx != NULL );
00457     CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
00458     if( ctx->cipher_info == NULL )
00459         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00460 
00461 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00462     if( ctx->psa_enabled == 1 )
00463     {
00464         /* While PSA Crypto has an API for multipart
00465          * operations, we currently don't make it
00466          * accessible through the cipher layer. */
00467         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00468     }
00469 #endif /* MBEDTLS_USE_PSA_CRYPTO */
00470 
00471 #if defined(MBEDTLS_GCM_C)
00472     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
00473     {
00474         return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
00475                                     ctx->iv, ctx->iv_size, ad, ad_len ) );
00476     }
00477 #endif
00478 
00479 #if defined(MBEDTLS_CHACHAPOLY_C)
00480     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
00481     {
00482         int result;
00483         mbedtls_chachapoly_mode_t  mode;
00484 
00485         mode = ( ctx->operation == MBEDTLS_ENCRYPT )
00486                 ? MBEDTLS_CHACHAPOLY_ENCRYPT
00487                 : MBEDTLS_CHACHAPOLY_DECRYPT;
00488 
00489         result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
00490                                                         ctx->iv,
00491                                                         mode );
00492         if ( result != 0 )
00493             return( result );
00494 
00495         return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
00496                                                ad, ad_len ) );
00497     }
00498 #endif
00499 
00500     return( 0 );
00501 }
00502 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
00503 
00504 int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
00505                    size_t ilen, unsigned char *output, size_t *olen )
00506 {
00507     int ret;
00508     size_t block_size;
00509 
00510     CIPHER_VALIDATE_RET( ctx != NULL );
00511     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
00512     CIPHER_VALIDATE_RET( output != NULL );
00513     CIPHER_VALIDATE_RET( olen != NULL );
00514     if( ctx->cipher_info == NULL )
00515         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00516 
00517 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00518     if( ctx->psa_enabled == 1 )
00519     {
00520         /* While PSA Crypto has an API for multipart
00521          * operations, we currently don't make it
00522          * accessible through the cipher layer. */
00523         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00524     }
00525 #endif /* MBEDTLS_USE_PSA_CRYPTO */
00526 
00527     *olen = 0;
00528     block_size = mbedtls_cipher_get_block_size( ctx );
00529 
00530     if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
00531     {
00532         if( ilen != block_size )
00533             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
00534 
00535         *olen = ilen;
00536 
00537         if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
00538                     ctx->operation, input, output ) ) )
00539         {
00540             return( ret );
00541         }
00542 
00543         return( 0 );
00544     }
00545 
00546 #if defined(MBEDTLS_GCM_C)
00547     if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
00548     {
00549         *olen = ilen;
00550         return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
00551                                     output ) );
00552     }
00553 #endif
00554 
00555 #if defined(MBEDTLS_CHACHAPOLY_C)
00556     if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
00557     {
00558         *olen = ilen;
00559         return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
00560                                            ilen, input, output ) );
00561     }
00562 #endif
00563 
00564     if ( 0 == block_size )
00565     {
00566         return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
00567     }
00568 
00569     if( input == output &&
00570        ( ctx->unprocessed_len != 0 || ilen % block_size ) )
00571     {
00572         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00573     }
00574 
00575 #if defined(MBEDTLS_CIPHER_MODE_CBC)
00576     if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
00577     {
00578         size_t copy_len = 0;
00579 
00580         /*
00581          * If there is not enough data for a full block, cache it.
00582          */
00583         if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
00584                 ilen <= block_size - ctx->unprocessed_len ) ||
00585             ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
00586                 ilen < block_size - ctx->unprocessed_len ) ||
00587              ( ctx->operation == MBEDTLS_ENCRYPT &&
00588                 ilen < block_size - ctx->unprocessed_len ) )
00589         {
00590             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
00591                     ilen );
00592 
00593             ctx->unprocessed_len += ilen;
00594             return( 0 );
00595         }
00596 
00597         /*
00598          * Process cached data first
00599          */
00600         if( 0 != ctx->unprocessed_len )
00601         {
00602             copy_len = block_size - ctx->unprocessed_len;
00603 
00604             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
00605                     copy_len );
00606 
00607             if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
00608                     ctx->operation, block_size, ctx->iv,
00609                     ctx->unprocessed_data, output ) ) )
00610             {
00611                 return( ret );
00612             }
00613 
00614             *olen += block_size;
00615             output += block_size;
00616             ctx->unprocessed_len = 0;
00617 
00618             input += copy_len;
00619             ilen -= copy_len;
00620         }
00621 
00622         /*
00623          * Cache final, incomplete block
00624          */
00625         if( 0 != ilen )
00626         {
00627             if( 0 == block_size )
00628             {
00629                 return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
00630             }
00631 
00632             /* Encryption: only cache partial blocks
00633              * Decryption w/ padding: always keep at least one whole block
00634              * Decryption w/o padding: only cache partial blocks
00635              */
00636             copy_len = ilen % block_size;
00637             if( copy_len == 0 &&
00638                 ctx->operation == MBEDTLS_DECRYPT &&
00639                 NULL != ctx->add_padding)
00640             {
00641                 copy_len = block_size;
00642             }
00643 
00644             memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
00645                     copy_len );
00646 
00647             ctx->unprocessed_len += copy_len;
00648             ilen -= copy_len;
00649         }
00650 
00651         /*
00652          * Process remaining full blocks
00653          */
00654         if( ilen )
00655         {
00656             if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
00657                     ctx->operation, ilen, ctx->iv, input, output ) ) )
00658             {
00659                 return( ret );
00660             }
00661 
00662             *olen += ilen;
00663         }
00664 
00665         return( 0 );
00666     }
00667 #endif /* MBEDTLS_CIPHER_MODE_CBC */
00668 
00669 #if defined(MBEDTLS_CIPHER_MODE_CFB)
00670     if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
00671     {
00672         if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
00673                 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
00674                 input, output ) ) )
00675         {
00676             return( ret );
00677         }
00678 
00679         *olen = ilen;
00680 
00681         return( 0 );
00682     }
00683 #endif /* MBEDTLS_CIPHER_MODE_CFB */
00684 
00685 #if defined(MBEDTLS_CIPHER_MODE_OFB)
00686     if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
00687     {
00688         if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
00689                 ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
00690         {
00691             return( ret );
00692         }
00693 
00694         *olen = ilen;
00695 
00696         return( 0 );
00697     }
00698 #endif /* MBEDTLS_CIPHER_MODE_OFB */
00699 
00700 #if defined(MBEDTLS_CIPHER_MODE_CTR)
00701     if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
00702     {
00703         if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
00704                 ilen, &ctx->unprocessed_len, ctx->iv,
00705                 ctx->unprocessed_data, input, output ) ) )
00706         {
00707             return( ret );
00708         }
00709 
00710         *olen = ilen;
00711 
00712         return( 0 );
00713     }
00714 #endif /* MBEDTLS_CIPHER_MODE_CTR */
00715 
00716 #if defined(MBEDTLS_CIPHER_MODE_XTS)
00717     if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
00718     {
00719         if( ctx->unprocessed_len > 0 ) {
00720             /* We can only process an entire data unit at a time. */
00721             return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00722         }
00723 
00724         ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
00725                 ctx->operation, ilen, ctx->iv, input, output );
00726         if( ret != 0 )
00727         {
00728             return( ret );
00729         }
00730 
00731         *olen = ilen;
00732 
00733         return( 0 );
00734     }
00735 #endif /* MBEDTLS_CIPHER_MODE_XTS */
00736 
00737 #if defined(MBEDTLS_CIPHER_MODE_STREAM)
00738     if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
00739     {
00740         if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
00741                                                     ilen, input, output ) ) )
00742         {
00743             return( ret );
00744         }
00745 
00746         *olen = ilen;
00747 
00748         return( 0 );
00749     }
00750 #endif /* MBEDTLS_CIPHER_MODE_STREAM */
00751 
00752     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00753 }
00754 
00755 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
00756 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
00757 /*
00758  * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
00759  */
00760 static void add_pkcs_padding( unsigned char *output, size_t output_len,
00761         size_t data_len )
00762 {
00763     size_t padding_len = output_len - data_len;
00764     unsigned char i;
00765 
00766     for( i = 0; i < padding_len; i++ )
00767         output[data_len + i] = (unsigned char) padding_len;
00768 }
00769 
00770 static int get_pkcs_padding( unsigned char *input, size_t input_len,
00771         size_t *data_len )
00772 {
00773     size_t i, pad_idx;
00774     unsigned char padding_len, bad = 0;
00775 
00776     if( NULL == input || NULL == data_len )
00777         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00778 
00779     padding_len = input[input_len - 1];
00780     *data_len = input_len - padding_len;
00781 
00782     /* Avoid logical || since it results in a branch */
00783     bad |= padding_len > input_len;
00784     bad |= padding_len == 0;
00785 
00786     /* The number of bytes checked must be independent of padding_len,
00787      * so pick input_len, which is usually 8 or 16 (one block) */
00788     pad_idx = input_len - padding_len;
00789     for( i = 0; i < input_len; i++ )
00790         bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
00791 
00792     return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
00793 }
00794 #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
00795 
00796 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
00797 /*
00798  * One and zeros padding: fill with 80 00 ... 00
00799  */
00800 static void add_one_and_zeros_padding( unsigned char *output,
00801                                        size_t output_len, size_t data_len )
00802 {
00803     size_t padding_len = output_len - data_len;
00804     unsigned char i = 0;
00805 
00806     output[data_len] = 0x80;
00807     for( i = 1; i < padding_len; i++ )
00808         output[data_len + i] = 0x00;
00809 }
00810 
00811 static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
00812                                       size_t *data_len )
00813 {
00814     size_t i;
00815     unsigned char done = 0, prev_done, bad;
00816 
00817     if( NULL == input || NULL == data_len )
00818         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00819 
00820     bad = 0x80;
00821     *data_len = 0;
00822     for( i = input_len; i > 0; i-- )
00823     {
00824         prev_done = done;
00825         done |= ( input[i - 1] != 0 );
00826         *data_len |= ( i - 1 ) * ( done != prev_done );
00827         bad ^= input[i - 1] * ( done != prev_done );
00828     }
00829 
00830     return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
00831 
00832 }
00833 #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
00834 
00835 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
00836 /*
00837  * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
00838  */
00839 static void add_zeros_and_len_padding( unsigned char *output,
00840                                        size_t output_len, size_t data_len )
00841 {
00842     size_t padding_len = output_len - data_len;
00843     unsigned char i = 0;
00844 
00845     for( i = 1; i < padding_len; i++ )
00846         output[data_len + i - 1] = 0x00;
00847     output[output_len - 1] = (unsigned char) padding_len;
00848 }
00849 
00850 static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
00851                                       size_t *data_len )
00852 {
00853     size_t i, pad_idx;
00854     unsigned char padding_len, bad = 0;
00855 
00856     if( NULL == input || NULL == data_len )
00857         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00858 
00859     padding_len = input[input_len - 1];
00860     *data_len = input_len - padding_len;
00861 
00862     /* Avoid logical || since it results in a branch */
00863     bad |= padding_len > input_len;
00864     bad |= padding_len == 0;
00865 
00866     /* The number of bytes checked must be independent of padding_len */
00867     pad_idx = input_len - padding_len;
00868     for( i = 0; i < input_len - 1; i++ )
00869         bad |= input[i] * ( i >= pad_idx );
00870 
00871     return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
00872 }
00873 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
00874 
00875 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
00876 /*
00877  * Zero padding: fill with 00 ... 00
00878  */
00879 static void add_zeros_padding( unsigned char *output,
00880                                size_t output_len, size_t data_len )
00881 {
00882     size_t i;
00883 
00884     for( i = data_len; i < output_len; i++ )
00885         output[i] = 0x00;
00886 }
00887 
00888 static int get_zeros_padding( unsigned char *input, size_t input_len,
00889                               size_t *data_len )
00890 {
00891     size_t i;
00892     unsigned char done = 0, prev_done;
00893 
00894     if( NULL == input || NULL == data_len )
00895         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00896 
00897     *data_len = 0;
00898     for( i = input_len; i > 0; i-- )
00899     {
00900         prev_done = done;
00901         done |= ( input[i-1] != 0 );
00902         *data_len |= i * ( done != prev_done );
00903     }
00904 
00905     return( 0 );
00906 }
00907 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
00908 
00909 /*
00910  * No padding: don't pad :)
00911  *
00912  * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
00913  * but a trivial get_padding function
00914  */
00915 static int get_no_padding( unsigned char *input, size_t input_len,
00916                               size_t *data_len )
00917 {
00918     if( NULL == input || NULL == data_len )
00919         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00920 
00921     *data_len = input_len;
00922 
00923     return( 0 );
00924 }
00925 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
00926 
00927 int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
00928                    unsigned char *output, size_t *olen )
00929 {
00930     CIPHER_VALIDATE_RET( ctx != NULL );
00931     CIPHER_VALIDATE_RET( output != NULL );
00932     CIPHER_VALIDATE_RET( olen != NULL );
00933     if( ctx->cipher_info == NULL )
00934         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
00935 
00936 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00937     if( ctx->psa_enabled == 1 )
00938     {
00939         /* While PSA Crypto has an API for multipart
00940          * operations, we currently don't make it
00941          * accessible through the cipher layer. */
00942         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
00943     }
00944 #endif /* MBEDTLS_USE_PSA_CRYPTO */
00945 
00946     *olen = 0;
00947 
00948     if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
00949         MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
00950         MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
00951         MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
00952         MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
00953         MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
00954     {
00955         return( 0 );
00956     }
00957 
00958     if ( ( MBEDTLS_CIPHER_CHACHA20          == ctx->cipher_info->type ) ||
00959          ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
00960     {
00961         return( 0 );
00962     }
00963 
00964     if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
00965     {
00966         if( ctx->unprocessed_len != 0 )
00967             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
00968 
00969         return( 0 );
00970     }
00971 
00972 #if defined(MBEDTLS_CIPHER_MODE_CBC)
00973     if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
00974     {
00975         int ret = 0;
00976 
00977         if( MBEDTLS_ENCRYPT == ctx->operation )
00978         {
00979             /* check for 'no padding' mode */
00980             if( NULL == ctx->add_padding )
00981             {
00982                 if( 0 != ctx->unprocessed_len )
00983                     return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
00984 
00985                 return( 0 );
00986             }
00987 
00988             ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
00989                     ctx->unprocessed_len );
00990         }
00991         else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
00992         {
00993             /*
00994              * For decrypt operations, expect a full block,
00995              * or an empty block if no padding
00996              */
00997             if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
00998                 return( 0 );
00999 
01000             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
01001         }
01002 
01003         /* cipher block */
01004         if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
01005                 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
01006                 ctx->unprocessed_data, output ) ) )
01007         {
01008             return( ret );
01009         }
01010 
01011         /* Set output size for decryption */
01012         if( MBEDTLS_DECRYPT == ctx->operation )
01013             return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
01014                                       olen ) );
01015 
01016         /* Set output size for encryption */
01017         *olen = mbedtls_cipher_get_block_size( ctx );
01018         return( 0 );
01019     }
01020 #else
01021     ((void) output);
01022 #endif /* MBEDTLS_CIPHER_MODE_CBC */
01023 
01024     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
01025 }
01026 
01027 #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
01028 int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
01029                                      mbedtls_cipher_padding_t mode )
01030 {
01031     CIPHER_VALIDATE_RET( ctx != NULL );
01032 
01033     if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
01034     {
01035         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01036     }
01037 
01038 #if defined(MBEDTLS_USE_PSA_CRYPTO)
01039     if( ctx->psa_enabled == 1 )
01040     {
01041         /* While PSA Crypto knows about CBC padding
01042          * schemes, we currently don't make them
01043          * accessible through the cipher layer. */
01044         if( mode != MBEDTLS_PADDING_NONE )
01045             return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
01046 
01047         return( 0 );
01048     }
01049 #endif /* MBEDTLS_USE_PSA_CRYPTO */
01050 
01051     switch( mode )
01052     {
01053 #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
01054     case MBEDTLS_PADDING_PKCS7:
01055         ctx->add_padding = add_pkcs_padding;
01056         ctx->get_padding = get_pkcs_padding;
01057         break;
01058 #endif
01059 #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
01060     case MBEDTLS_PADDING_ONE_AND_ZEROS:
01061         ctx->add_padding = add_one_and_zeros_padding;
01062         ctx->get_padding = get_one_and_zeros_padding;
01063         break;
01064 #endif
01065 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
01066     case MBEDTLS_PADDING_ZEROS_AND_LEN:
01067         ctx->add_padding = add_zeros_and_len_padding;
01068         ctx->get_padding = get_zeros_and_len_padding;
01069         break;
01070 #endif
01071 #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
01072     case MBEDTLS_PADDING_ZEROS:
01073         ctx->add_padding = add_zeros_padding;
01074         ctx->get_padding = get_zeros_padding;
01075         break;
01076 #endif
01077     case MBEDTLS_PADDING_NONE:
01078         ctx->add_padding = NULL;
01079         ctx->get_padding = get_no_padding;
01080         break;
01081 
01082     default:
01083         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
01084     }
01085 
01086     return( 0 );
01087 }
01088 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
01089 
01090 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
01091 int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
01092                       unsigned char *tag, size_t tag_len )
01093 {
01094     CIPHER_VALIDATE_RET( ctx != NULL );
01095     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
01096     if( ctx->cipher_info == NULL )
01097         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01098 
01099     if( MBEDTLS_ENCRYPT != ctx->operation )
01100         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01101 
01102 #if defined(MBEDTLS_USE_PSA_CRYPTO)
01103     if( ctx->psa_enabled == 1 )
01104     {
01105         /* While PSA Crypto has an API for multipart
01106          * operations, we currently don't make it
01107          * accessible through the cipher layer. */
01108         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
01109     }
01110 #endif /* MBEDTLS_USE_PSA_CRYPTO */
01111 
01112 #if defined(MBEDTLS_GCM_C)
01113     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
01114         return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
01115                                     tag, tag_len ) );
01116 #endif
01117 
01118 #if defined(MBEDTLS_CHACHAPOLY_C)
01119     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
01120     {
01121         /* Don't allow truncated MAC for Poly1305 */
01122         if ( tag_len != 16U )
01123             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01124 
01125         return( mbedtls_chachapoly_finish(
01126                     (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) );
01127     }
01128 #endif
01129 
01130     return( 0 );
01131 }
01132 
01133 int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
01134                       const unsigned char *tag, size_t tag_len )
01135 {
01136     unsigned char check_tag[16];
01137     int ret;
01138 
01139     CIPHER_VALIDATE_RET( ctx != NULL );
01140     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
01141     if( ctx->cipher_info == NULL )
01142         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01143 
01144     if( MBEDTLS_DECRYPT != ctx->operation )
01145     {
01146         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01147     }
01148 
01149 #if defined(MBEDTLS_USE_PSA_CRYPTO)
01150     if( ctx->psa_enabled == 1 )
01151     {
01152         /* While PSA Crypto has an API for multipart
01153          * operations, we currently don't make it
01154          * accessible through the cipher layer. */
01155         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
01156     }
01157 #endif /* MBEDTLS_USE_PSA_CRYPTO */
01158 
01159 #if defined(MBEDTLS_GCM_C)
01160     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
01161     {
01162         if( tag_len > sizeof( check_tag ) )
01163             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01164 
01165         if( 0 != ( ret = mbedtls_gcm_finish(
01166                        (mbedtls_gcm_context *) ctx->cipher_ctx,
01167                        check_tag, tag_len ) ) )
01168         {
01169             return( ret );
01170         }
01171 
01172         /* Check the tag in "constant-time" */
01173         if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
01174             return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
01175 
01176         return( 0 );
01177     }
01178 #endif /* MBEDTLS_GCM_C */
01179 
01180 #if defined(MBEDTLS_CHACHAPOLY_C)
01181     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
01182     {
01183         /* Don't allow truncated MAC for Poly1305 */
01184         if ( tag_len != sizeof( check_tag ) )
01185             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01186 
01187         ret = mbedtls_chachapoly_finish(
01188             (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag );
01189         if ( ret != 0 )
01190         {
01191             return( ret );
01192         }
01193 
01194         /* Check the tag in "constant-time" */
01195         if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
01196             return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
01197 
01198         return( 0 );
01199     }
01200 #endif /* MBEDTLS_CHACHAPOLY_C */
01201 
01202     return( 0 );
01203 }
01204 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
01205 
01206 /*
01207  * Packet-oriented wrapper for non-AEAD modes
01208  */
01209 int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
01210                   const unsigned char *iv, size_t iv_len,
01211                   const unsigned char *input, size_t ilen,
01212                   unsigned char *output, size_t *olen )
01213 {
01214     int ret;
01215     size_t finish_olen;
01216 
01217     CIPHER_VALIDATE_RET( ctx != NULL );
01218     CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
01219     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
01220     CIPHER_VALIDATE_RET( output != NULL );
01221     CIPHER_VALIDATE_RET( olen != NULL );
01222 
01223 #if defined(MBEDTLS_USE_PSA_CRYPTO)
01224     if( ctx->psa_enabled == 1 )
01225     {
01226         /* As in the non-PSA case, we don't check that
01227          * a key has been set. If not, the key slot will
01228          * still be in its default state of 0, which is
01229          * guaranteed to be invalid, hence the PSA-call
01230          * below will gracefully fail. */
01231         mbedtls_cipher_context_psa * const cipher_psa =
01232             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
01233 
01234         psa_status_t status;
01235         psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
01236         size_t part_len;
01237 
01238         if( ctx->operation == MBEDTLS_DECRYPT )
01239         {
01240             status = psa_cipher_decrypt_setup( &cipher_op,
01241                                                cipher_psa->slot,
01242                                                cipher_psa->alg );
01243         }
01244         else if( ctx->operation == MBEDTLS_ENCRYPT )
01245         {
01246             status = psa_cipher_encrypt_setup( &cipher_op,
01247                                                cipher_psa->slot,
01248                                                cipher_psa->alg );
01249         }
01250         else
01251             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01252 
01253         /* In the following, we can immediately return on an error,
01254          * because the PSA Crypto API guarantees that cipher operations
01255          * are terminated by unsuccessful calls to psa_cipher_update(),
01256          * and by any call to psa_cipher_finish(). */
01257         if( status != PSA_SUCCESS )
01258             return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
01259 
01260         status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
01261         if( status != PSA_SUCCESS )
01262             return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
01263 
01264         status = psa_cipher_update( &cipher_op,
01265                                     input, ilen,
01266                                     output, ilen, olen );
01267         if( status != PSA_SUCCESS )
01268             return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
01269 
01270         status = psa_cipher_finish( &cipher_op,
01271                                     output + *olen, ilen - *olen,
01272                                     &part_len );
01273         if( status != PSA_SUCCESS )
01274             return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
01275 
01276         *olen += part_len;
01277         return( 0 );
01278     }
01279 #endif /* MBEDTLS_USE_PSA_CRYPTO */
01280 
01281     if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
01282         return( ret );
01283 
01284     if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
01285         return( ret );
01286 
01287     if( ( ret = mbedtls_cipher_update( ctx, input, ilen,
01288                                        output, olen ) ) != 0 )
01289         return( ret );
01290 
01291     if( ( ret = mbedtls_cipher_finish( ctx, output + *olen,
01292                                        &finish_olen ) ) != 0 )
01293         return( ret );
01294 
01295     *olen += finish_olen;
01296 
01297     return( 0 );
01298 }
01299 
01300 #if defined(MBEDTLS_CIPHER_MODE_AEAD)
01301 /*
01302  * Packet-oriented encryption for AEAD modes
01303  */
01304 int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
01305                          const unsigned char *iv, size_t iv_len,
01306                          const unsigned char *ad, size_t ad_len,
01307                          const unsigned char *input, size_t ilen,
01308                          unsigned char *output, size_t *olen,
01309                          unsigned char *tag, size_t tag_len )
01310 {
01311     CIPHER_VALIDATE_RET( ctx != NULL );
01312     CIPHER_VALIDATE_RET( iv != NULL );
01313     CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
01314     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
01315     CIPHER_VALIDATE_RET( output != NULL );
01316     CIPHER_VALIDATE_RET( olen != NULL );
01317     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
01318 
01319 #if defined(MBEDTLS_USE_PSA_CRYPTO)
01320     if( ctx->psa_enabled == 1 )
01321     {
01322         /* As in the non-PSA case, we don't check that
01323          * a key has been set. If not, the key slot will
01324          * still be in its default state of 0, which is
01325          * guaranteed to be invalid, hence the PSA-call
01326          * below will gracefully fail. */
01327         mbedtls_cipher_context_psa * const cipher_psa =
01328             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
01329 
01330         psa_status_t status;
01331 
01332         /* PSA Crypto API always writes the authentication tag
01333          * at the end of the encrypted message. */
01334         if( tag != output + ilen )
01335             return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
01336 
01337         status = psa_aead_encrypt( cipher_psa->slot,
01338                                    cipher_psa->alg,
01339                                    iv, iv_len,
01340                                    ad, ad_len,
01341                                    input, ilen,
01342                                    output, ilen + tag_len, olen );
01343         if( status != PSA_SUCCESS )
01344             return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
01345 
01346         *olen -= tag_len;
01347         return( 0 );
01348     }
01349 #endif /* MBEDTLS_USE_PSA_CRYPTO */
01350 
01351 #if defined(MBEDTLS_GCM_C)
01352     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
01353     {
01354         *olen = ilen;
01355         return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
01356                                            ilen, iv, iv_len, ad, ad_len,
01357                                            input, output, tag_len, tag ) );
01358     }
01359 #endif /* MBEDTLS_GCM_C */
01360 #if defined(MBEDTLS_CCM_C)
01361     if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
01362     {
01363         *olen = ilen;
01364         return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
01365                                      iv, iv_len, ad, ad_len, input, output,
01366                                      tag, tag_len ) );
01367     }
01368 #endif /* MBEDTLS_CCM_C */
01369 #if defined(MBEDTLS_CHACHAPOLY_C)
01370     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
01371     {
01372         /* ChachaPoly has fixed length nonce and MAC (tag) */
01373         if ( ( iv_len != ctx->cipher_info->iv_size ) ||
01374              ( tag_len != 16U ) )
01375         {
01376             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01377         }
01378 
01379         *olen = ilen;
01380         return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
01381                                 ilen, iv, ad, ad_len, input, output, tag ) );
01382     }
01383 #endif /* MBEDTLS_CHACHAPOLY_C */
01384 #if defined(MBEDTLS_NIST_KW_C)
01385    if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
01386        MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
01387     {
01388         mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
01389                                         MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
01390 
01391         /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
01392         if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
01393         {
01394             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01395         }
01396 
01397         return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
01398     }
01399 #endif /* MBEDTLS_NIST_KW_C */
01400 
01401     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
01402 }
01403 
01404 /*
01405  * Packet-oriented decryption for AEAD modes
01406  */
01407 int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
01408                          const unsigned char *iv, size_t iv_len,
01409                          const unsigned char *ad, size_t ad_len,
01410                          const unsigned char *input, size_t ilen,
01411                          unsigned char *output, size_t *olen,
01412                          const unsigned char *tag, size_t tag_len )
01413 {
01414     CIPHER_VALIDATE_RET( ctx != NULL );
01415     CIPHER_VALIDATE_RET( iv != NULL );
01416     CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
01417     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
01418     CIPHER_VALIDATE_RET( output != NULL );
01419     CIPHER_VALIDATE_RET( olen != NULL );
01420     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
01421 
01422 #if defined(MBEDTLS_USE_PSA_CRYPTO)
01423     if( ctx->psa_enabled == 1 )
01424     {
01425         /* As in the non-PSA case, we don't check that
01426          * a key has been set. If not, the key slot will
01427          * still be in its default state of 0, which is
01428          * guaranteed to be invalid, hence the PSA-call
01429          * below will gracefully fail. */
01430         mbedtls_cipher_context_psa * const cipher_psa =
01431             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
01432 
01433         psa_status_t status;
01434 
01435         /* PSA Crypto API always writes the authentication tag
01436          * at the end of the encrypted message. */
01437         if( tag != input + ilen )
01438             return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
01439 
01440         status = psa_aead_decrypt( cipher_psa->slot,
01441                                    cipher_psa->alg,
01442                                    iv, iv_len,
01443                                    ad, ad_len,
01444                                    input, ilen + tag_len,
01445                                    output, ilen, olen );
01446         if( status == PSA_ERROR_INVALID_SIGNATURE )
01447             return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
01448         else if( status != PSA_SUCCESS )
01449             return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
01450 
01451         return( 0 );
01452     }
01453 #endif /* MBEDTLS_USE_PSA_CRYPTO */
01454 
01455 #if defined(MBEDTLS_GCM_C)
01456     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
01457     {
01458         int ret;
01459 
01460         *olen = ilen;
01461         ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
01462                                 iv, iv_len, ad, ad_len,
01463                                 tag, tag_len, input, output );
01464 
01465         if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
01466             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
01467 
01468         return( ret );
01469     }
01470 #endif /* MBEDTLS_GCM_C */
01471 #if defined(MBEDTLS_CCM_C)
01472     if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
01473     {
01474         int ret;
01475 
01476         *olen = ilen;
01477         ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
01478                                 iv, iv_len, ad, ad_len,
01479                                 input, output, tag, tag_len );
01480 
01481         if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
01482             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
01483 
01484         return( ret );
01485     }
01486 #endif /* MBEDTLS_CCM_C */
01487 #if defined(MBEDTLS_CHACHAPOLY_C)
01488     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
01489     {
01490         int ret;
01491 
01492         /* ChachaPoly has fixed length nonce and MAC (tag) */
01493         if ( ( iv_len != ctx->cipher_info->iv_size ) ||
01494              ( tag_len != 16U ) )
01495         {
01496             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01497         }
01498 
01499         *olen = ilen;
01500         ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
01501                                 iv, ad, ad_len, tag, input, output );
01502 
01503         if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
01504             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
01505 
01506         return( ret );
01507     }
01508 #endif /* MBEDTLS_CHACHAPOLY_C */
01509 #if defined(MBEDTLS_NIST_KW_C)
01510     if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
01511         MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
01512     {
01513         mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
01514                                         MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
01515 
01516         /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
01517         if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
01518         {
01519             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
01520         }
01521 
01522         return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
01523     }
01524 #endif /* MBEDTLS_NIST_KW_C */
01525 
01526     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
01527 }
01528 #endif /* MBEDTLS_CIPHER_MODE_AEAD */
01529 
01530 #endif /* MBEDTLS_CIPHER_C */