LCOV - code coverage report
Current view: top level - externals/mbedtls/library - cipher.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 29.1 % 148 43
Test Date: 2026-03-12 12:01:18 Functions: 31.6 % 19 6
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 16.2 % 130 21

             Branch data     Line data    Source code
       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 The Mbed TLS Contributors
       9                 :             :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
      10                 :             :  */
      11                 :             : 
      12                 :             : #include "common.h"
      13                 :             : 
      14                 :             : #if defined(MBEDTLS_CIPHER_C)
      15                 :             : 
      16                 :             : #include "mbedtls/cipher.h"
      17                 :             : #include "cipher_invasive.h"
      18                 :             : #include "cipher_wrap.h"
      19                 :             : #include "mbedtls/platform_util.h"
      20                 :             : #include "mbedtls/error.h"
      21                 :             : #include "mbedtls/constant_time.h"
      22                 :             : #include "constant_time_internal.h"
      23                 :             : 
      24                 :             : #include <stdlib.h>
      25                 :             : #include <string.h>
      26                 :             : 
      27                 :             : #if defined(MBEDTLS_CHACHAPOLY_C)
      28                 :             : #include "mbedtls/chachapoly.h"
      29                 :             : #endif
      30                 :             : 
      31                 :             : #if defined(MBEDTLS_GCM_C)
      32                 :             : #include "mbedtls/gcm.h"
      33                 :             : #endif
      34                 :             : 
      35                 :             : #if defined(MBEDTLS_CCM_C)
      36                 :             : #include "mbedtls/ccm.h"
      37                 :             : #endif
      38                 :             : 
      39                 :             : #if defined(MBEDTLS_CHACHA20_C)
      40                 :             : #include "mbedtls/chacha20.h"
      41                 :             : #endif
      42                 :             : 
      43                 :             : #if defined(MBEDTLS_CMAC_C)
      44                 :             : #include "mbedtls/cmac.h"
      45                 :             : #endif
      46                 :             : 
      47                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
      48                 :             : #include "psa/crypto.h"
      49                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
      50                 :             : 
      51                 :             : #if defined(MBEDTLS_NIST_KW_C)
      52                 :             : #include "mbedtls/nist_kw.h"
      53                 :             : #endif
      54                 :             : 
      55                 :             : #include "mbedtls/platform.h"
      56                 :             : 
      57                 :             : static int supported_init = 0;
      58                 :             : 
      59                 :         474 : static inline const mbedtls_cipher_base_t *mbedtls_cipher_get_base(
      60                 :             :     const mbedtls_cipher_info_t *info)
      61                 :             : {
      62                 :         474 :     return mbedtls_cipher_base_lookup_table[info->base_idx];
      63                 :             : }
      64                 :             : 
      65                 :           0 : const int *mbedtls_cipher_list(void)
      66                 :             : {
      67                 :           0 :     const mbedtls_cipher_definition_t *def;
      68                 :           0 :     int *type;
      69                 :             : 
      70         [ #  # ]:           0 :     if (!supported_init) {
      71                 :             :         def = mbedtls_cipher_definitions;
      72                 :             :         type = mbedtls_cipher_supported;
      73                 :             : 
      74         [ #  # ]:           0 :         while (def->type != 0) {
      75                 :           0 :             *type++ = (*def++).type;
      76                 :             :         }
      77                 :             : 
      78                 :           0 :         *type = 0;
      79                 :             : 
      80                 :           0 :         supported_init = 1;
      81                 :             :     }
      82                 :             : 
      83                 :           0 :     return mbedtls_cipher_supported;
      84                 :             : }
      85                 :             : 
      86                 :           0 : const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
      87                 :             :     const mbedtls_cipher_type_t cipher_type)
      88                 :             : {
      89                 :           0 :     const mbedtls_cipher_definition_t *def;
      90                 :             : 
      91         [ #  # ]:           0 :     for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
      92         [ #  # ]:           0 :         if (def->type == cipher_type) {
      93                 :           0 :             return def->info;
      94                 :             :         }
      95                 :             :     }
      96                 :             : 
      97                 :             :     return NULL;
      98                 :             : }
      99                 :             : 
     100                 :           0 : const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
     101                 :             :     const char *cipher_name)
     102                 :             : {
     103                 :           0 :     const mbedtls_cipher_definition_t *def;
     104                 :             : 
     105         [ #  # ]:           0 :     if (NULL == cipher_name) {
     106                 :             :         return NULL;
     107                 :             :     }
     108                 :             : 
     109         [ #  # ]:           0 :     for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
     110         [ #  # ]:           0 :         if (!strcmp(def->info->name, cipher_name)) {
     111                 :           0 :             return def->info;
     112                 :             :         }
     113                 :             :     }
     114                 :             : 
     115                 :             :     return NULL;
     116                 :             : }
     117                 :             : 
     118                 :          34 : const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
     119                 :             :     const mbedtls_cipher_id_t cipher_id,
     120                 :             :     int key_bitlen,
     121                 :             :     const mbedtls_cipher_mode_t mode)
     122                 :             : {
     123                 :          34 :     const mbedtls_cipher_definition_t *def;
     124                 :             : 
     125         [ +  - ]:          34 :     for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
     126         [ +  - ]:          34 :         if (mbedtls_cipher_get_base(def->info)->cipher == cipher_id &&
     127         [ +  - ]:          34 :             mbedtls_cipher_info_get_key_bitlen(def->info) == (unsigned) key_bitlen &&
     128         [ +  - ]:          34 :             def->info->mode == mode) {
     129                 :          34 :             return def->info;
     130                 :             :         }
     131                 :             :     }
     132                 :             : 
     133                 :             :     return NULL;
     134                 :             : }
     135                 :             : 
     136                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
     137                 :             : static inline psa_key_type_t mbedtls_psa_translate_cipher_type(
     138                 :             :     mbedtls_cipher_type_t cipher)
     139                 :             : {
     140                 :             :     switch (cipher) {
     141                 :             :         case MBEDTLS_CIPHER_AES_128_CCM:
     142                 :             :         case MBEDTLS_CIPHER_AES_192_CCM:
     143                 :             :         case MBEDTLS_CIPHER_AES_256_CCM:
     144                 :             :         case MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:
     145                 :             :         case MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:
     146                 :             :         case MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:
     147                 :             :         case MBEDTLS_CIPHER_AES_128_GCM:
     148                 :             :         case MBEDTLS_CIPHER_AES_192_GCM:
     149                 :             :         case MBEDTLS_CIPHER_AES_256_GCM:
     150                 :             :         case MBEDTLS_CIPHER_AES_128_CBC:
     151                 :             :         case MBEDTLS_CIPHER_AES_192_CBC:
     152                 :             :         case MBEDTLS_CIPHER_AES_256_CBC:
     153                 :             :         case MBEDTLS_CIPHER_AES_128_ECB:
     154                 :             :         case MBEDTLS_CIPHER_AES_192_ECB:
     155                 :             :         case MBEDTLS_CIPHER_AES_256_ECB:
     156                 :             :             return PSA_KEY_TYPE_AES;
     157                 :             : 
     158                 :             :         /* ARIA not yet supported in PSA. */
     159                 :             :         /* case MBEDTLS_CIPHER_ARIA_128_CCM:
     160                 :             :            case MBEDTLS_CIPHER_ARIA_192_CCM:
     161                 :             :            case MBEDTLS_CIPHER_ARIA_256_CCM:
     162                 :             :            case MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:
     163                 :             :            case MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:
     164                 :             :            case MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:
     165                 :             :            case MBEDTLS_CIPHER_ARIA_128_GCM:
     166                 :             :            case MBEDTLS_CIPHER_ARIA_192_GCM:
     167                 :             :            case MBEDTLS_CIPHER_ARIA_256_GCM:
     168                 :             :            case MBEDTLS_CIPHER_ARIA_128_CBC:
     169                 :             :            case MBEDTLS_CIPHER_ARIA_192_CBC:
     170                 :             :            case MBEDTLS_CIPHER_ARIA_256_CBC:
     171                 :             :                return( PSA_KEY_TYPE_ARIA ); */
     172                 :             : 
     173                 :             :         default:
     174                 :             :             return 0;
     175                 :             :     }
     176                 :             : }
     177                 :             : 
     178                 :             : static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode(
     179                 :             :     mbedtls_cipher_mode_t mode, size_t taglen)
     180                 :             : {
     181                 :             :     switch (mode) {
     182                 :             :         case MBEDTLS_MODE_ECB:
     183                 :             :             return PSA_ALG_ECB_NO_PADDING;
     184                 :             :         case MBEDTLS_MODE_GCM:
     185                 :             :             return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, taglen);
     186                 :             :         case MBEDTLS_MODE_CCM:
     187                 :             :             return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen);
     188                 :             :         case MBEDTLS_MODE_CCM_STAR_NO_TAG:
     189                 :             :             return PSA_ALG_CCM_STAR_NO_TAG;
     190                 :             :         case MBEDTLS_MODE_CBC:
     191                 :             :             if (taglen == 0) {
     192                 :             :                 return PSA_ALG_CBC_NO_PADDING;
     193                 :             :             } else {
     194                 :             :                 return 0;
     195                 :             :             }
     196                 :             :         default:
     197                 :             :             return 0;
     198                 :             :     }
     199                 :             : }
     200                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
     201                 :             : 
     202                 :           0 : void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx)
     203                 :             : {
     204                 :           0 :     memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
     205                 :           0 : }
     206                 :             : 
     207                 :          68 : void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
     208                 :             : {
     209         [ +  - ]:          68 :     if (ctx == NULL) {
     210                 :             :         return;
     211                 :             :     }
     212                 :             : 
     213                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
     214                 :             :     if (ctx->psa_enabled == 1) {
     215                 :             :         if (ctx->cipher_ctx != NULL) {
     216                 :             :             mbedtls_cipher_context_psa * const cipher_psa =
     217                 :             :                 (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
     218                 :             : 
     219                 :             :             if (cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED) {
     220                 :             :                 /* xxx_free() doesn't allow to return failures. */
     221                 :             :                 (void) psa_destroy_key(cipher_psa->slot);
     222                 :             :             }
     223                 :             : 
     224                 :             :             mbedtls_zeroize_and_free(cipher_psa, sizeof(*cipher_psa));
     225                 :             :         }
     226                 :             : 
     227                 :             :         mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
     228                 :             :         return;
     229                 :             :     }
     230                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
     231                 :             : 
     232                 :             : #if defined(MBEDTLS_CMAC_C)
     233                 :             :     if (ctx->cmac_ctx) {
     234                 :             :         mbedtls_zeroize_and_free(ctx->cmac_ctx,
     235                 :             :                                  sizeof(mbedtls_cmac_context_t));
     236                 :             :     }
     237                 :             : #endif
     238                 :             : 
     239         [ +  + ]:          68 :     if (ctx->cipher_ctx) {
     240                 :          34 :         mbedtls_cipher_get_base(ctx->cipher_info)->ctx_free_func(ctx->cipher_ctx);
     241                 :             :     }
     242                 :             : 
     243                 :          68 :     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
     244                 :             : }
     245                 :             : 
     246                 :          34 : int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx,
     247                 :             :                          const mbedtls_cipher_info_t *cipher_info)
     248                 :             : {
     249         [ +  - ]:          34 :     if (cipher_info == NULL) {
     250                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     251                 :             :     }
     252                 :             : 
     253         [ +  - ]:          34 :     memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
     254                 :             : 
     255         [ +  - ]:          34 :     if (mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func != NULL) {
     256                 :          34 :         ctx->cipher_ctx = mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func();
     257         [ +  - ]:          34 :         if (ctx->cipher_ctx == NULL) {
     258                 :             :             return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
     259                 :             :         }
     260                 :             :     }
     261                 :             : 
     262                 :          34 :     ctx->cipher_info = cipher_info;
     263                 :             : 
     264                 :          34 :     return 0;
     265                 :             : }
     266                 :             : 
     267                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
     268                 :             : int mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx,
     269                 :             :                              const mbedtls_cipher_info_t *cipher_info,
     270                 :             :                              size_t taglen)
     271                 :             : {
     272                 :             :     psa_algorithm_t alg;
     273                 :             :     mbedtls_cipher_context_psa *cipher_psa;
     274                 :             : 
     275                 :             :     if (NULL == cipher_info || NULL == ctx) {
     276                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     277                 :             :     }
     278                 :             : 
     279                 :             :     /* Check that the underlying cipher mode and cipher type are
     280                 :             :      * supported by the underlying PSA Crypto implementation. */
     281                 :             :     alg = mbedtls_psa_translate_cipher_mode(((mbedtls_cipher_mode_t) cipher_info->mode), taglen);
     282                 :             :     if (alg == 0) {
     283                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     284                 :             :     }
     285                 :             :     if (mbedtls_psa_translate_cipher_type(((mbedtls_cipher_type_t) cipher_info->type)) == 0) {
     286                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     287                 :             :     }
     288                 :             : 
     289                 :             :     memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
     290                 :             : 
     291                 :             :     cipher_psa = mbedtls_calloc(1, sizeof(mbedtls_cipher_context_psa));
     292                 :             :     if (cipher_psa == NULL) {
     293                 :             :         return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
     294                 :             :     }
     295                 :             :     cipher_psa->alg  = alg;
     296                 :             :     ctx->cipher_ctx  = cipher_psa;
     297                 :             :     ctx->cipher_info = cipher_info;
     298                 :             :     ctx->psa_enabled = 1;
     299                 :             :     return 0;
     300                 :             : }
     301                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
     302                 :             : 
     303                 :          34 : int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
     304                 :             :                           const unsigned char *key,
     305                 :             :                           int key_bitlen,
     306                 :             :                           const mbedtls_operation_t operation)
     307                 :             : {
     308         [ +  - ]:          34 :     if (operation != MBEDTLS_ENCRYPT && operation != MBEDTLS_DECRYPT) {
     309                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     310                 :             :     }
     311         [ +  - ]:          34 :     if (ctx->cipher_info == NULL) {
     312                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     313                 :             :     }
     314                 :             : #if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     315                 :             :     if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) &&
     316                 :             :         MBEDTLS_DECRYPT == operation) {
     317                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     318                 :             :     }
     319                 :             : #endif
     320                 :             : 
     321                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
     322                 :             :     if (ctx->psa_enabled == 1) {
     323                 :             :         mbedtls_cipher_context_psa * const cipher_psa =
     324                 :             :             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
     325                 :             : 
     326                 :             :         size_t const key_bytelen = ((size_t) key_bitlen + 7) / 8;
     327                 :             : 
     328                 :             :         psa_status_t status;
     329                 :             :         psa_key_type_t key_type;
     330                 :             :         psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     331                 :             : 
     332                 :             :         /* PSA Crypto API only accepts byte-aligned keys. */
     333                 :             :         if (key_bitlen % 8 != 0) {
     334                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     335                 :             :         }
     336                 :             : 
     337                 :             :         /* Don't allow keys to be set multiple times. */
     338                 :             :         if (cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET) {
     339                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     340                 :             :         }
     341                 :             : 
     342                 :             :         key_type = mbedtls_psa_translate_cipher_type(
     343                 :             :             ((mbedtls_cipher_type_t) ctx->cipher_info->type));
     344                 :             :         if (key_type == 0) {
     345                 :             :             return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     346                 :             :         }
     347                 :             :         psa_set_key_type(&attributes, key_type);
     348                 :             : 
     349                 :             :         /* Mbed TLS' cipher layer doesn't enforce the mode of operation
     350                 :             :          * (encrypt vs. decrypt): it is possible to setup a key for encryption
     351                 :             :          * and use it for AEAD decryption. Until tests relying on this
     352                 :             :          * are changed, allow any usage in PSA. */
     353                 :             :         psa_set_key_usage_flags(&attributes,
     354                 :             :                                 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
     355                 :             :         psa_set_key_algorithm(&attributes, cipher_psa->alg);
     356                 :             : 
     357                 :             :         status = psa_import_key(&attributes, key, key_bytelen,
     358                 :             :                                 &cipher_psa->slot);
     359                 :             :         switch (status) {
     360                 :             :             case PSA_SUCCESS:
     361                 :             :                 break;
     362                 :             :             case PSA_ERROR_INSUFFICIENT_MEMORY:
     363                 :             :                 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
     364                 :             :             case PSA_ERROR_NOT_SUPPORTED:
     365                 :             :                 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     366                 :             :             default:
     367                 :             :                 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
     368                 :             :         }
     369                 :             :         /* Indicate that we own the key slot and need to
     370                 :             :          * destroy it in mbedtls_cipher_free(). */
     371                 :             :         cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
     372                 :             : 
     373                 :             :         ctx->key_bitlen = key_bitlen;
     374                 :             :         ctx->operation = operation;
     375                 :             :         return 0;
     376                 :             :     }
     377                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
     378                 :             : 
     379         [ +  - ]:          34 :     if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN) == 0 &&
     380         [ +  - ]:          34 :         (int) mbedtls_cipher_info_get_key_bitlen(ctx->cipher_info) != key_bitlen) {
     381                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     382                 :             :     }
     383                 :             : 
     384                 :          34 :     ctx->key_bitlen = key_bitlen;
     385                 :          34 :     ctx->operation = operation;
     386                 :             : 
     387                 :             : #if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
     388                 :             :     /*
     389                 :             :      * For OFB, CFB and CTR mode always use the encryption key schedule
     390                 :             :      */
     391         [ -  + ]:          34 :     if (MBEDTLS_ENCRYPT == operation ||
     392   [ #  #  #  # ]:           0 :         MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
     393         [ #  # ]:           0 :         MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
     394                 :             :         MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
     395                 :          34 :         return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key,
     396                 :             :                                                                           ctx->key_bitlen);
     397                 :             :     }
     398                 :             : 
     399                 :           0 :     if (MBEDTLS_DECRYPT == operation) {
     400                 :           0 :         return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_dec_func(ctx->cipher_ctx, key,
     401                 :             :                                                                           ctx->key_bitlen);
     402                 :             :     }
     403                 :             : #else
     404                 :             :     if (operation == MBEDTLS_ENCRYPT || operation == MBEDTLS_DECRYPT) {
     405                 :             :         return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key,
     406                 :             :                                                                           ctx->key_bitlen);
     407                 :             :     }
     408                 :             : #endif
     409                 :             : 
     410                 :             :     return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     411                 :             : }
     412                 :             : 
     413                 :           0 : int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
     414                 :             :                           const unsigned char *iv,
     415                 :             :                           size_t iv_len)
     416                 :             : {
     417                 :           0 :     size_t actual_iv_size;
     418                 :             : 
     419         [ #  # ]:           0 :     if (ctx->cipher_info == NULL) {
     420                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     421                 :             :     }
     422                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
     423                 :             :     if (ctx->psa_enabled == 1) {
     424                 :             :         /* While PSA Crypto has an API for multipart
     425                 :             :          * operations, we currently don't make it
     426                 :             :          * accessible through the cipher layer. */
     427                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     428                 :             :     }
     429                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
     430                 :             : 
     431                 :             :     /* avoid buffer overflow in ctx->iv */
     432         [ #  # ]:           0 :     if (iv_len > MBEDTLS_MAX_IV_LENGTH) {
     433                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     434                 :             :     }
     435                 :             : 
     436         [ #  # ]:           0 :     if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN) != 0) {
     437                 :             :         actual_iv_size = iv_len;
     438                 :             :     } else {
     439                 :           0 :         actual_iv_size = mbedtls_cipher_info_get_iv_size(ctx->cipher_info);
     440                 :             : 
     441                 :             :         /* avoid reading past the end of input buffer */
     442         [ #  # ]:           0 :         if (actual_iv_size > iv_len) {
     443                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     444                 :             :         }
     445                 :             :     }
     446                 :             : 
     447                 :             : #if defined(MBEDTLS_CHACHA20_C)
     448                 :             :     if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20) {
     449                 :             :         /* Even though the actual_iv_size is overwritten with a correct value
     450                 :             :          * of 12 from the cipher info, return an error to indicate that
     451                 :             :          * the input iv_len is wrong. */
     452                 :             :         if (iv_len != 12) {
     453                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     454                 :             :         }
     455                 :             : 
     456                 :             :         if (0 != mbedtls_chacha20_starts((mbedtls_chacha20_context *) ctx->cipher_ctx,
     457                 :             :                                          iv,
     458                 :             :                                          0U)) {   /* Initial counter value */
     459                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     460                 :             :         }
     461                 :             :     }
     462                 :             : #if defined(MBEDTLS_CHACHAPOLY_C)
     463                 :             :     if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305 &&
     464                 :             :         iv_len != 12) {
     465                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     466                 :             :     }
     467                 :             : #endif
     468                 :             : #endif
     469                 :             : 
     470                 :             : #if defined(MBEDTLS_GCM_C)
     471                 :             :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
     472                 :             :         return mbedtls_gcm_starts((mbedtls_gcm_context *) ctx->cipher_ctx,
     473                 :             :                                   ctx->operation,
     474                 :             :                                   iv, iv_len);
     475                 :             :     }
     476                 :             : #endif
     477                 :             : 
     478                 :             : #if defined(MBEDTLS_CCM_C)
     479         [ #  # ]:           0 :     if (MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
     480                 :           0 :         int set_lengths_result;
     481                 :           0 :         int ccm_star_mode;
     482                 :             : 
     483                 :           0 :         set_lengths_result = mbedtls_ccm_set_lengths(
     484                 :           0 :             (mbedtls_ccm_context *) ctx->cipher_ctx,
     485                 :             :             0, 0, 0);
     486         [ #  # ]:           0 :         if (set_lengths_result != 0) {
     487                 :             :             return set_lengths_result;
     488                 :             :         }
     489                 :             : 
     490         [ #  # ]:           0 :         if (ctx->operation == MBEDTLS_DECRYPT) {
     491                 :             :             ccm_star_mode = MBEDTLS_CCM_STAR_DECRYPT;
     492         [ #  # ]:           0 :         } else if (ctx->operation == MBEDTLS_ENCRYPT) {
     493                 :             :             ccm_star_mode = MBEDTLS_CCM_STAR_ENCRYPT;
     494                 :             :         } else {
     495                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     496                 :             :         }
     497                 :             : 
     498                 :           0 :         return mbedtls_ccm_starts((mbedtls_ccm_context *) ctx->cipher_ctx,
     499                 :             :                                   ccm_star_mode,
     500                 :             :                                   iv, iv_len);
     501                 :             :     }
     502                 :             : #endif
     503                 :             : 
     504         [ #  # ]:           0 :     if (actual_iv_size != 0) {
     505                 :           0 :         memcpy(ctx->iv, iv, actual_iv_size);
     506                 :           0 :         ctx->iv_size = actual_iv_size;
     507                 :             :     }
     508                 :             : 
     509                 :             :     return 0;
     510                 :             : }
     511                 :             : 
     512                 :           0 : int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx)
     513                 :             : {
     514         [ #  # ]:           0 :     if (ctx->cipher_info == NULL) {
     515                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     516                 :             :     }
     517                 :             : 
     518                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
     519                 :             :     if (ctx->psa_enabled == 1) {
     520                 :             :         /* We don't support resetting PSA-based
     521                 :             :          * cipher contexts, yet. */
     522                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     523                 :             :     }
     524                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
     525                 :             : 
     526                 :           0 :     ctx->unprocessed_len = 0;
     527                 :             : 
     528                 :           0 :     return 0;
     529                 :             : }
     530                 :             : 
     531                 :             : #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
     532                 :             : int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx,
     533                 :             :                              const unsigned char *ad, size_t ad_len)
     534                 :             : {
     535                 :             :     if (ctx->cipher_info == NULL) {
     536                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     537                 :             :     }
     538                 :             : 
     539                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
     540                 :             :     if (ctx->psa_enabled == 1) {
     541                 :             :         /* While PSA Crypto has an API for multipart
     542                 :             :          * operations, we currently don't make it
     543                 :             :          * accessible through the cipher layer. */
     544                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     545                 :             :     }
     546                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
     547                 :             : 
     548                 :             : #if defined(MBEDTLS_GCM_C)
     549                 :             :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
     550                 :             :         return mbedtls_gcm_update_ad((mbedtls_gcm_context *) ctx->cipher_ctx,
     551                 :             :                                      ad, ad_len);
     552                 :             :     }
     553                 :             : #endif
     554                 :             : 
     555                 :             : #if defined(MBEDTLS_CHACHAPOLY_C)
     556                 :             :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
     557                 :             :         int result;
     558                 :             :         mbedtls_chachapoly_mode_t mode;
     559                 :             : 
     560                 :             :         mode = (ctx->operation == MBEDTLS_ENCRYPT)
     561                 :             :                 ? MBEDTLS_CHACHAPOLY_ENCRYPT
     562                 :             :                 : MBEDTLS_CHACHAPOLY_DECRYPT;
     563                 :             : 
     564                 :             :         result = mbedtls_chachapoly_starts((mbedtls_chachapoly_context *) ctx->cipher_ctx,
     565                 :             :                                            ctx->iv,
     566                 :             :                                            mode);
     567                 :             :         if (result != 0) {
     568                 :             :             return result;
     569                 :             :         }
     570                 :             : 
     571                 :             :         return mbedtls_chachapoly_update_aad((mbedtls_chachapoly_context *) ctx->cipher_ctx,
     572                 :             :                                              ad, ad_len);
     573                 :             :     }
     574                 :             : #endif
     575                 :             : 
     576                 :             :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     577                 :             : }
     578                 :             : #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
     579                 :             : 
     580                 :         338 : int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *input,
     581                 :             :                           size_t ilen, unsigned char *output, size_t *olen)
     582                 :             : {
     583                 :         338 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     584                 :         338 :     size_t block_size;
     585                 :             : 
     586         [ -  + ]:         338 :     if (ctx->cipher_info == NULL) {
     587                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     588                 :             :     }
     589                 :             : 
     590                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
     591                 :             :     if (ctx->psa_enabled == 1) {
     592                 :             :         /* While PSA Crypto has an API for multipart
     593                 :             :          * operations, we currently don't make it
     594                 :             :          * accessible through the cipher layer. */
     595                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     596                 :             :     }
     597                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
     598                 :             : 
     599                 :         338 :     *olen = 0;
     600                 :         338 :     block_size = mbedtls_cipher_get_block_size(ctx);
     601         [ +  - ]:         338 :     if (0 == block_size) {
     602                 :             :         return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
     603                 :             :     }
     604                 :             : 
     605         [ +  - ]:         338 :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_ECB) {
     606         [ +  - ]:         338 :         if (ilen != block_size) {
     607                 :             :             return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
     608                 :             :         }
     609                 :             : 
     610                 :         338 :         *olen = ilen;
     611                 :             : 
     612         [ +  - ]:         338 :         if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ecb_func(ctx->cipher_ctx,
     613                 :             :                                                                             ctx->operation, input,
     614                 :             :                                                                             output))) {
     615                 :             :             return ret;
     616                 :             :         }
     617                 :             : 
     618                 :         338 :         return 0;
     619                 :             :     }
     620                 :             : 
     621                 :             : #if defined(MBEDTLS_GCM_C)
     622                 :             :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_GCM) {
     623                 :             :         return mbedtls_gcm_update((mbedtls_gcm_context *) ctx->cipher_ctx,
     624                 :             :                                   input, ilen,
     625                 :             :                                   output, ilen, olen);
     626                 :             :     }
     627                 :             : #endif
     628                 :             : 
     629                 :             : #if defined(MBEDTLS_CCM_C)
     630         [ #  # ]:           0 :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CCM_STAR_NO_TAG) {
     631                 :           0 :         return mbedtls_ccm_update((mbedtls_ccm_context *) ctx->cipher_ctx,
     632                 :             :                                   input, ilen,
     633                 :             :                                   output, ilen, olen);
     634                 :             :     }
     635                 :             : #endif
     636                 :             : 
     637                 :             : #if defined(MBEDTLS_CHACHAPOLY_C)
     638                 :             :     if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305) {
     639                 :             :         *olen = ilen;
     640                 :             :         return mbedtls_chachapoly_update((mbedtls_chachapoly_context *) ctx->cipher_ctx,
     641                 :             :                                          ilen, input, output);
     642                 :             :     }
     643                 :             : #endif
     644                 :             : 
     645         [ #  # ]:           0 :     if (input == output &&
     646   [ #  #  #  # ]:           0 :         (ctx->unprocessed_len != 0 || ilen % block_size)) {
     647                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     648                 :             :     }
     649                 :             : 
     650                 :             : #if defined(MBEDTLS_CIPHER_MODE_CBC)
     651                 :             :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CBC) {
     652                 :             :         size_t copy_len = 0;
     653                 :             : 
     654                 :             :         /*
     655                 :             :          * If there is not enough data for a full block, cache it.
     656                 :             :          */
     657                 :             :         if ((ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
     658                 :             :              ilen <= block_size - ctx->unprocessed_len) ||
     659                 :             :             (ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
     660                 :             :              ilen < block_size - ctx->unprocessed_len) ||
     661                 :             :             (ctx->operation == MBEDTLS_ENCRYPT &&
     662                 :             :              ilen < block_size - ctx->unprocessed_len)) {
     663                 :             :             memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,
     664                 :             :                    ilen);
     665                 :             : 
     666                 :             :             ctx->unprocessed_len += ilen;
     667                 :             :             return 0;
     668                 :             :         }
     669                 :             : 
     670                 :             :         /*
     671                 :             :          * Process cached data first
     672                 :             :          */
     673                 :             :         if (0 != ctx->unprocessed_len) {
     674                 :             :             copy_len = block_size - ctx->unprocessed_len;
     675                 :             : 
     676                 :             :             memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,
     677                 :             :                    copy_len);
     678                 :             : 
     679                 :             :             if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
     680                 :             :                                                                                 ctx->operation,
     681                 :             :                                                                                 block_size, ctx->iv,
     682                 :             :                                                                                 ctx->
     683                 :             :                                                                                 unprocessed_data,
     684                 :             :                                                                                 output))) {
     685                 :             :                 return ret;
     686                 :             :             }
     687                 :             : 
     688                 :             :             *olen += block_size;
     689                 :             :             output += block_size;
     690                 :             :             ctx->unprocessed_len = 0;
     691                 :             : 
     692                 :             :             input += copy_len;
     693                 :             :             ilen -= copy_len;
     694                 :             :         }
     695                 :             : 
     696                 :             :         /*
     697                 :             :          * Cache final, incomplete block
     698                 :             :          */
     699                 :             :         if (0 != ilen) {
     700                 :             :             /* Encryption: only cache partial blocks
     701                 :             :              * Decryption w/ padding: always keep at least one whole block
     702                 :             :              * Decryption w/o padding: only cache partial blocks
     703                 :             :              */
     704                 :             :             copy_len = ilen % block_size;
     705                 :             :             if (copy_len == 0 &&
     706                 :             :                 ctx->operation == MBEDTLS_DECRYPT &&
     707                 :             :                 NULL != ctx->add_padding) {
     708                 :             :                 copy_len = block_size;
     709                 :             :             }
     710                 :             : 
     711                 :             :             memcpy(ctx->unprocessed_data, &(input[ilen - copy_len]),
     712                 :             :                    copy_len);
     713                 :             : 
     714                 :             :             ctx->unprocessed_len += copy_len;
     715                 :             :             ilen -= copy_len;
     716                 :             :         }
     717                 :             : 
     718                 :             :         /*
     719                 :             :          * Process remaining full blocks
     720                 :             :          */
     721                 :             :         if (ilen) {
     722                 :             :             if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
     723                 :             :                                                                                 ctx->operation,
     724                 :             :                                                                                 ilen, ctx->iv,
     725                 :             :                                                                                 input,
     726                 :             :                                                                                 output))) {
     727                 :             :                 return ret;
     728                 :             :             }
     729                 :             : 
     730                 :             :             *olen += ilen;
     731                 :             :         }
     732                 :             : 
     733                 :             :         return 0;
     734                 :             :     }
     735                 :             : #endif /* MBEDTLS_CIPHER_MODE_CBC */
     736                 :             : 
     737                 :             : #if defined(MBEDTLS_CIPHER_MODE_CFB)
     738                 :             :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CFB) {
     739                 :             :         if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cfb_func(ctx->cipher_ctx,
     740                 :             :                                                                             ctx->operation, ilen,
     741                 :             :                                                                             &ctx->unprocessed_len,
     742                 :             :                                                                             ctx->iv,
     743                 :             :                                                                             input, output))) {
     744                 :             :             return ret;
     745                 :             :         }
     746                 :             : 
     747                 :             :         *olen = ilen;
     748                 :             : 
     749                 :             :         return 0;
     750                 :             :     }
     751                 :             : #endif /* MBEDTLS_CIPHER_MODE_CFB */
     752                 :             : 
     753                 :             : #if defined(MBEDTLS_CIPHER_MODE_OFB)
     754                 :             :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_OFB) {
     755                 :             :         if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ofb_func(ctx->cipher_ctx,
     756                 :             :                                                                             ilen,
     757                 :             :                                                                             &ctx->unprocessed_len,
     758                 :             :                                                                             ctx->iv,
     759                 :             :                                                                             input, output))) {
     760                 :             :             return ret;
     761                 :             :         }
     762                 :             : 
     763                 :             :         *olen = ilen;
     764                 :             : 
     765                 :             :         return 0;
     766                 :             :     }
     767                 :             : #endif /* MBEDTLS_CIPHER_MODE_OFB */
     768                 :             : 
     769                 :             : #if defined(MBEDTLS_CIPHER_MODE_CTR)
     770                 :             :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CTR) {
     771                 :             :         if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ctr_func(ctx->cipher_ctx,
     772                 :             :                                                                             ilen,
     773                 :             :                                                                             &ctx->unprocessed_len,
     774                 :             :                                                                             ctx->iv,
     775                 :             :                                                                             ctx->unprocessed_data,
     776                 :             :                                                                             input, output))) {
     777                 :             :             return ret;
     778                 :             :         }
     779                 :             : 
     780                 :             :         *olen = ilen;
     781                 :             : 
     782                 :             :         return 0;
     783                 :             :     }
     784                 :             : #endif /* MBEDTLS_CIPHER_MODE_CTR */
     785                 :             : 
     786                 :             : #if defined(MBEDTLS_CIPHER_MODE_XTS)
     787                 :             :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_XTS) {
     788                 :             :         if (ctx->unprocessed_len > 0) {
     789                 :             :             /* We can only process an entire data unit at a time. */
     790                 :             :             return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     791                 :             :         }
     792                 :             : 
     793                 :             :         ret = mbedtls_cipher_get_base(ctx->cipher_info)->xts_func(ctx->cipher_ctx,
     794                 :             :                                                                   ctx->operation,
     795                 :             :                                                                   ilen,
     796                 :             :                                                                   ctx->iv,
     797                 :             :                                                                   input,
     798                 :             :                                                                   output);
     799                 :             :         if (ret != 0) {
     800                 :             :             return ret;
     801                 :             :         }
     802                 :             : 
     803                 :             :         *olen = ilen;
     804                 :             : 
     805                 :             :         return 0;
     806                 :             :     }
     807                 :             : #endif /* MBEDTLS_CIPHER_MODE_XTS */
     808                 :             : 
     809                 :             : #if defined(MBEDTLS_CIPHER_MODE_STREAM)
     810                 :             :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_STREAM) {
     811                 :             :         if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->stream_func(ctx->cipher_ctx,
     812                 :             :                                                                                ilen, input,
     813                 :             :                                                                                output))) {
     814                 :             :             return ret;
     815                 :             :         }
     816                 :             : 
     817                 :             :         *olen = ilen;
     818                 :             : 
     819                 :             :         return 0;
     820                 :             :     }
     821                 :             : #endif /* MBEDTLS_CIPHER_MODE_STREAM */
     822                 :             : 
     823                 :             :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     824                 :             : }
     825                 :             : 
     826                 :             : #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
     827                 :             : #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
     828                 :             : /*
     829                 :             :  * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
     830                 :             :  */
     831                 :             : static void add_pkcs_padding(unsigned char *output, size_t output_len,
     832                 :             :                              size_t data_len)
     833                 :             : {
     834                 :             :     size_t padding_len = output_len - data_len;
     835                 :             :     unsigned char i;
     836                 :             : 
     837                 :             :     for (i = 0; i < padding_len; i++) {
     838                 :             :         output[data_len + i] = (unsigned char) padding_len;
     839                 :             :     }
     840                 :             : }
     841                 :             : 
     842                 :             : /*
     843                 :             :  * Get the length of the PKCS7 padding.
     844                 :             :  *
     845                 :             :  * Note: input_len must be the block size of the cipher.
     846                 :             :  */
     847                 :             : MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,
     848                 :             :                                                      size_t input_len,
     849                 :             :                                                      size_t *data_len,
     850                 :             :                                                      size_t *invalid_padding)
     851                 :             : {
     852                 :             :     size_t i, pad_idx;
     853                 :             :     unsigned char padding_len;
     854                 :             : 
     855                 :             :     if (NULL == input || NULL == data_len) {
     856                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     857                 :             :     }
     858                 :             : 
     859                 :             :     padding_len = input[input_len - 1];
     860                 :             : 
     861                 :             :     mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
     862                 :             :     bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
     863                 :             : 
     864                 :             :     /* The number of bytes checked must be independent of padding_len,
     865                 :             :      * so pick input_len, which is usually 8 or 16 (one block) */
     866                 :             :     pad_idx = input_len - padding_len;
     867                 :             :     for (i = 0; i < input_len; i++) {
     868                 :             :         mbedtls_ct_condition_t in_padding = mbedtls_ct_uint_ge(i, pad_idx);
     869                 :             :         mbedtls_ct_condition_t different  = mbedtls_ct_uint_ne(input[i], padding_len);
     870                 :             :         bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different));
     871                 :             :     }
     872                 :             : 
     873                 :             :     /* If the padding is invalid, set the output length to 0 */
     874                 :             :     *data_len = mbedtls_ct_if(bad, 0, input_len - padding_len);
     875                 :             : 
     876                 :             :     *invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX);
     877                 :             :     return 0;
     878                 :             : }
     879                 :             : #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
     880                 :             : 
     881                 :             : #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
     882                 :             : /*
     883                 :             :  * One and zeros padding: fill with 80 00 ... 00
     884                 :             :  */
     885                 :             : static void add_one_and_zeros_padding(unsigned char *output,
     886                 :             :                                       size_t output_len, size_t data_len)
     887                 :             : {
     888                 :             :     size_t padding_len = output_len - data_len;
     889                 :             :     unsigned char i = 0;
     890                 :             : 
     891                 :             :     output[data_len] = 0x80;
     892                 :             :     for (i = 1; i < padding_len; i++) {
     893                 :             :         output[data_len + i] = 0x00;
     894                 :             :     }
     895                 :             : }
     896                 :             : 
     897                 :             : static int get_one_and_zeros_padding(unsigned char *input, size_t input_len,
     898                 :             :                                      size_t *data_len, size_t *invalid_padding)
     899                 :             : {
     900                 :             :     if (NULL == input || NULL == data_len) {
     901                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     902                 :             :     }
     903                 :             : 
     904                 :             :     mbedtls_ct_condition_t in_padding = MBEDTLS_CT_TRUE;
     905                 :             :     mbedtls_ct_condition_t bad = MBEDTLS_CT_TRUE;
     906                 :             : 
     907                 :             :     *data_len = 0;
     908                 :             : 
     909                 :             :     for (ptrdiff_t i = (ptrdiff_t) (input_len) - 1; i >= 0; i--) {
     910                 :             :         mbedtls_ct_condition_t is_nonzero = mbedtls_ct_bool(input[i]);
     911                 :             : 
     912                 :             :         mbedtls_ct_condition_t hit_first_nonzero = mbedtls_ct_bool_and(is_nonzero, in_padding);
     913                 :             : 
     914                 :             :         *data_len = mbedtls_ct_size_if(hit_first_nonzero, i, *data_len);
     915                 :             : 
     916                 :             :         bad = mbedtls_ct_bool_if(hit_first_nonzero, mbedtls_ct_uint_ne(input[i], 0x80), bad);
     917                 :             : 
     918                 :             :         in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_bool_not(is_nonzero));
     919                 :             :     }
     920                 :             : 
     921                 :             :     *invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX);
     922                 :             :     return 0;
     923                 :             : }
     924                 :             : #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
     925                 :             : 
     926                 :             : #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
     927                 :             : /*
     928                 :             :  * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
     929                 :             :  */
     930                 :             : static void add_zeros_and_len_padding(unsigned char *output,
     931                 :             :                                       size_t output_len, size_t data_len)
     932                 :             : {
     933                 :             :     size_t padding_len = output_len - data_len;
     934                 :             :     unsigned char i = 0;
     935                 :             : 
     936                 :             :     for (i = 1; i < padding_len; i++) {
     937                 :             :         output[data_len + i - 1] = 0x00;
     938                 :             :     }
     939                 :             :     output[output_len - 1] = (unsigned char) padding_len;
     940                 :             : }
     941                 :             : 
     942                 :             : static int get_zeros_and_len_padding(unsigned char *input, size_t input_len,
     943                 :             :                                      size_t *data_len, size_t *invalid_padding)
     944                 :             : {
     945                 :             :     size_t i, pad_idx;
     946                 :             :     unsigned char padding_len;
     947                 :             :     mbedtls_ct_condition_t bad;
     948                 :             : 
     949                 :             :     if (NULL == input || NULL == data_len) {
     950                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     951                 :             :     }
     952                 :             : 
     953                 :             :     padding_len = input[input_len - 1];
     954                 :             :     *data_len = input_len - padding_len;
     955                 :             : 
     956                 :             :     /* Avoid logical || since it results in a branch */
     957                 :             :     bad = mbedtls_ct_uint_gt(padding_len, input_len);
     958                 :             :     bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
     959                 :             : 
     960                 :             :     /* The number of bytes checked must be independent of padding_len */
     961                 :             :     pad_idx = input_len - padding_len;
     962                 :             :     for (i = 0; i < input_len - 1; i++) {
     963                 :             :         mbedtls_ct_condition_t is_padding = mbedtls_ct_uint_ge(i, pad_idx);
     964                 :             :         mbedtls_ct_condition_t nonzero_pad_byte;
     965                 :             :         nonzero_pad_byte = mbedtls_ct_bool_if_else_0(is_padding, mbedtls_ct_bool(input[i]));
     966                 :             :         bad = mbedtls_ct_bool_or(bad, nonzero_pad_byte);
     967                 :             :     }
     968                 :             : 
     969                 :             :     *invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX);
     970                 :             :     return 0;
     971                 :             : }
     972                 :             : #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
     973                 :             : 
     974                 :             : #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
     975                 :             : /*
     976                 :             :  * Zero padding: fill with 00 ... 00
     977                 :             :  */
     978                 :             : static void add_zeros_padding(unsigned char *output,
     979                 :             :                               size_t output_len, size_t data_len)
     980                 :             : {
     981                 :             :     memset(output + data_len, 0, output_len - data_len);
     982                 :             : }
     983                 :             : 
     984                 :             : static int get_zeros_padding(unsigned char *input, size_t input_len,
     985                 :             :                              size_t *data_len, size_t *invalid_padding)
     986                 :             : {
     987                 :             :     size_t i;
     988                 :             :     mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE, prev_done;
     989                 :             : 
     990                 :             :     if (NULL == input || NULL == data_len) {
     991                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     992                 :             :     }
     993                 :             : 
     994                 :             :     *data_len = 0;
     995                 :             :     for (i = input_len; i > 0; i--) {
     996                 :             :         prev_done = done;
     997                 :             :         done = mbedtls_ct_bool_or(done, mbedtls_ct_uint_ne(input[i-1], 0));
     998                 :             :         *data_len = mbedtls_ct_size_if(mbedtls_ct_bool_ne(done, prev_done), i, *data_len);
     999                 :             :     }
    1000                 :             : 
    1001                 :             :     *invalid_padding = 0;
    1002                 :             :     return 0;
    1003                 :             : }
    1004                 :             : #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
    1005                 :             : 
    1006                 :             : /*
    1007                 :             :  * No padding: don't pad :)
    1008                 :             :  *
    1009                 :             :  * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
    1010                 :             :  * but a trivial get_padding function
    1011                 :             :  */
    1012                 :             : static int get_no_padding(unsigned char *input, size_t input_len,
    1013                 :             :                           size_t *data_len, size_t *invalid_padding)
    1014                 :             : {
    1015                 :             :     if (NULL == input || NULL == data_len) {
    1016                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1017                 :             :     }
    1018                 :             : 
    1019                 :             :     *data_len = input_len;
    1020                 :             :     *invalid_padding = 0;
    1021                 :             :     return 0;
    1022                 :             : }
    1023                 :             : #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
    1024                 :             : 
    1025                 :           0 : int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx,
    1026                 :             :                                  unsigned char *output, size_t *olen,
    1027                 :             :                                  size_t *invalid_padding)
    1028                 :             : {
    1029         [ #  # ]:           0 :     if (ctx->cipher_info == NULL) {
    1030                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1031                 :             :     }
    1032                 :             : 
    1033                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1034                 :             :     if (ctx->psa_enabled == 1) {
    1035                 :             :         /* While PSA Crypto has an API for multipart
    1036                 :             :          * operations, we currently don't make it
    1037                 :             :          * accessible through the cipher layer. */
    1038                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1039                 :             :     }
    1040                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1041                 :             : 
    1042                 :           0 :     *olen = 0;
    1043                 :           0 :     *invalid_padding = 0;
    1044                 :             : 
    1045                 :             : #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
    1046                 :             :     /* CBC mode requires padding so we make sure a call to
    1047                 :             :      * mbedtls_cipher_set_padding_mode has been done successfully. */
    1048                 :             :     if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1049                 :             :         if (ctx->get_padding == NULL) {
    1050                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1051                 :             :         }
    1052                 :             :     }
    1053                 :             : #endif
    1054                 :             : 
    1055         [ #  # ]:           0 :     if (MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1056         [ #  # ]:           0 :         MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1057         [ #  # ]:           0 :         MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1058         [ #  # ]:           0 :         MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1059         [ #  # ]:           0 :         MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1060         [ #  # ]:           0 :         MBEDTLS_MODE_XTS == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1061                 :             :         MBEDTLS_MODE_STREAM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1062                 :             :         return 0;
    1063                 :             :     }
    1064                 :             : 
    1065         [ #  # ]:           0 :     if ((MBEDTLS_CIPHER_CHACHA20          == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) ||
    1066                 :             :         (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type))) {
    1067                 :             :         return 0;
    1068                 :             :     }
    1069                 :             : 
    1070         [ #  # ]:           0 :     if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1071         [ #  # ]:           0 :         if (ctx->unprocessed_len != 0) {
    1072                 :             :             return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
    1073                 :             :         }
    1074                 :             : 
    1075                 :           0 :         return 0;
    1076                 :             :     }
    1077                 :             : 
    1078                 :             : #if defined(MBEDTLS_CIPHER_MODE_CBC)
    1079                 :             :     if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1080                 :             :         int ret = 0;
    1081                 :             : 
    1082                 :             :         if (MBEDTLS_ENCRYPT == ctx->operation) {
    1083                 :             :             /* check for 'no padding' mode */
    1084                 :             :             if (NULL == ctx->add_padding) {
    1085                 :             :                 if (0 != ctx->unprocessed_len) {
    1086                 :             :                     return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
    1087                 :             :                 }
    1088                 :             : 
    1089                 :             :                 return 0;
    1090                 :             :             }
    1091                 :             : 
    1092                 :             :             ctx->add_padding(ctx->unprocessed_data, mbedtls_cipher_get_iv_size(ctx),
    1093                 :             :                              ctx->unprocessed_len);
    1094                 :             :         } else if (mbedtls_cipher_get_block_size(ctx) != ctx->unprocessed_len) {
    1095                 :             :             /*
    1096                 :             :              * For decrypt operations, expect a full block,
    1097                 :             :              * or an empty block if no padding
    1098                 :             :              */
    1099                 :             :             if (NULL == ctx->add_padding && 0 == ctx->unprocessed_len) {
    1100                 :             :                 return 0;
    1101                 :             :             }
    1102                 :             : 
    1103                 :             :             return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
    1104                 :             :         }
    1105                 :             : 
    1106                 :             :         /* cipher block */
    1107                 :             :         if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
    1108                 :             :                                                                             ctx->operation,
    1109                 :             :                                                                             mbedtls_cipher_get_block_size(
    1110                 :             :                                                                                 ctx),
    1111                 :             :                                                                             ctx->iv,
    1112                 :             :                                                                             ctx->unprocessed_data,
    1113                 :             :                                                                             output))) {
    1114                 :             :             return ret;
    1115                 :             :         }
    1116                 :             : 
    1117                 :             :         /* Set output size for decryption */
    1118                 :             :         if (MBEDTLS_DECRYPT == ctx->operation) {
    1119                 :             :             return ctx->get_padding(output, mbedtls_cipher_get_block_size(ctx),
    1120                 :             :                                     olen, invalid_padding);
    1121                 :             :         }
    1122                 :             : 
    1123                 :             :         /* Set output size for encryption */
    1124                 :             :         *olen = mbedtls_cipher_get_block_size(ctx);
    1125                 :             :         return 0;
    1126                 :             :     }
    1127                 :             : #else
    1128                 :             :     ((void) output);
    1129                 :             : #endif /* MBEDTLS_CIPHER_MODE_CBC */
    1130                 :             : 
    1131                 :             :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1132                 :             : }
    1133                 :             : 
    1134                 :           0 : int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
    1135                 :             :                           unsigned char *output, size_t *olen)
    1136                 :             : {
    1137                 :           0 :     size_t invalid_padding = 0;
    1138                 :           0 :     int ret = mbedtls_cipher_finish_padded(ctx, output, olen,
    1139                 :             :                                            &invalid_padding);
    1140         [ #  # ]:           0 :     if (ret == 0) {
    1141                 :           0 :         ret = mbedtls_ct_error_if_else_0(invalid_padding,
    1142                 :             :                                          MBEDTLS_ERR_CIPHER_INVALID_PADDING);
    1143                 :             :     }
    1144                 :           0 :     return ret;
    1145                 :             : }
    1146                 :             : 
    1147                 :             : #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
    1148                 :             : int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
    1149                 :             :                                     mbedtls_cipher_padding_t mode)
    1150                 :             : {
    1151                 :             :     if (NULL == ctx->cipher_info ||
    1152                 :             :         MBEDTLS_MODE_CBC != ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1153                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1154                 :             :     }
    1155                 :             : 
    1156                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1157                 :             :     if (ctx->psa_enabled == 1) {
    1158                 :             :         /* While PSA Crypto knows about CBC padding
    1159                 :             :          * schemes, we currently don't make them
    1160                 :             :          * accessible through the cipher layer. */
    1161                 :             :         if (mode != MBEDTLS_PADDING_NONE) {
    1162                 :             :             return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1163                 :             :         }
    1164                 :             : 
    1165                 :             :         return 0;
    1166                 :             :     }
    1167                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1168                 :             : 
    1169                 :             :     switch (mode) {
    1170                 :             : #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
    1171                 :             :         case MBEDTLS_PADDING_PKCS7:
    1172                 :             :             ctx->add_padding = add_pkcs_padding;
    1173                 :             :             ctx->get_padding = mbedtls_get_pkcs_padding;
    1174                 :             :             break;
    1175                 :             : #endif
    1176                 :             : #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
    1177                 :             :         case MBEDTLS_PADDING_ONE_AND_ZEROS:
    1178                 :             :             ctx->add_padding = add_one_and_zeros_padding;
    1179                 :             :             ctx->get_padding = get_one_and_zeros_padding;
    1180                 :             :             break;
    1181                 :             : #endif
    1182                 :             : #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
    1183                 :             :         case MBEDTLS_PADDING_ZEROS_AND_LEN:
    1184                 :             :             ctx->add_padding = add_zeros_and_len_padding;
    1185                 :             :             ctx->get_padding = get_zeros_and_len_padding;
    1186                 :             :             break;
    1187                 :             : #endif
    1188                 :             : #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
    1189                 :             :         case MBEDTLS_PADDING_ZEROS:
    1190                 :             :             ctx->add_padding = add_zeros_padding;
    1191                 :             :             ctx->get_padding = get_zeros_padding;
    1192                 :             :             break;
    1193                 :             : #endif
    1194                 :             :         case MBEDTLS_PADDING_NONE:
    1195                 :             :             ctx->add_padding = NULL;
    1196                 :             :             ctx->get_padding = get_no_padding;
    1197                 :             :             break;
    1198                 :             : 
    1199                 :             :         default:
    1200                 :             :             return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1201                 :             :     }
    1202                 :             : 
    1203                 :             :     return 0;
    1204                 :             : }
    1205                 :             : #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
    1206                 :             : 
    1207                 :             : #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
    1208                 :             : int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx,
    1209                 :             :                              unsigned char *tag, size_t tag_len)
    1210                 :             : {
    1211                 :             :     if (ctx->cipher_info == NULL) {
    1212                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1213                 :             :     }
    1214                 :             : 
    1215                 :             :     if (MBEDTLS_ENCRYPT != ctx->operation) {
    1216                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1217                 :             :     }
    1218                 :             : 
    1219                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1220                 :             :     if (ctx->psa_enabled == 1) {
    1221                 :             :         /* While PSA Crypto has an API for multipart
    1222                 :             :          * operations, we currently don't make it
    1223                 :             :          * accessible through the cipher layer. */
    1224                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1225                 :             :     }
    1226                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1227                 :             : 
    1228                 :             : #if defined(MBEDTLS_GCM_C)
    1229                 :             :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1230                 :             :         size_t output_length;
    1231                 :             :         /* The code here doesn't yet support alternative implementations
    1232                 :             :          * that can delay up to a block of output. */
    1233                 :             :         return mbedtls_gcm_finish((mbedtls_gcm_context *) ctx->cipher_ctx,
    1234                 :             :                                   NULL, 0, &output_length,
    1235                 :             :                                   tag, tag_len);
    1236                 :             :     }
    1237                 :             : #endif
    1238                 :             : 
    1239                 :             : #if defined(MBEDTLS_CHACHAPOLY_C)
    1240                 :             :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1241                 :             :         /* Don't allow truncated MAC for Poly1305 */
    1242                 :             :         if (tag_len != 16U) {
    1243                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1244                 :             :         }
    1245                 :             : 
    1246                 :             :         return mbedtls_chachapoly_finish(
    1247                 :             :             (mbedtls_chachapoly_context *) ctx->cipher_ctx, tag);
    1248                 :             :     }
    1249                 :             : #endif
    1250                 :             : 
    1251                 :             :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1252                 :             : }
    1253                 :             : 
    1254                 :             : int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx,
    1255                 :             :                              const unsigned char *tag, size_t tag_len)
    1256                 :             : {
    1257                 :             :     unsigned char check_tag[16];
    1258                 :             :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1259                 :             : 
    1260                 :             :     if (ctx->cipher_info == NULL) {
    1261                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1262                 :             :     }
    1263                 :             : 
    1264                 :             :     if (MBEDTLS_DECRYPT != ctx->operation) {
    1265                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1266                 :             :     }
    1267                 :             : 
    1268                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1269                 :             :     if (ctx->psa_enabled == 1) {
    1270                 :             :         /* While PSA Crypto has an API for multipart
    1271                 :             :          * operations, we currently don't make it
    1272                 :             :          * accessible through the cipher layer. */
    1273                 :             :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1274                 :             :     }
    1275                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1276                 :             : 
    1277                 :             :     /* Status to return on a non-authenticated algorithm. */
    1278                 :             :     ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1279                 :             : 
    1280                 :             : #if defined(MBEDTLS_GCM_C)
    1281                 :             :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1282                 :             :         size_t output_length;
    1283                 :             :         /* The code here doesn't yet support alternative implementations
    1284                 :             :          * that can delay up to a block of output. */
    1285                 :             : 
    1286                 :             :         if (tag_len > sizeof(check_tag)) {
    1287                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1288                 :             :         }
    1289                 :             : 
    1290                 :             :         if (0 != (ret = mbedtls_gcm_finish(
    1291                 :             :                       (mbedtls_gcm_context *) ctx->cipher_ctx,
    1292                 :             :                       NULL, 0, &output_length,
    1293                 :             :                       check_tag, tag_len))) {
    1294                 :             :             return ret;
    1295                 :             :         }
    1296                 :             : 
    1297                 :             :         /* Check the tag in "constant-time" */
    1298                 :             :         if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {
    1299                 :             :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1300                 :             :             goto exit;
    1301                 :             :         }
    1302                 :             :     }
    1303                 :             : #endif /* MBEDTLS_GCM_C */
    1304                 :             : 
    1305                 :             : #if defined(MBEDTLS_CHACHAPOLY_C)
    1306                 :             :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1307                 :             :         /* Don't allow truncated MAC for Poly1305 */
    1308                 :             :         if (tag_len != sizeof(check_tag)) {
    1309                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1310                 :             :         }
    1311                 :             : 
    1312                 :             :         ret = mbedtls_chachapoly_finish(
    1313                 :             :             (mbedtls_chachapoly_context *) ctx->cipher_ctx, check_tag);
    1314                 :             :         if (ret != 0) {
    1315                 :             :             return ret;
    1316                 :             :         }
    1317                 :             : 
    1318                 :             :         /* Check the tag in "constant-time" */
    1319                 :             :         if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {
    1320                 :             :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1321                 :             :             goto exit;
    1322                 :             :         }
    1323                 :             :     }
    1324                 :             : #endif /* MBEDTLS_CHACHAPOLY_C */
    1325                 :             : 
    1326                 :             : exit:
    1327                 :             :     mbedtls_platform_zeroize(check_tag, tag_len);
    1328                 :             :     return ret;
    1329                 :             : }
    1330                 :             : #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
    1331                 :             : 
    1332                 :             : /*
    1333                 :             :  * Packet-oriented wrapper for non-AEAD modes
    1334                 :             :  */
    1335                 :           0 : int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx,
    1336                 :             :                          const unsigned char *iv, size_t iv_len,
    1337                 :             :                          const unsigned char *input, size_t ilen,
    1338                 :             :                          unsigned char *output, size_t *olen)
    1339                 :             : {
    1340                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1341                 :           0 :     size_t finish_olen;
    1342                 :             : 
    1343                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1344                 :             :     if (ctx->psa_enabled == 1) {
    1345                 :             :         /* As in the non-PSA case, we don't check that
    1346                 :             :          * a key has been set. If not, the key slot will
    1347                 :             :          * still be in its default state of 0, which is
    1348                 :             :          * guaranteed to be invalid, hence the PSA-call
    1349                 :             :          * below will gracefully fail. */
    1350                 :             :         mbedtls_cipher_context_psa * const cipher_psa =
    1351                 :             :             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
    1352                 :             : 
    1353                 :             :         psa_status_t status;
    1354                 :             :         psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
    1355                 :             :         size_t part_len;
    1356                 :             : 
    1357                 :             :         if (ctx->operation == MBEDTLS_DECRYPT) {
    1358                 :             :             status = psa_cipher_decrypt_setup(&cipher_op,
    1359                 :             :                                               cipher_psa->slot,
    1360                 :             :                                               cipher_psa->alg);
    1361                 :             :         } else if (ctx->operation == MBEDTLS_ENCRYPT) {
    1362                 :             :             status = psa_cipher_encrypt_setup(&cipher_op,
    1363                 :             :                                               cipher_psa->slot,
    1364                 :             :                                               cipher_psa->alg);
    1365                 :             :         } else {
    1366                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1367                 :             :         }
    1368                 :             : 
    1369                 :             :         /* In the following, we can immediately return on an error,
    1370                 :             :          * because the PSA Crypto API guarantees that cipher operations
    1371                 :             :          * are terminated by unsuccessful calls to psa_cipher_update(),
    1372                 :             :          * and by any call to psa_cipher_finish(). */
    1373                 :             :         if (status != PSA_SUCCESS) {
    1374                 :             :             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1375                 :             :         }
    1376                 :             : 
    1377                 :             :         if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) != MBEDTLS_MODE_ECB) {
    1378                 :             :             status = psa_cipher_set_iv(&cipher_op, iv, iv_len);
    1379                 :             :             if (status != PSA_SUCCESS) {
    1380                 :             :                 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1381                 :             :             }
    1382                 :             :         }
    1383                 :             : 
    1384                 :             :         status = psa_cipher_update(&cipher_op,
    1385                 :             :                                    input, ilen,
    1386                 :             :                                    output, ilen, olen);
    1387                 :             :         if (status != PSA_SUCCESS) {
    1388                 :             :             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1389                 :             :         }
    1390                 :             : 
    1391                 :             :         status = psa_cipher_finish(&cipher_op,
    1392                 :             :                                    output + *olen, ilen - *olen,
    1393                 :             :                                    &part_len);
    1394                 :             :         if (status != PSA_SUCCESS) {
    1395                 :             :             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1396                 :             :         }
    1397                 :             : 
    1398                 :             :         *olen += part_len;
    1399                 :             :         return 0;
    1400                 :             :     }
    1401                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1402                 :             : 
    1403         [ #  # ]:           0 :     if ((ret = mbedtls_cipher_set_iv(ctx, iv, iv_len)) != 0) {
    1404                 :             :         return ret;
    1405                 :             :     }
    1406                 :             : 
    1407         [ #  # ]:           0 :     if ((ret = mbedtls_cipher_reset(ctx)) != 0) {
    1408                 :             :         return ret;
    1409                 :             :     }
    1410                 :             : 
    1411         [ #  # ]:           0 :     if ((ret = mbedtls_cipher_update(ctx, input, ilen,
    1412                 :             :                                      output, olen)) != 0) {
    1413                 :             :         return ret;
    1414                 :             :     }
    1415                 :             : 
    1416                 :           0 :     size_t invalid_padding = 0;
    1417         [ #  # ]:           0 :     if ((ret = mbedtls_cipher_finish_padded(ctx, output + *olen,
    1418                 :             :                                             &finish_olen,
    1419                 :             :                                             &invalid_padding)) != 0) {
    1420                 :             :         return ret;
    1421                 :             :     }
    1422                 :           0 :     *olen += finish_olen;
    1423                 :             : 
    1424                 :           0 :     ret = mbedtls_ct_error_if_else_0(invalid_padding,
    1425                 :             :                                      MBEDTLS_ERR_CIPHER_INVALID_PADDING);
    1426                 :           0 :     return ret;
    1427                 :             : }
    1428                 :             : 
    1429                 :             : #if defined(MBEDTLS_CIPHER_MODE_AEAD)
    1430                 :             : /*
    1431                 :             :  * Packet-oriented encryption for AEAD modes: internal function used by
    1432                 :             :  * mbedtls_cipher_auth_encrypt_ext().
    1433                 :             :  */
    1434                 :           0 : static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx,
    1435                 :             :                                        const unsigned char *iv, size_t iv_len,
    1436                 :             :                                        const unsigned char *ad, size_t ad_len,
    1437                 :             :                                        const unsigned char *input, size_t ilen,
    1438                 :             :                                        unsigned char *output, size_t *olen,
    1439                 :             :                                        unsigned char *tag, size_t tag_len)
    1440                 :             : {
    1441                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1442                 :             :     if (ctx->psa_enabled == 1) {
    1443                 :             :         /* As in the non-PSA case, we don't check that
    1444                 :             :          * a key has been set. If not, the key slot will
    1445                 :             :          * still be in its default state of 0, which is
    1446                 :             :          * guaranteed to be invalid, hence the PSA-call
    1447                 :             :          * below will gracefully fail. */
    1448                 :             :         mbedtls_cipher_context_psa * const cipher_psa =
    1449                 :             :             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
    1450                 :             : 
    1451                 :             :         psa_status_t status;
    1452                 :             : 
    1453                 :             :         /* PSA Crypto API always writes the authentication tag
    1454                 :             :          * at the end of the encrypted message. */
    1455                 :             :         if (output == NULL || tag != output + ilen) {
    1456                 :             :             return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1457                 :             :         }
    1458                 :             : 
    1459                 :             :         status = psa_aead_encrypt(cipher_psa->slot,
    1460                 :             :                                   cipher_psa->alg,
    1461                 :             :                                   iv, iv_len,
    1462                 :             :                                   ad, ad_len,
    1463                 :             :                                   input, ilen,
    1464                 :             :                                   output, ilen + tag_len, olen);
    1465                 :             :         if (status != PSA_SUCCESS) {
    1466                 :             :             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1467                 :             :         }
    1468                 :             : 
    1469                 :             :         *olen -= tag_len;
    1470                 :             :         return 0;
    1471                 :             :     }
    1472                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1473                 :             : 
    1474                 :             : #if defined(MBEDTLS_GCM_C)
    1475                 :             :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1476                 :             :         *olen = ilen;
    1477                 :             :         return mbedtls_gcm_crypt_and_tag(ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
    1478                 :             :                                          ilen, iv, iv_len, ad, ad_len,
    1479                 :             :                                          input, output, tag_len, tag);
    1480                 :             :     }
    1481                 :             : #endif /* MBEDTLS_GCM_C */
    1482                 :             : #if defined(MBEDTLS_CCM_C)
    1483         [ #  # ]:           0 :     if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1484                 :           0 :         *olen = ilen;
    1485                 :           0 :         return mbedtls_ccm_encrypt_and_tag(ctx->cipher_ctx, ilen,
    1486                 :             :                                            iv, iv_len, ad, ad_len, input, output,
    1487                 :             :                                            tag, tag_len);
    1488                 :             :     }
    1489                 :             : #endif /* MBEDTLS_CCM_C */
    1490                 :             : #if defined(MBEDTLS_CHACHAPOLY_C)
    1491                 :             :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1492                 :             :         /* ChachaPoly has fixed length nonce and MAC (tag) */
    1493                 :             :         if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
    1494                 :             :             (tag_len != 16U)) {
    1495                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1496                 :             :         }
    1497                 :             : 
    1498                 :             :         *olen = ilen;
    1499                 :             :         return mbedtls_chachapoly_encrypt_and_tag(ctx->cipher_ctx,
    1500                 :             :                                                   ilen, iv, ad, ad_len, input, output, tag);
    1501                 :             :     }
    1502                 :             : #endif /* MBEDTLS_CHACHAPOLY_C */
    1503                 :             : 
    1504                 :             :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1505                 :             : }
    1506                 :             : 
    1507                 :             : /*
    1508                 :             :  * Packet-oriented encryption for AEAD modes: internal function used by
    1509                 :             :  * mbedtls_cipher_auth_encrypt_ext().
    1510                 :             :  */
    1511                 :           0 : static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx,
    1512                 :             :                                        const unsigned char *iv, size_t iv_len,
    1513                 :             :                                        const unsigned char *ad, size_t ad_len,
    1514                 :             :                                        const unsigned char *input, size_t ilen,
    1515                 :             :                                        unsigned char *output, size_t *olen,
    1516                 :             :                                        const unsigned char *tag, size_t tag_len)
    1517                 :             : {
    1518                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1519                 :             :     if (ctx->psa_enabled == 1) {
    1520                 :             :         /* As in the non-PSA case, we don't check that
    1521                 :             :          * a key has been set. If not, the key slot will
    1522                 :             :          * still be in its default state of 0, which is
    1523                 :             :          * guaranteed to be invalid, hence the PSA-call
    1524                 :             :          * below will gracefully fail. */
    1525                 :             :         mbedtls_cipher_context_psa * const cipher_psa =
    1526                 :             :             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
    1527                 :             : 
    1528                 :             :         psa_status_t status;
    1529                 :             : 
    1530                 :             :         /* PSA Crypto API always writes the authentication tag
    1531                 :             :          * at the end of the encrypted message. */
    1532                 :             :         if (input == NULL || tag != input + ilen) {
    1533                 :             :             return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1534                 :             :         }
    1535                 :             : 
    1536                 :             :         status = psa_aead_decrypt(cipher_psa->slot,
    1537                 :             :                                   cipher_psa->alg,
    1538                 :             :                                   iv, iv_len,
    1539                 :             :                                   ad, ad_len,
    1540                 :             :                                   input, ilen + tag_len,
    1541                 :             :                                   output, ilen, olen);
    1542                 :             :         if (status == PSA_ERROR_INVALID_SIGNATURE) {
    1543                 :             :             return MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1544                 :             :         } else if (status != PSA_SUCCESS) {
    1545                 :             :             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1546                 :             :         }
    1547                 :             : 
    1548                 :             :         return 0;
    1549                 :             :     }
    1550                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1551                 :             : 
    1552                 :             : #if defined(MBEDTLS_GCM_C)
    1553                 :             :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1554                 :             :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1555                 :             : 
    1556                 :             :         *olen = ilen;
    1557                 :             :         ret = mbedtls_gcm_auth_decrypt(ctx->cipher_ctx, ilen,
    1558                 :             :                                        iv, iv_len, ad, ad_len,
    1559                 :             :                                        tag, tag_len, input, output);
    1560                 :             : 
    1561                 :             :         if (ret == MBEDTLS_ERR_GCM_AUTH_FAILED) {
    1562                 :             :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1563                 :             :         }
    1564                 :             : 
    1565                 :             :         return ret;
    1566                 :             :     }
    1567                 :             : #endif /* MBEDTLS_GCM_C */
    1568                 :             : #if defined(MBEDTLS_CCM_C)
    1569         [ #  # ]:           0 :     if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1570                 :           0 :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1571                 :             : 
    1572                 :           0 :         *olen = ilen;
    1573                 :           0 :         ret = mbedtls_ccm_auth_decrypt(ctx->cipher_ctx, ilen,
    1574                 :             :                                        iv, iv_len, ad, ad_len,
    1575                 :             :                                        input, output, tag, tag_len);
    1576                 :             : 
    1577         [ #  # ]:           0 :         if (ret == MBEDTLS_ERR_CCM_AUTH_FAILED) {
    1578                 :           0 :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1579                 :             :         }
    1580                 :             : 
    1581                 :           0 :         return ret;
    1582                 :             :     }
    1583                 :             : #endif /* MBEDTLS_CCM_C */
    1584                 :             : #if defined(MBEDTLS_CHACHAPOLY_C)
    1585                 :             :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1586                 :             :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1587                 :             : 
    1588                 :             :         /* ChachaPoly has fixed length nonce and MAC (tag) */
    1589                 :             :         if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
    1590                 :             :             (tag_len != 16U)) {
    1591                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1592                 :             :         }
    1593                 :             : 
    1594                 :             :         *olen = ilen;
    1595                 :             :         ret = mbedtls_chachapoly_auth_decrypt(ctx->cipher_ctx, ilen,
    1596                 :             :                                               iv, ad, ad_len, tag, input, output);
    1597                 :             : 
    1598                 :             :         if (ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) {
    1599                 :             :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1600                 :             :         }
    1601                 :             : 
    1602                 :             :         return ret;
    1603                 :             :     }
    1604                 :             : #endif /* MBEDTLS_CHACHAPOLY_C */
    1605                 :             : 
    1606                 :             :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1607                 :             : }
    1608                 :             : #endif /* MBEDTLS_CIPHER_MODE_AEAD */
    1609                 :             : 
    1610                 :             : #if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
    1611                 :             : /*
    1612                 :             :  * Packet-oriented encryption for AEAD/NIST_KW: public function.
    1613                 :             :  */
    1614                 :           0 : int mbedtls_cipher_auth_encrypt_ext(mbedtls_cipher_context_t *ctx,
    1615                 :             :                                     const unsigned char *iv, size_t iv_len,
    1616                 :             :                                     const unsigned char *ad, size_t ad_len,
    1617                 :             :                                     const unsigned char *input, size_t ilen,
    1618                 :             :                                     unsigned char *output, size_t output_len,
    1619                 :             :                                     size_t *olen, size_t tag_len)
    1620                 :             : {
    1621                 :             : #if defined(MBEDTLS_NIST_KW_C)
    1622                 :             :     if (
    1623                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1624                 :             :         ctx->psa_enabled == 0 &&
    1625                 :             : #endif
    1626                 :             :         (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1627                 :             :          MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {
    1628                 :             :         mbedtls_nist_kw_mode_t mode =
    1629                 :             :             (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?
    1630                 :             :             MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
    1631                 :             : 
    1632                 :             :         /* There is no iv, tag or ad associated with KW and KWP,
    1633                 :             :          * so these length should be 0 as documented. */
    1634                 :             :         if (iv_len != 0 || tag_len != 0 || ad_len != 0) {
    1635                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1636                 :             :         }
    1637                 :             : 
    1638                 :             :         (void) iv;
    1639                 :             :         (void) ad;
    1640                 :             : 
    1641                 :             :         return mbedtls_nist_kw_wrap(ctx->cipher_ctx, mode, input, ilen,
    1642                 :             :                                     output, olen, output_len);
    1643                 :             :     }
    1644                 :             : #endif /* MBEDTLS_NIST_KW_C */
    1645                 :             : 
    1646                 :             : #if defined(MBEDTLS_CIPHER_MODE_AEAD)
    1647                 :             :     /* AEAD case: check length before passing on to shared function */
    1648         [ #  # ]:           0 :     if (output_len < ilen + tag_len) {
    1649                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1650                 :             :     }
    1651                 :             : 
    1652                 :           0 :     int ret = mbedtls_cipher_aead_encrypt(ctx, iv, iv_len, ad, ad_len,
    1653                 :             :                                           input, ilen, output, olen,
    1654                 :             :                                           output + ilen, tag_len);
    1655                 :           0 :     *olen += tag_len;
    1656                 :           0 :     return ret;
    1657                 :             : #else
    1658                 :             :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1659                 :             : #endif /* MBEDTLS_CIPHER_MODE_AEAD */
    1660                 :             : }
    1661                 :             : 
    1662                 :             : /*
    1663                 :             :  * Packet-oriented decryption for AEAD/NIST_KW: public function.
    1664                 :             :  */
    1665                 :           0 : int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx,
    1666                 :             :                                     const unsigned char *iv, size_t iv_len,
    1667                 :             :                                     const unsigned char *ad, size_t ad_len,
    1668                 :             :                                     const unsigned char *input, size_t ilen,
    1669                 :             :                                     unsigned char *output, size_t output_len,
    1670                 :             :                                     size_t *olen, size_t tag_len)
    1671                 :             : {
    1672                 :             : #if defined(MBEDTLS_NIST_KW_C)
    1673                 :             :     if (
    1674                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1675                 :             :         ctx->psa_enabled == 0 &&
    1676                 :             : #endif
    1677                 :             :         (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1678                 :             :          MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {
    1679                 :             :         mbedtls_nist_kw_mode_t mode =
    1680                 :             :             (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?
    1681                 :             :             MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
    1682                 :             : 
    1683                 :             :         /* There is no iv, tag or ad associated with KW and KWP,
    1684                 :             :          * so these length should be 0 as documented. */
    1685                 :             :         if (iv_len != 0 || tag_len != 0 || ad_len != 0) {
    1686                 :             :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1687                 :             :         }
    1688                 :             : 
    1689                 :             :         (void) iv;
    1690                 :             :         (void) ad;
    1691                 :             : 
    1692                 :             :         return mbedtls_nist_kw_unwrap(ctx->cipher_ctx, mode, input, ilen,
    1693                 :             :                                       output, olen, output_len);
    1694                 :             :     }
    1695                 :             : #endif /* MBEDTLS_NIST_KW_C */
    1696                 :             : 
    1697                 :             : #if defined(MBEDTLS_CIPHER_MODE_AEAD)
    1698                 :             :     /* AEAD case: check length before passing on to shared function */
    1699   [ #  #  #  # ]:           0 :     if (ilen < tag_len || output_len < ilen - tag_len) {
    1700                 :             :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1701                 :             :     }
    1702                 :             : 
    1703                 :           0 :     return mbedtls_cipher_aead_decrypt(ctx, iv, iv_len, ad, ad_len,
    1704                 :             :                                        input, ilen - tag_len, output, olen,
    1705                 :             :                                        input + ilen - tag_len, tag_len);
    1706                 :             : #else
    1707                 :             :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1708                 :             : #endif /* MBEDTLS_CIPHER_MODE_AEAD */
    1709                 :             : }
    1710                 :             : #endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
    1711                 :             : 
    1712                 :             : #endif /* MBEDTLS_CIPHER_C */
        

Generated by: LCOV version 2.0-1