Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**
  2.  * \file cipher.c
  3.  *
  4.  * \brief Generic cipher wrapper for mbed TLS
  5.  *
  6.  * \author Adriaan de Jong <dejong@fox-it.com>
  7.  *
  8.  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  9.  *  SPDX-License-Identifier: GPL-2.0
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License along
  22.  *  with this program; if not, write to the Free Software Foundation, Inc.,
  23.  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  24.  *
  25.  *  This file is part of mbed TLS (https://tls.mbed.org)
  26.  */
  27.  
  28. #if !defined(MBEDTLS_CONFIG_FILE)
  29. #include "mbedtls/config.h"
  30. #else
  31. #include MBEDTLS_CONFIG_FILE
  32. #endif
  33.  
  34. #if defined(MBEDTLS_CIPHER_C)
  35.  
  36. #include "mbedtls/cipher.h"
  37. #include "mbedtls/cipher_internal.h"
  38. #include "mbedtls/platform_util.h"
  39.  
  40. #include <stdlib.h>
  41. #include <string.h>
  42.  
  43. #if defined(MBEDTLS_CHACHAPOLY_C)
  44. #include "mbedtls/chachapoly.h"
  45. #endif
  46.  
  47. #if defined(MBEDTLS_GCM_C)
  48. #include "mbedtls/gcm.h"
  49. #endif
  50.  
  51. #if defined(MBEDTLS_CCM_C)
  52. #include "mbedtls/ccm.h"
  53. #endif
  54.  
  55. #if defined(MBEDTLS_CHACHA20_C)
  56. #include "mbedtls/chacha20.h"
  57. #endif
  58.  
  59. #if defined(MBEDTLS_CMAC_C)
  60. #include "mbedtls/cmac.h"
  61. #endif
  62.  
  63. #if defined(MBEDTLS_PLATFORM_C)
  64. #include "mbedtls/platform.h"
  65. #else
  66. #define mbedtls_calloc calloc
  67. #define mbedtls_free   free
  68. #endif
  69.  
  70. #define CIPHER_VALIDATE_RET( cond )    \
  71.     MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
  72. #define CIPHER_VALIDATE( cond )        \
  73.     MBEDTLS_INTERNAL_VALIDATE( cond )
  74.  
  75. #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
  76. /* Compare the contents of two buffers in constant time.
  77.  * Returns 0 if the contents are bitwise identical, otherwise returns
  78.  * a non-zero value.
  79.  * This is currently only used by GCM and ChaCha20+Poly1305.
  80.  */
  81. static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len )
  82. {
  83.     const unsigned char *p1 = (const unsigned char*) v1;
  84.     const unsigned char *p2 = (const unsigned char*) v2;
  85.     size_t i;
  86.     unsigned char diff;
  87.  
  88.     for( diff = 0, i = 0; i < len; i++ )
  89.         diff |= p1[i] ^ p2[i];
  90.  
  91.     return( (int)diff );
  92. }
  93. #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
  94.  
  95. static int supported_init = 0;
  96.  
  97. const int *mbedtls_cipher_list( void )
  98. {
  99.     const mbedtls_cipher_definition_t *def;
  100.     int *type;
  101.  
  102.     if( ! supported_init )
  103.     {
  104.         def = mbedtls_cipher_definitions;
  105.         type = mbedtls_cipher_supported;
  106.  
  107.         while( def->type != 0 )
  108.             *type++ = (*def++).type;
  109.  
  110.         *type = 0;
  111.  
  112.         supported_init = 1;
  113.     }
  114.  
  115.     return( mbedtls_cipher_supported );
  116. }
  117.  
  118. const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type )
  119. {
  120.     const mbedtls_cipher_definition_t *def;
  121.  
  122.     for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
  123.         if( def->type == cipher_type )
  124.             return( def->info );
  125.  
  126.     return( NULL );
  127. }
  128.  
  129. const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name )
  130. {
  131.     const mbedtls_cipher_definition_t *def;
  132.  
  133.     if( NULL == cipher_name )
  134.         return( NULL );
  135.  
  136.     for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
  137.         if( !  strcmp( def->info->name, cipher_name ) )
  138.             return( def->info );
  139.  
  140.     return( NULL );
  141. }
  142.  
  143. const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
  144.                                               int key_bitlen,
  145.                                               const mbedtls_cipher_mode_t mode )
  146. {
  147.     const mbedtls_cipher_definition_t *def;
  148.  
  149.     for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
  150.         if( def->info->base->cipher == cipher_id &&
  151.             def->info->key_bitlen == (unsigned) key_bitlen &&
  152.             def->info->mode == mode )
  153.             return( def->info );
  154.  
  155.     return( NULL );
  156. }
  157.  
  158. void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
  159. {
  160.     CIPHER_VALIDATE( ctx != NULL );
  161.     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
  162. }
  163.  
  164. void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
  165. {
  166.     if( ctx == NULL )
  167.         return;
  168.  
  169. #if defined(MBEDTLS_CMAC_C)
  170.     if( ctx->cmac_ctx )
  171.     {
  172.        mbedtls_platform_zeroize( ctx->cmac_ctx,
  173.                                  sizeof( mbedtls_cmac_context_t ) );
  174.        mbedtls_free( ctx->cmac_ctx );
  175.     }
  176. #endif
  177.  
  178.     if( ctx->cipher_ctx )
  179.         ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
  180.  
  181.     mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
  182. }
  183.  
  184. int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
  185. {
  186.     CIPHER_VALIDATE_RET( ctx != NULL );
  187.     if( cipher_info == NULL )
  188.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  189.  
  190.     memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
  191.  
  192.     if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
  193.         return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
  194.  
  195.     ctx->cipher_info = cipher_info;
  196.  
  197. #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
  198.     /*
  199.      * Ignore possible errors caused by a cipher mode that doesn't use padding
  200.      */
  201. #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
  202.     (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
  203. #else
  204.     (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
  205. #endif
  206. #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
  207.  
  208.     return( 0 );
  209. }
  210.  
  211. int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
  212.                            const unsigned char *key,
  213.                            int key_bitlen,
  214.                            const mbedtls_operation_t operation )
  215. {
  216.     CIPHER_VALIDATE_RET( ctx != NULL );
  217.     CIPHER_VALIDATE_RET( key != NULL );
  218.     CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
  219.                          operation == MBEDTLS_DECRYPT );
  220.     if( ctx->cipher_info == NULL )
  221.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  222.  
  223.     if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
  224.         (int) ctx->cipher_info->key_bitlen != key_bitlen )
  225.     {
  226.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  227.     }
  228.  
  229.     ctx->key_bitlen = key_bitlen;
  230.     ctx->operation = operation;
  231.  
  232.     /*
  233.      * For OFB, CFB and CTR mode always use the encryption key schedule
  234.      */
  235.     if( MBEDTLS_ENCRYPT == operation ||
  236.         MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
  237.         MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
  238.         MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
  239.     {
  240.         return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
  241.                                                          ctx->key_bitlen ) );
  242.     }
  243.  
  244.     if( MBEDTLS_DECRYPT == operation )
  245.         return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
  246.                                                          ctx->key_bitlen ) );
  247.  
  248.     return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  249. }
  250.  
  251. int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
  252.                            const unsigned char *iv,
  253.                            size_t iv_len )
  254. {
  255.     size_t actual_iv_size;
  256.  
  257.     CIPHER_VALIDATE_RET( ctx != NULL );
  258.     CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
  259.     if( ctx->cipher_info == NULL )
  260.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  261.  
  262.     /* avoid buffer overflow in ctx->iv */
  263.     if( iv_len > MBEDTLS_MAX_IV_LENGTH )
  264.         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
  265.  
  266.     if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
  267.         actual_iv_size = iv_len;
  268.     else
  269.     {
  270.         actual_iv_size = ctx->cipher_info->iv_size;
  271.  
  272.         /* avoid reading past the end of input buffer */
  273.         if( actual_iv_size > iv_len )
  274.             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  275.     }
  276.  
  277. #if defined(MBEDTLS_CHACHA20_C)
  278.     if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
  279.     {
  280.         if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
  281.                                            iv,
  282.                                            0U ) ) /* Initial counter value */
  283.         {
  284.             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  285.         }
  286.     }
  287. #endif
  288.  
  289.     if ( actual_iv_size != 0 )
  290.     {
  291.         memcpy( ctx->iv, iv, actual_iv_size );
  292.         ctx->iv_size = actual_iv_size;
  293.     }
  294.  
  295.     return( 0 );
  296. }
  297.  
  298. int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
  299. {
  300.     CIPHER_VALIDATE_RET( ctx != NULL );
  301.     if( ctx->cipher_info == NULL )
  302.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  303.  
  304.     ctx->unprocessed_len = 0;
  305.  
  306.     return( 0 );
  307. }
  308.  
  309. #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
  310. int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
  311.                       const unsigned char *ad, size_t ad_len )
  312. {
  313.     CIPHER_VALIDATE_RET( ctx != NULL );
  314.     CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
  315.     if( ctx->cipher_info == NULL )
  316.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  317.  
  318. #if defined(MBEDTLS_GCM_C)
  319.     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
  320.     {
  321.         return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
  322.                                     ctx->iv, ctx->iv_size, ad, ad_len ) );
  323.     }
  324. #endif
  325.  
  326. #if defined(MBEDTLS_CHACHAPOLY_C)
  327.     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
  328.     {
  329.         int result;
  330.         mbedtls_chachapoly_mode_t mode;
  331.  
  332.         mode = ( ctx->operation == MBEDTLS_ENCRYPT )
  333.                 ? MBEDTLS_CHACHAPOLY_ENCRYPT
  334.                 : MBEDTLS_CHACHAPOLY_DECRYPT;
  335.  
  336.         result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
  337.                                                         ctx->iv,
  338.                                                         mode );
  339.         if ( result != 0 )
  340.             return( result );
  341.  
  342.         return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
  343.                                                ad, ad_len ) );
  344.     }
  345. #endif
  346.  
  347.     return( 0 );
  348. }
  349. #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
  350.  
  351. int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
  352.                    size_t ilen, unsigned char *output, size_t *olen )
  353. {
  354.     int ret;
  355.     size_t block_size;
  356.  
  357.     CIPHER_VALIDATE_RET( ctx != NULL );
  358.     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
  359.     CIPHER_VALIDATE_RET( output != NULL );
  360.     CIPHER_VALIDATE_RET( olen != NULL );
  361.     if( ctx->cipher_info == NULL )
  362.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  363.  
  364.     *olen = 0;
  365.     block_size = mbedtls_cipher_get_block_size( ctx );
  366.     if ( 0 == block_size )
  367.     {
  368.         return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
  369.     }
  370.  
  371.     if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
  372.     {
  373.         if( ilen != block_size )
  374.             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
  375.  
  376.         *olen = ilen;
  377.  
  378.         if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
  379.                     ctx->operation, input, output ) ) )
  380.         {
  381.             return( ret );
  382.         }
  383.  
  384.         return( 0 );
  385.     }
  386.  
  387. #if defined(MBEDTLS_GCM_C)
  388.     if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
  389.     {
  390.         *olen = ilen;
  391.         return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
  392.                                     output ) );
  393.     }
  394. #endif
  395.  
  396. #if defined(MBEDTLS_CHACHAPOLY_C)
  397.     if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
  398.     {
  399.         *olen = ilen;
  400.         return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
  401.                                            ilen, input, output ) );
  402.     }
  403. #endif
  404.  
  405.     if( input == output &&
  406.        ( ctx->unprocessed_len != 0 || ilen % block_size ) )
  407.     {
  408.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  409.     }
  410.  
  411. #if defined(MBEDTLS_CIPHER_MODE_CBC)
  412.     if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
  413.     {
  414.         size_t copy_len = 0;
  415.  
  416.         /*
  417.          * If there is not enough data for a full block, cache it.
  418.          */
  419.         if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
  420.                 ilen <= block_size - ctx->unprocessed_len ) ||
  421.             ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
  422.                 ilen < block_size - ctx->unprocessed_len ) ||
  423.              ( ctx->operation == MBEDTLS_ENCRYPT &&
  424.                 ilen < block_size - ctx->unprocessed_len ) )
  425.         {
  426.             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
  427.                     ilen );
  428.  
  429.             ctx->unprocessed_len += ilen;
  430.             return( 0 );
  431.         }
  432.  
  433.         /*
  434.          * Process cached data first
  435.          */
  436.         if( 0 != ctx->unprocessed_len )
  437.         {
  438.             copy_len = block_size - ctx->unprocessed_len;
  439.  
  440.             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
  441.                     copy_len );
  442.  
  443.             if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
  444.                     ctx->operation, block_size, ctx->iv,
  445.                     ctx->unprocessed_data, output ) ) )
  446.             {
  447.                 return( ret );
  448.             }
  449.  
  450.             *olen += block_size;
  451.             output += block_size;
  452.             ctx->unprocessed_len = 0;
  453.  
  454.             input += copy_len;
  455.             ilen -= copy_len;
  456.         }
  457.  
  458.         /*
  459.          * Cache final, incomplete block
  460.          */
  461.         if( 0 != ilen )
  462.         {
  463.             /* Encryption: only cache partial blocks
  464.              * Decryption w/ padding: always keep at least one whole block
  465.              * Decryption w/o padding: only cache partial blocks
  466.              */
  467.             copy_len = ilen % block_size;
  468.             if( copy_len == 0 &&
  469.                 ctx->operation == MBEDTLS_DECRYPT &&
  470.                 NULL != ctx->add_padding)
  471.             {
  472.                 copy_len = block_size;
  473.             }
  474.  
  475.             memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
  476.                     copy_len );
  477.  
  478.             ctx->unprocessed_len += copy_len;
  479.             ilen -= copy_len;
  480.         }
  481.  
  482.         /*
  483.          * Process remaining full blocks
  484.          */
  485.         if( ilen )
  486.         {
  487.             if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
  488.                     ctx->operation, ilen, ctx->iv, input, output ) ) )
  489.             {
  490.                 return( ret );
  491.             }
  492.  
  493.             *olen += ilen;
  494.         }
  495.  
  496.         return( 0 );
  497.     }
  498. #endif /* MBEDTLS_CIPHER_MODE_CBC */
  499.  
  500. #if defined(MBEDTLS_CIPHER_MODE_CFB)
  501.     if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
  502.     {
  503.         if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
  504.                 ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
  505.                 input, output ) ) )
  506.         {
  507.             return( ret );
  508.         }
  509.  
  510.         *olen = ilen;
  511.  
  512.         return( 0 );
  513.     }
  514. #endif /* MBEDTLS_CIPHER_MODE_CFB */
  515.  
  516. #if defined(MBEDTLS_CIPHER_MODE_OFB)
  517.     if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
  518.     {
  519.         if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
  520.                 ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
  521.         {
  522.             return( ret );
  523.         }
  524.  
  525.         *olen = ilen;
  526.  
  527.         return( 0 );
  528.     }
  529. #endif /* MBEDTLS_CIPHER_MODE_OFB */
  530.  
  531. #if defined(MBEDTLS_CIPHER_MODE_CTR)
  532.     if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
  533.     {
  534.         if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
  535.                 ilen, &ctx->unprocessed_len, ctx->iv,
  536.                 ctx->unprocessed_data, input, output ) ) )
  537.         {
  538.             return( ret );
  539.         }
  540.  
  541.         *olen = ilen;
  542.  
  543.         return( 0 );
  544.     }
  545. #endif /* MBEDTLS_CIPHER_MODE_CTR */
  546.  
  547. #if defined(MBEDTLS_CIPHER_MODE_XTS)
  548.     if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
  549.     {
  550.         if( ctx->unprocessed_len > 0 ) {
  551.             /* We can only process an entire data unit at a time. */
  552.             return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
  553.         }
  554.  
  555.         ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
  556.                 ctx->operation, ilen, ctx->iv, input, output );
  557.         if( ret != 0 )
  558.         {
  559.             return( ret );
  560.         }
  561.  
  562.         *olen = ilen;
  563.  
  564.         return( 0 );
  565.     }
  566. #endif /* MBEDTLS_CIPHER_MODE_XTS */
  567.  
  568. #if defined(MBEDTLS_CIPHER_MODE_STREAM)
  569.     if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
  570.     {
  571.         if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
  572.                                                     ilen, input, output ) ) )
  573.         {
  574.             return( ret );
  575.         }
  576.  
  577.         *olen = ilen;
  578.  
  579.         return( 0 );
  580.     }
  581. #endif /* MBEDTLS_CIPHER_MODE_STREAM */
  582.  
  583.     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
  584. }
  585.  
  586. #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
  587. #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
  588. /*
  589.  * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
  590.  */
  591. static void add_pkcs_padding( unsigned char *output, size_t output_len,
  592.         size_t data_len )
  593. {
  594.     size_t padding_len = output_len - data_len;
  595.     unsigned char i;
  596.  
  597.     for( i = 0; i < padding_len; i++ )
  598.         output[data_len + i] = (unsigned char) padding_len;
  599. }
  600.  
  601. static int get_pkcs_padding( unsigned char *input, size_t input_len,
  602.         size_t *data_len )
  603. {
  604.     size_t i, pad_idx;
  605.     unsigned char padding_len, bad = 0;
  606.  
  607.     if( NULL == input || NULL == data_len )
  608.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  609.  
  610.     padding_len = input[input_len - 1];
  611.     *data_len = input_len - padding_len;
  612.  
  613.     /* Avoid logical || since it results in a branch */
  614.     bad |= padding_len > input_len;
  615.     bad |= padding_len == 0;
  616.  
  617.     /* The number of bytes checked must be independent of padding_len,
  618.      * so pick input_len, which is usually 8 or 16 (one block) */
  619.     pad_idx = input_len - padding_len;
  620.     for( i = 0; i < input_len; i++ )
  621.         bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
  622.  
  623.     return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
  624. }
  625. #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
  626.  
  627. #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
  628. /*
  629.  * One and zeros padding: fill with 80 00 ... 00
  630.  */
  631. static void add_one_and_zeros_padding( unsigned char *output,
  632.                                        size_t output_len, size_t data_len )
  633. {
  634.     size_t padding_len = output_len - data_len;
  635.     unsigned char i = 0;
  636.  
  637.     output[data_len] = 0x80;
  638.     for( i = 1; i < padding_len; i++ )
  639.         output[data_len + i] = 0x00;
  640. }
  641.  
  642. static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
  643.                                       size_t *data_len )
  644. {
  645.     size_t i;
  646.     unsigned char done = 0, prev_done, bad;
  647.  
  648.     if( NULL == input || NULL == data_len )
  649.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  650.  
  651.     bad = 0x80;
  652.     *data_len = 0;
  653.     for( i = input_len; i > 0; i-- )
  654.     {
  655.         prev_done = done;
  656.         done |= ( input[i - 1] != 0 );
  657.         *data_len |= ( i - 1 ) * ( done != prev_done );
  658.         bad ^= input[i - 1] * ( done != prev_done );
  659.     }
  660.  
  661.     return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
  662.  
  663. }
  664. #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
  665.  
  666. #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
  667. /*
  668.  * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
  669.  */
  670. static void add_zeros_and_len_padding( unsigned char *output,
  671.                                        size_t output_len, size_t data_len )
  672. {
  673.     size_t padding_len = output_len - data_len;
  674.     unsigned char i = 0;
  675.  
  676.     for( i = 1; i < padding_len; i++ )
  677.         output[data_len + i - 1] = 0x00;
  678.     output[output_len - 1] = (unsigned char) padding_len;
  679. }
  680.  
  681. static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
  682.                                       size_t *data_len )
  683. {
  684.     size_t i, pad_idx;
  685.     unsigned char padding_len, bad = 0;
  686.  
  687.     if( NULL == input || NULL == data_len )
  688.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  689.  
  690.     padding_len = input[input_len - 1];
  691.     *data_len = input_len - padding_len;
  692.  
  693.     /* Avoid logical || since it results in a branch */
  694.     bad |= padding_len > input_len;
  695.     bad |= padding_len == 0;
  696.  
  697.     /* The number of bytes checked must be independent of padding_len */
  698.     pad_idx = input_len - padding_len;
  699.     for( i = 0; i < input_len - 1; i++ )
  700.         bad |= input[i] * ( i >= pad_idx );
  701.  
  702.     return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
  703. }
  704. #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
  705.  
  706. #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
  707. /*
  708.  * Zero padding: fill with 00 ... 00
  709.  */
  710. static void add_zeros_padding( unsigned char *output,
  711.                                size_t output_len, size_t data_len )
  712. {
  713.     size_t i;
  714.  
  715.     for( i = data_len; i < output_len; i++ )
  716.         output[i] = 0x00;
  717. }
  718.  
  719. static int get_zeros_padding( unsigned char *input, size_t input_len,
  720.                               size_t *data_len )
  721. {
  722.     size_t i;
  723.     unsigned char done = 0, prev_done;
  724.  
  725.     if( NULL == input || NULL == data_len )
  726.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  727.  
  728.     *data_len = 0;
  729.     for( i = input_len; i > 0; i-- )
  730.     {
  731.         prev_done = done;
  732.         done |= ( input[i-1] != 0 );
  733.         *data_len |= i * ( done != prev_done );
  734.     }
  735.  
  736.     return( 0 );
  737. }
  738. #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
  739.  
  740. /*
  741.  * No padding: don't pad :)
  742.  *
  743.  * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
  744.  * but a trivial get_padding function
  745.  */
  746. static int get_no_padding( unsigned char *input, size_t input_len,
  747.                               size_t *data_len )
  748. {
  749.     if( NULL == input || NULL == data_len )
  750.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  751.  
  752.     *data_len = input_len;
  753.  
  754.     return( 0 );
  755. }
  756. #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
  757.  
  758. int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
  759.                    unsigned char *output, size_t *olen )
  760. {
  761.     CIPHER_VALIDATE_RET( ctx != NULL );
  762.     CIPHER_VALIDATE_RET( output != NULL );
  763.     CIPHER_VALIDATE_RET( olen != NULL );
  764.     if( ctx->cipher_info == NULL )
  765.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  766.  
  767.     *olen = 0;
  768.  
  769.     if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
  770.         MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
  771.         MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
  772.         MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
  773.         MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
  774.         MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
  775.     {
  776.         return( 0 );
  777.     }
  778.  
  779.     if ( ( MBEDTLS_CIPHER_CHACHA20          == ctx->cipher_info->type ) ||
  780.          ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
  781.     {
  782.         return( 0 );
  783.     }
  784.  
  785.     if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
  786.     {
  787.         if( ctx->unprocessed_len != 0 )
  788.             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
  789.  
  790.         return( 0 );
  791.     }
  792.  
  793. #if defined(MBEDTLS_CIPHER_MODE_CBC)
  794.     if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
  795.     {
  796.         int ret = 0;
  797.  
  798.         if( MBEDTLS_ENCRYPT == ctx->operation )
  799.         {
  800.             /* check for 'no padding' mode */
  801.             if( NULL == ctx->add_padding )
  802.             {
  803.                 if( 0 != ctx->unprocessed_len )
  804.                     return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
  805.  
  806.                 return( 0 );
  807.             }
  808.  
  809.             ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
  810.                     ctx->unprocessed_len );
  811.         }
  812.         else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
  813.         {
  814.             /*
  815.              * For decrypt operations, expect a full block,
  816.              * or an empty block if no padding
  817.              */
  818.             if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
  819.                 return( 0 );
  820.  
  821.             return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
  822.         }
  823.  
  824.         /* cipher block */
  825.         if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
  826.                 ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
  827.                 ctx->unprocessed_data, output ) ) )
  828.         {
  829.             return( ret );
  830.         }
  831.  
  832.         /* Set output size for decryption */
  833.         if( MBEDTLS_DECRYPT == ctx->operation )
  834.             return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
  835.                                       olen ) );
  836.  
  837.         /* Set output size for encryption */
  838.         *olen = mbedtls_cipher_get_block_size( ctx );
  839.         return( 0 );
  840.     }
  841. #else
  842.     ((void) output);
  843. #endif /* MBEDTLS_CIPHER_MODE_CBC */
  844.  
  845.     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
  846. }
  847.  
  848. #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
  849. int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
  850.                                      mbedtls_cipher_padding_t mode )
  851. {
  852.     CIPHER_VALIDATE_RET( ctx != NULL );
  853.  
  854.     if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
  855.     {
  856.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  857.     }
  858.  
  859.     switch( mode )
  860.     {
  861. #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
  862.     case MBEDTLS_PADDING_PKCS7:
  863.         ctx->add_padding = add_pkcs_padding;
  864.         ctx->get_padding = get_pkcs_padding;
  865.         break;
  866. #endif
  867. #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
  868.     case MBEDTLS_PADDING_ONE_AND_ZEROS:
  869.         ctx->add_padding = add_one_and_zeros_padding;
  870.         ctx->get_padding = get_one_and_zeros_padding;
  871.         break;
  872. #endif
  873. #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
  874.     case MBEDTLS_PADDING_ZEROS_AND_LEN:
  875.         ctx->add_padding = add_zeros_and_len_padding;
  876.         ctx->get_padding = get_zeros_and_len_padding;
  877.         break;
  878. #endif
  879. #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
  880.     case MBEDTLS_PADDING_ZEROS:
  881.         ctx->add_padding = add_zeros_padding;
  882.         ctx->get_padding = get_zeros_padding;
  883.         break;
  884. #endif
  885.     case MBEDTLS_PADDING_NONE:
  886.         ctx->add_padding = NULL;
  887.         ctx->get_padding = get_no_padding;
  888.         break;
  889.  
  890.     default:
  891.         return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
  892.     }
  893.  
  894.     return( 0 );
  895. }
  896. #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
  897.  
  898. #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
  899. int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
  900.                       unsigned char *tag, size_t tag_len )
  901. {
  902.     CIPHER_VALIDATE_RET( ctx != NULL );
  903.     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
  904.     if( ctx->cipher_info == NULL )
  905.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  906.  
  907.     if( MBEDTLS_ENCRYPT != ctx->operation )
  908.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  909.  
  910. #if defined(MBEDTLS_GCM_C)
  911.     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
  912.         return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
  913.                                     tag, tag_len ) );
  914. #endif
  915.  
  916. #if defined(MBEDTLS_CHACHAPOLY_C)
  917.     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
  918.     {
  919.         /* Don't allow truncated MAC for Poly1305 */
  920.         if ( tag_len != 16U )
  921.             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  922.  
  923.         return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
  924.                                            tag ) );
  925.     }
  926. #endif
  927.  
  928.     return( 0 );
  929. }
  930.  
  931. int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
  932.                       const unsigned char *tag, size_t tag_len )
  933. {
  934.     unsigned char check_tag[16];
  935.     int ret;
  936.  
  937.     CIPHER_VALIDATE_RET( ctx != NULL );
  938.     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
  939.     if( ctx->cipher_info == NULL )
  940.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  941.  
  942.     if( MBEDTLS_DECRYPT != ctx->operation )
  943.     {
  944.         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  945.     }
  946.  
  947. #if defined(MBEDTLS_GCM_C)
  948.     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
  949.     {
  950.         if( tag_len > sizeof( check_tag ) )
  951.             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  952.  
  953.         if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
  954.                                      check_tag, tag_len ) ) )
  955.         {
  956.             return( ret );
  957.         }
  958.  
  959.         /* Check the tag in "constant-time" */
  960.         if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
  961.             return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
  962.  
  963.         return( 0 );
  964.     }
  965. #endif /* MBEDTLS_GCM_C */
  966.  
  967. #if defined(MBEDTLS_CHACHAPOLY_C)
  968.     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
  969.     {
  970.         /* Don't allow truncated MAC for Poly1305 */
  971.         if ( tag_len != sizeof( check_tag ) )
  972.             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  973.  
  974.         ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
  975.                                                      check_tag );
  976.         if ( ret != 0 )
  977.         {
  978.             return( ret );
  979.         }
  980.  
  981.         /* Check the tag in "constant-time" */
  982.         if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
  983.             return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
  984.  
  985.         return( 0 );
  986.     }
  987. #endif /* MBEDTLS_CHACHAPOLY_C */
  988.  
  989.     return( 0 );
  990. }
  991. #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
  992.  
  993. /*
  994.  * Packet-oriented wrapper for non-AEAD modes
  995.  */
  996. int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
  997.                   const unsigned char *iv, size_t iv_len,
  998.                   const unsigned char *input, size_t ilen,
  999.                   unsigned char *output, size_t *olen )
  1000. {
  1001.     int ret;
  1002.     size_t finish_olen;
  1003.  
  1004.     CIPHER_VALIDATE_RET( ctx != NULL );
  1005.     CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
  1006.     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
  1007.     CIPHER_VALIDATE_RET( output != NULL );
  1008.     CIPHER_VALIDATE_RET( olen != NULL );
  1009.  
  1010.     if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
  1011.         return( ret );
  1012.  
  1013.     if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
  1014.         return( ret );
  1015.  
  1016.     if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 )
  1017.         return( ret );
  1018.  
  1019.     if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 )
  1020.         return( ret );
  1021.  
  1022.     *olen += finish_olen;
  1023.  
  1024.     return( 0 );
  1025. }
  1026.  
  1027. #if defined(MBEDTLS_CIPHER_MODE_AEAD)
  1028. /*
  1029.  * Packet-oriented encryption for AEAD modes
  1030.  */
  1031. int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
  1032.                          const unsigned char *iv, size_t iv_len,
  1033.                          const unsigned char *ad, size_t ad_len,
  1034.                          const unsigned char *input, size_t ilen,
  1035.                          unsigned char *output, size_t *olen,
  1036.                          unsigned char *tag, size_t tag_len )
  1037. {
  1038.     CIPHER_VALIDATE_RET( ctx != NULL );
  1039.     CIPHER_VALIDATE_RET( iv != NULL );
  1040.     CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
  1041.     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
  1042.     CIPHER_VALIDATE_RET( output != NULL );
  1043.     CIPHER_VALIDATE_RET( olen != NULL );
  1044.     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
  1045.  
  1046. #if defined(MBEDTLS_GCM_C)
  1047.     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
  1048.     {
  1049.         *olen = ilen;
  1050.         return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen,
  1051.                                    iv, iv_len, ad, ad_len, input, output,
  1052.                                    tag_len, tag ) );
  1053.     }
  1054. #endif /* MBEDTLS_GCM_C */
  1055. #if defined(MBEDTLS_CCM_C)
  1056.     if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
  1057.     {
  1058.         *olen = ilen;
  1059.         return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
  1060.                                      iv, iv_len, ad, ad_len, input, output,
  1061.                                      tag, tag_len ) );
  1062.     }
  1063. #endif /* MBEDTLS_CCM_C */
  1064. #if defined(MBEDTLS_CHACHAPOLY_C)
  1065.     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
  1066.     {
  1067.         /* ChachaPoly has fixed length nonce and MAC (tag) */
  1068.         if ( ( iv_len != ctx->cipher_info->iv_size ) ||
  1069.              ( tag_len != 16U ) )
  1070.         {
  1071.             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  1072.         }
  1073.  
  1074.         *olen = ilen;
  1075.         return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
  1076.                                 ilen, iv, ad, ad_len, input, output, tag ) );
  1077.     }
  1078. #endif /* MBEDTLS_CHACHAPOLY_C */
  1079.  
  1080.     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
  1081. }
  1082.  
  1083. /*
  1084.  * Packet-oriented decryption for AEAD modes
  1085.  */
  1086. int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
  1087.                          const unsigned char *iv, size_t iv_len,
  1088.                          const unsigned char *ad, size_t ad_len,
  1089.                          const unsigned char *input, size_t ilen,
  1090.                          unsigned char *output, size_t *olen,
  1091.                          const unsigned char *tag, size_t tag_len )
  1092. {
  1093.     CIPHER_VALIDATE_RET( ctx != NULL );
  1094.     CIPHER_VALIDATE_RET( iv != NULL );
  1095.     CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
  1096.     CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
  1097.     CIPHER_VALIDATE_RET( output != NULL );
  1098.     CIPHER_VALIDATE_RET( olen != NULL );
  1099.     CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
  1100.  
  1101. #if defined(MBEDTLS_GCM_C)
  1102.     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
  1103.     {
  1104.         int ret;
  1105.  
  1106.         *olen = ilen;
  1107.         ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
  1108.                                 iv, iv_len, ad, ad_len,
  1109.                                 tag, tag_len, input, output );
  1110.  
  1111.         if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
  1112.             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
  1113.  
  1114.         return( ret );
  1115.     }
  1116. #endif /* MBEDTLS_GCM_C */
  1117. #if defined(MBEDTLS_CCM_C)
  1118.     if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
  1119.     {
  1120.         int ret;
  1121.  
  1122.         *olen = ilen;
  1123.         ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
  1124.                                 iv, iv_len, ad, ad_len,
  1125.                                 input, output, tag, tag_len );
  1126.  
  1127.         if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
  1128.             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
  1129.  
  1130.         return( ret );
  1131.     }
  1132. #endif /* MBEDTLS_CCM_C */
  1133. #if defined(MBEDTLS_CHACHAPOLY_C)
  1134.     if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
  1135.     {
  1136.         int ret;
  1137.  
  1138.         /* ChachaPoly has fixed length nonce and MAC (tag) */
  1139.         if ( ( iv_len != ctx->cipher_info->iv_size ) ||
  1140.              ( tag_len != 16U ) )
  1141.         {
  1142.             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  1143.         }
  1144.  
  1145.         *olen = ilen;
  1146.         ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
  1147.                                 iv, ad, ad_len, tag, input, output );
  1148.  
  1149.         if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
  1150.             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
  1151.  
  1152.         return( ret );
  1153.     }
  1154. #endif /* MBEDTLS_CHACHAPOLY_C */
  1155.  
  1156.     return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
  1157. }
  1158. #endif /* MBEDTLS_CIPHER_MODE_AEAD */
  1159.  
  1160. #endif /* MBEDTLS_CIPHER_C */
  1161.