LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - cipher.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 16.0 % 263 42
Test Date: 2025-11-23 08:10:21 Functions: 27.3 % 22 6

            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         9496 : static inline const mbedtls_cipher_base_t *mbedtls_cipher_get_base(
      60              :     const mbedtls_cipher_info_t *info)
      61              : {
      62         9496 :     return mbedtls_cipher_base_lookup_table[info->base_idx];
      63              : }
      64              : 
      65            0 : const int *mbedtls_cipher_list(void)
      66              : {
      67              :     const mbedtls_cipher_definition_t *def;
      68              :     int *type;
      69              : 
      70            0 :     if (!supported_init) {
      71            0 :         def = mbedtls_cipher_definitions;
      72            0 :         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              :     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            0 :     return NULL;
      98              : }
      99              : 
     100            0 : const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
     101              :     const char *cipher_name)
     102              : {
     103              :     const mbedtls_cipher_definition_t *def;
     104              : 
     105            0 :     if (NULL == cipher_name) {
     106            0 :         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            0 :     return NULL;
     116              : }
     117              : 
     118          819 : 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              :     const mbedtls_cipher_definition_t *def;
     124              : 
     125         2453 :     for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
     126         2453 :         if (mbedtls_cipher_get_base(def->info)->cipher == cipher_id &&
     127         2453 :             mbedtls_cipher_info_get_key_bitlen(def->info) == (unsigned) key_bitlen &&
     128          819 :             def->info->mode == mode) {
     129          819 :             return def->info;
     130              :         }
     131              :     }
     132              : 
     133            0 :     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         1638 : void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
     208              : {
     209         1638 :     if (ctx == NULL) {
     210            0 :         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         1638 :     if (ctx->cipher_ctx) {
     240          819 :         mbedtls_cipher_get_base(ctx->cipher_info)->ctx_free_func(ctx->cipher_ctx);
     241              :     }
     242              : 
     243         1638 :     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
     244              : }
     245              : 
     246          819 : int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx,
     247              :                          const mbedtls_cipher_info_t *cipher_info)
     248              : {
     249          819 :     if (cipher_info == NULL) {
     250            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     251              :     }
     252              : 
     253          819 :     memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
     254              : 
     255          819 :     if (mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func != NULL) {
     256          819 :         ctx->cipher_ctx = mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func();
     257          819 :         if (ctx->cipher_ctx == NULL) {
     258            0 :             return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
     259              :         }
     260              :     }
     261              : 
     262          819 :     ctx->cipher_info = cipher_info;
     263              : 
     264          819 :     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          819 : 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          819 :     if (operation != MBEDTLS_ENCRYPT && operation != MBEDTLS_DECRYPT) {
     309            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     310              :     }
     311          819 :     if (ctx->cipher_info == NULL) {
     312            0 :         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          819 :     if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN) == 0 &&
     380          819 :         (int) mbedtls_cipher_info_get_key_bitlen(ctx->cipher_info) != key_bitlen) {
     381            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     382              :     }
     383              : 
     384          819 :     ctx->key_bitlen = key_bitlen;
     385          819 :     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          819 :     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            0 :         MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
     395         1638 :         return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key,
     396          819 :                                                                           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            0 :                                                                           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            0 :     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              :     size_t actual_iv_size;
     418              : 
     419            0 :     if (ctx->cipher_info == NULL) {
     420            0 :         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            0 :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     434              :     }
     435              : 
     436            0 :     if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN) != 0) {
     437            0 :         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            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     444              :         }
     445              :     }
     446              : 
     447              : #if defined(MBEDTLS_CHACHA20_C)
     448            0 :     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            0 :         if (iv_len != 12) {
     453            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     454              :         }
     455              : 
     456            0 :         if (0 != mbedtls_chacha20_starts((mbedtls_chacha20_context *) ctx->cipher_ctx,
     457              :                                          iv,
     458              :                                          0U)) {   /* Initial counter value */
     459            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     460              :         }
     461              :     }
     462              : #if defined(MBEDTLS_CHACHAPOLY_C)
     463            0 :     if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305 &&
     464              :         iv_len != 12) {
     465            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     466              :     }
     467              : #endif
     468              : #endif
     469              : 
     470              : #if defined(MBEDTLS_GCM_C)
     471            0 :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
     472            0 :         return mbedtls_gcm_starts((mbedtls_gcm_context *) ctx->cipher_ctx,
     473            0 :                                   ctx->operation,
     474              :                                   iv, iv_len);
     475              :     }
     476              : #endif
     477              : 
     478              : #if defined(MBEDTLS_CCM_C)
     479              :     if (MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
     480              :         int set_lengths_result;
     481              :         int ccm_star_mode;
     482              : 
     483              :         set_lengths_result = mbedtls_ccm_set_lengths(
     484              :             (mbedtls_ccm_context *) ctx->cipher_ctx,
     485              :             0, 0, 0);
     486              :         if (set_lengths_result != 0) {
     487              :             return set_lengths_result;
     488              :         }
     489              : 
     490              :         if (ctx->operation == MBEDTLS_DECRYPT) {
     491              :             ccm_star_mode = MBEDTLS_CCM_STAR_DECRYPT;
     492              :         } 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              :         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            0 :     return 0;
     510              : }
     511              : 
     512            0 : int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx)
     513              : {
     514            0 :     if (ctx->cipher_info == NULL) {
     515            0 :         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            0 : int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx,
     533              :                              const unsigned char *ad, size_t ad_len)
     534              : {
     535            0 :     if (ctx->cipher_info == NULL) {
     536            0 :         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            0 :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
     550            0 :         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            0 :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
     557              :         int result;
     558              :         mbedtls_chachapoly_mode_t mode;
     559              : 
     560            0 :         mode = (ctx->operation == MBEDTLS_ENCRYPT)
     561              :                 ? MBEDTLS_CHACHAPOLY_ENCRYPT
     562            0 :                 : MBEDTLS_CHACHAPOLY_DECRYPT;
     563              : 
     564            0 :         result = mbedtls_chachapoly_starts((mbedtls_chachapoly_context *) ctx->cipher_ctx,
     565            0 :                                            ctx->iv,
     566              :                                            mode);
     567            0 :         if (result != 0) {
     568            0 :             return result;
     569              :         }
     570              : 
     571            0 :         return mbedtls_chachapoly_update_aad((mbedtls_chachapoly_context *) ctx->cipher_ctx,
     572              :                                              ad, ad_len);
     573              :     }
     574              : #endif
     575              : 
     576            0 :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
     577              : }
     578              : #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
     579              : 
     580         3767 : 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         3767 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     584              :     size_t block_size;
     585              : 
     586         3767 :     if (ctx->cipher_info == NULL) {
     587            0 :         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         3767 :     *olen = 0;
     600         3767 :     block_size = mbedtls_cipher_get_block_size(ctx);
     601         3767 :     if (0 == block_size) {
     602            0 :         return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
     603              :     }
     604              : 
     605         3767 :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_ECB) {
     606         3767 :         if (ilen != block_size) {
     607            0 :             return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
     608              :         }
     609              : 
     610         3767 :         *olen = ilen;
     611              : 
     612         3767 :         if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ecb_func(ctx->cipher_ctx,
     613              :                                                                             ctx->operation, input,
     614              :                                                                             output))) {
     615            0 :             return ret;
     616              :         }
     617              : 
     618         3767 :         return 0;
     619              :     }
     620              : 
     621              : #if defined(MBEDTLS_GCM_C)
     622            0 :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_GCM) {
     623            0 :         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              :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CCM_STAR_NO_TAG) {
     631              :         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            0 :     if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305) {
     639            0 :         *olen = ilen;
     640            0 :         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            0 :         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            0 :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_STREAM) {
     811            0 :         if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->stream_func(ctx->cipher_ctx,
     812              :                                                                                ilen, input,
     813              :                                                                                output))) {
     814            0 :             return ret;
     815              :         }
     816              : 
     817            0 :         *olen = ilen;
     818              : 
     819            0 :         return 0;
     820              :     }
     821              : #endif /* MBEDTLS_CIPHER_MODE_STREAM */
     822              : 
     823            0 :     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            0 :         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            0 :         MBEDTLS_MODE_STREAM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1062            0 :         return 0;
    1063              :     }
    1064              : 
    1065            0 :     if ((MBEDTLS_CIPHER_CHACHA20          == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) ||
    1066            0 :         (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type))) {
    1067            0 :         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            0 :             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            0 :     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            0 : int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx,
    1209              :                              unsigned char *tag, size_t tag_len)
    1210              : {
    1211            0 :     if (ctx->cipher_info == NULL) {
    1212            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1213              :     }
    1214              : 
    1215            0 :     if (MBEDTLS_ENCRYPT != ctx->operation) {
    1216            0 :         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            0 :     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            0 :         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            0 :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1241              :         /* Don't allow truncated MAC for Poly1305 */
    1242            0 :         if (tag_len != 16U) {
    1243            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1244              :         }
    1245              : 
    1246            0 :         return mbedtls_chachapoly_finish(
    1247            0 :             (mbedtls_chachapoly_context *) ctx->cipher_ctx, tag);
    1248              :     }
    1249              : #endif
    1250              : 
    1251            0 :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1252              : }
    1253              : 
    1254            0 : 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            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1259              : 
    1260            0 :     if (ctx->cipher_info == NULL) {
    1261            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1262              :     }
    1263              : 
    1264            0 :     if (MBEDTLS_DECRYPT != ctx->operation) {
    1265            0 :         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            0 :     ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1279              : 
    1280              : #if defined(MBEDTLS_GCM_C)
    1281            0 :     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            0 :         if (tag_len > sizeof(check_tag)) {
    1287            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1288              :         }
    1289              : 
    1290            0 :         if (0 != (ret = mbedtls_gcm_finish(
    1291            0 :                       (mbedtls_gcm_context *) ctx->cipher_ctx,
    1292              :                       NULL, 0, &output_length,
    1293              :                       check_tag, tag_len))) {
    1294            0 :             return ret;
    1295              :         }
    1296              : 
    1297              :         /* Check the tag in "constant-time" */
    1298            0 :         if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {
    1299            0 :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1300            0 :             goto exit;
    1301              :         }
    1302              :     }
    1303              : #endif /* MBEDTLS_GCM_C */
    1304              : 
    1305              : #if defined(MBEDTLS_CHACHAPOLY_C)
    1306            0 :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1307              :         /* Don't allow truncated MAC for Poly1305 */
    1308            0 :         if (tag_len != sizeof(check_tag)) {
    1309            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1310              :         }
    1311              : 
    1312            0 :         ret = mbedtls_chachapoly_finish(
    1313            0 :             (mbedtls_chachapoly_context *) ctx->cipher_ctx, check_tag);
    1314            0 :         if (ret != 0) {
    1315            0 :             return ret;
    1316              :         }
    1317              : 
    1318              :         /* Check the tag in "constant-time" */
    1319            0 :         if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {
    1320            0 :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1321            0 :             goto exit;
    1322              :         }
    1323              :     }
    1324              : #endif /* MBEDTLS_CHACHAPOLY_C */
    1325              : 
    1326            0 : exit:
    1327            0 :     mbedtls_platform_zeroize(check_tag, tag_len);
    1328            0 :     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              :     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            0 :         return ret;
    1405              :     }
    1406              : 
    1407            0 :     if ((ret = mbedtls_cipher_reset(ctx)) != 0) {
    1408            0 :         return ret;
    1409              :     }
    1410              : 
    1411            0 :     if ((ret = mbedtls_cipher_update(ctx, input, ilen,
    1412              :                                      output, olen)) != 0) {
    1413            0 :         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            0 :         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            0 :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1476            0 :         *olen = ilen;
    1477            0 :         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              :     if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1484              :         *olen = ilen;
    1485              :         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            0 :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1492              :         /* ChachaPoly has fixed length nonce and MAC (tag) */
    1493            0 :         if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
    1494              :             (tag_len != 16U)) {
    1495            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1496              :         }
    1497              : 
    1498            0 :         *olen = ilen;
    1499            0 :         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            0 :     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            0 :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1554            0 :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1555              : 
    1556            0 :         *olen = ilen;
    1557            0 :         ret = mbedtls_gcm_auth_decrypt(ctx->cipher_ctx, ilen,
    1558              :                                        iv, iv_len, ad, ad_len,
    1559              :                                        tag, tag_len, input, output);
    1560              : 
    1561            0 :         if (ret == MBEDTLS_ERR_GCM_AUTH_FAILED) {
    1562            0 :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1563              :         }
    1564              : 
    1565            0 :         return ret;
    1566              :     }
    1567              : #endif /* MBEDTLS_GCM_C */
    1568              : #if defined(MBEDTLS_CCM_C)
    1569              :     if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1570              :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1571              : 
    1572              :         *olen = ilen;
    1573              :         ret = mbedtls_ccm_auth_decrypt(ctx->cipher_ctx, ilen,
    1574              :                                        iv, iv_len, ad, ad_len,
    1575              :                                        input, output, tag, tag_len);
    1576              : 
    1577              :         if (ret == MBEDTLS_ERR_CCM_AUTH_FAILED) {
    1578              :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1579              :         }
    1580              : 
    1581              :         return ret;
    1582              :     }
    1583              : #endif /* MBEDTLS_CCM_C */
    1584              : #if defined(MBEDTLS_CHACHAPOLY_C)
    1585            0 :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1586            0 :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1587              : 
    1588              :         /* ChachaPoly has fixed length nonce and MAC (tag) */
    1589            0 :         if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
    1590              :             (tag_len != 16U)) {
    1591            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1592              :         }
    1593              : 
    1594            0 :         *olen = ilen;
    1595            0 :         ret = mbedtls_chachapoly_auth_decrypt(ctx->cipher_ctx, ilen,
    1596              :                                               iv, ad, ad_len, tag, input, output);
    1597              : 
    1598            0 :         if (ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) {
    1599            0 :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1600              :         }
    1601              : 
    1602            0 :         return ret;
    1603              :     }
    1604              : #endif /* MBEDTLS_CHACHAPOLY_C */
    1605              : 
    1606            0 :     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            0 :         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            0 :         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            0 :                                        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