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.5 % 254 42
Test Date: 2025-10-12 08:10:56 Functions: 28.6 % 21 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         9573 : static inline const mbedtls_cipher_base_t *mbedtls_cipher_get_base(
      60              :     const mbedtls_cipher_info_t *info)
      61              : {
      62         9573 :     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         3844 : 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         3844 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     584              :     size_t block_size;
     585              : 
     586         3844 :     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         3844 :     *olen = 0;
     600         3844 :     block_size = mbedtls_cipher_get_block_size(ctx);
     601         3844 :     if (0 == block_size) {
     602            0 :         return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
     603              :     }
     604              : 
     605         3844 :     if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_ECB) {
     606         3844 :         if (ilen != block_size) {
     607            0 :             return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
     608              :         }
     609              : 
     610         3844 :         *olen = ilen;
     611              : 
     612         3844 :         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         3844 :         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              : {
     851              :     size_t i, pad_idx;
     852              :     unsigned char padding_len;
     853              : 
     854              :     if (NULL == input || NULL == data_len) {
     855              :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     856              :     }
     857              : 
     858              :     padding_len = input[input_len - 1];
     859              : 
     860              :     mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
     861              :     bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
     862              : 
     863              :     /* The number of bytes checked must be independent of padding_len,
     864              :      * so pick input_len, which is usually 8 or 16 (one block) */
     865              :     pad_idx = input_len - padding_len;
     866              :     for (i = 0; i < input_len; i++) {
     867              :         mbedtls_ct_condition_t in_padding = mbedtls_ct_uint_ge(i, pad_idx);
     868              :         mbedtls_ct_condition_t different  = mbedtls_ct_uint_ne(input[i], padding_len);
     869              :         bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different));
     870              :     }
     871              : 
     872              :     /* If the padding is invalid, set the output length to 0 */
     873              :     *data_len = mbedtls_ct_if(bad, 0, input_len - padding_len);
     874              : 
     875              :     return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
     876              : }
     877              : #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
     878              : 
     879              : #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
     880              : /*
     881              :  * One and zeros padding: fill with 80 00 ... 00
     882              :  */
     883              : static void add_one_and_zeros_padding(unsigned char *output,
     884              :                                       size_t output_len, size_t data_len)
     885              : {
     886              :     size_t padding_len = output_len - data_len;
     887              :     unsigned char i = 0;
     888              : 
     889              :     output[data_len] = 0x80;
     890              :     for (i = 1; i < padding_len; i++) {
     891              :         output[data_len + i] = 0x00;
     892              :     }
     893              : }
     894              : 
     895              : static int get_one_and_zeros_padding(unsigned char *input, size_t input_len,
     896              :                                      size_t *data_len)
     897              : {
     898              :     if (NULL == input || NULL == data_len) {
     899              :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     900              :     }
     901              : 
     902              :     mbedtls_ct_condition_t in_padding = MBEDTLS_CT_TRUE;
     903              :     mbedtls_ct_condition_t bad = MBEDTLS_CT_TRUE;
     904              : 
     905              :     *data_len = 0;
     906              : 
     907              :     for (ptrdiff_t i = (ptrdiff_t) (input_len) - 1; i >= 0; i--) {
     908              :         mbedtls_ct_condition_t is_nonzero = mbedtls_ct_bool(input[i]);
     909              : 
     910              :         mbedtls_ct_condition_t hit_first_nonzero = mbedtls_ct_bool_and(is_nonzero, in_padding);
     911              : 
     912              :         *data_len = mbedtls_ct_size_if(hit_first_nonzero, i, *data_len);
     913              : 
     914              :         bad = mbedtls_ct_bool_if(hit_first_nonzero, mbedtls_ct_uint_ne(input[i], 0x80), bad);
     915              : 
     916              :         in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_bool_not(is_nonzero));
     917              :     }
     918              : 
     919              :     return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
     920              : }
     921              : #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
     922              : 
     923              : #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
     924              : /*
     925              :  * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
     926              :  */
     927              : static void add_zeros_and_len_padding(unsigned char *output,
     928              :                                       size_t output_len, size_t data_len)
     929              : {
     930              :     size_t padding_len = output_len - data_len;
     931              :     unsigned char i = 0;
     932              : 
     933              :     for (i = 1; i < padding_len; i++) {
     934              :         output[data_len + i - 1] = 0x00;
     935              :     }
     936              :     output[output_len - 1] = (unsigned char) padding_len;
     937              : }
     938              : 
     939              : static int get_zeros_and_len_padding(unsigned char *input, size_t input_len,
     940              :                                      size_t *data_len)
     941              : {
     942              :     size_t i, pad_idx;
     943              :     unsigned char padding_len;
     944              :     mbedtls_ct_condition_t bad;
     945              : 
     946              :     if (NULL == input || NULL == data_len) {
     947              :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     948              :     }
     949              : 
     950              :     padding_len = input[input_len - 1];
     951              :     *data_len = input_len - padding_len;
     952              : 
     953              :     /* Avoid logical || since it results in a branch */
     954              :     bad = mbedtls_ct_uint_gt(padding_len, input_len);
     955              :     bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
     956              : 
     957              :     /* The number of bytes checked must be independent of padding_len */
     958              :     pad_idx = input_len - padding_len;
     959              :     for (i = 0; i < input_len - 1; i++) {
     960              :         mbedtls_ct_condition_t is_padding = mbedtls_ct_uint_ge(i, pad_idx);
     961              :         mbedtls_ct_condition_t nonzero_pad_byte;
     962              :         nonzero_pad_byte = mbedtls_ct_bool_if_else_0(is_padding, mbedtls_ct_bool(input[i]));
     963              :         bad = mbedtls_ct_bool_or(bad, nonzero_pad_byte);
     964              :     }
     965              : 
     966              :     return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
     967              : }
     968              : #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
     969              : 
     970              : #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
     971              : /*
     972              :  * Zero padding: fill with 00 ... 00
     973              :  */
     974              : static void add_zeros_padding(unsigned char *output,
     975              :                               size_t output_len, size_t data_len)
     976              : {
     977              :     memset(output + data_len, 0, output_len - data_len);
     978              : }
     979              : 
     980              : static int get_zeros_padding(unsigned char *input, size_t input_len,
     981              :                              size_t *data_len)
     982              : {
     983              :     size_t i;
     984              :     mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE, prev_done;
     985              : 
     986              :     if (NULL == input || NULL == data_len) {
     987              :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     988              :     }
     989              : 
     990              :     *data_len = 0;
     991              :     for (i = input_len; i > 0; i--) {
     992              :         prev_done = done;
     993              :         done = mbedtls_ct_bool_or(done, mbedtls_ct_uint_ne(input[i-1], 0));
     994              :         *data_len = mbedtls_ct_size_if(mbedtls_ct_bool_ne(done, prev_done), i, *data_len);
     995              :     }
     996              : 
     997              :     return 0;
     998              : }
     999              : #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
    1000              : 
    1001              : /*
    1002              :  * No padding: don't pad :)
    1003              :  *
    1004              :  * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
    1005              :  * but a trivial get_padding function
    1006              :  */
    1007              : static int get_no_padding(unsigned char *input, size_t input_len,
    1008              :                           size_t *data_len)
    1009              : {
    1010              :     if (NULL == input || NULL == data_len) {
    1011              :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1012              :     }
    1013              : 
    1014              :     *data_len = input_len;
    1015              : 
    1016              :     return 0;
    1017              : }
    1018              : #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
    1019              : 
    1020            0 : int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
    1021              :                           unsigned char *output, size_t *olen)
    1022              : {
    1023            0 :     if (ctx->cipher_info == NULL) {
    1024            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1025              :     }
    1026              : 
    1027              : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1028              :     if (ctx->psa_enabled == 1) {
    1029              :         /* While PSA Crypto has an API for multipart
    1030              :          * operations, we currently don't make it
    1031              :          * accessible through the cipher layer. */
    1032              :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1033              :     }
    1034              : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1035              : 
    1036            0 :     *olen = 0;
    1037              : 
    1038              : #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
    1039              :     /* CBC mode requires padding so we make sure a call to
    1040              :      * mbedtls_cipher_set_padding_mode has been done successfully. */
    1041              :     if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1042              :         if (ctx->get_padding == NULL) {
    1043              :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1044              :         }
    1045              :     }
    1046              : #endif
    1047              : 
    1048            0 :     if (MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1049            0 :         MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1050            0 :         MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1051            0 :         MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1052            0 :         MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1053            0 :         MBEDTLS_MODE_XTS == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1054            0 :         MBEDTLS_MODE_STREAM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1055            0 :         return 0;
    1056              :     }
    1057              : 
    1058            0 :     if ((MBEDTLS_CIPHER_CHACHA20          == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) ||
    1059            0 :         (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type))) {
    1060            0 :         return 0;
    1061              :     }
    1062              : 
    1063            0 :     if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1064            0 :         if (ctx->unprocessed_len != 0) {
    1065            0 :             return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
    1066              :         }
    1067              : 
    1068            0 :         return 0;
    1069              :     }
    1070              : 
    1071              : #if defined(MBEDTLS_CIPHER_MODE_CBC)
    1072              :     if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1073              :         int ret = 0;
    1074              : 
    1075              :         if (MBEDTLS_ENCRYPT == ctx->operation) {
    1076              :             /* check for 'no padding' mode */
    1077              :             if (NULL == ctx->add_padding) {
    1078              :                 if (0 != ctx->unprocessed_len) {
    1079              :                     return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
    1080              :                 }
    1081              : 
    1082              :                 return 0;
    1083              :             }
    1084              : 
    1085              :             ctx->add_padding(ctx->unprocessed_data, mbedtls_cipher_get_iv_size(ctx),
    1086              :                              ctx->unprocessed_len);
    1087              :         } else if (mbedtls_cipher_get_block_size(ctx) != ctx->unprocessed_len) {
    1088              :             /*
    1089              :              * For decrypt operations, expect a full block,
    1090              :              * or an empty block if no padding
    1091              :              */
    1092              :             if (NULL == ctx->add_padding && 0 == ctx->unprocessed_len) {
    1093              :                 return 0;
    1094              :             }
    1095              : 
    1096              :             return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
    1097              :         }
    1098              : 
    1099              :         /* cipher block */
    1100              :         if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
    1101              :                                                                             ctx->operation,
    1102              :                                                                             mbedtls_cipher_get_block_size(
    1103              :                                                                                 ctx),
    1104              :                                                                             ctx->iv,
    1105              :                                                                             ctx->unprocessed_data,
    1106              :                                                                             output))) {
    1107              :             return ret;
    1108              :         }
    1109              : 
    1110              :         /* Set output size for decryption */
    1111              :         if (MBEDTLS_DECRYPT == ctx->operation) {
    1112              :             return ctx->get_padding(output, mbedtls_cipher_get_block_size(ctx),
    1113              :                                     olen);
    1114              :         }
    1115              : 
    1116              :         /* Set output size for encryption */
    1117              :         *olen = mbedtls_cipher_get_block_size(ctx);
    1118              :         return 0;
    1119              :     }
    1120              : #else
    1121              :     ((void) output);
    1122              : #endif /* MBEDTLS_CIPHER_MODE_CBC */
    1123              : 
    1124            0 :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1125              : }
    1126              : 
    1127              : #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
    1128              : int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
    1129              :                                     mbedtls_cipher_padding_t mode)
    1130              : {
    1131              :     if (NULL == ctx->cipher_info ||
    1132              :         MBEDTLS_MODE_CBC != ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1133              :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1134              :     }
    1135              : 
    1136              : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1137              :     if (ctx->psa_enabled == 1) {
    1138              :         /* While PSA Crypto knows about CBC padding
    1139              :          * schemes, we currently don't make them
    1140              :          * accessible through the cipher layer. */
    1141              :         if (mode != MBEDTLS_PADDING_NONE) {
    1142              :             return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1143              :         }
    1144              : 
    1145              :         return 0;
    1146              :     }
    1147              : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1148              : 
    1149              :     switch (mode) {
    1150              : #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
    1151              :         case MBEDTLS_PADDING_PKCS7:
    1152              :             ctx->add_padding = add_pkcs_padding;
    1153              :             ctx->get_padding = mbedtls_get_pkcs_padding;
    1154              :             break;
    1155              : #endif
    1156              : #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
    1157              :         case MBEDTLS_PADDING_ONE_AND_ZEROS:
    1158              :             ctx->add_padding = add_one_and_zeros_padding;
    1159              :             ctx->get_padding = get_one_and_zeros_padding;
    1160              :             break;
    1161              : #endif
    1162              : #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
    1163              :         case MBEDTLS_PADDING_ZEROS_AND_LEN:
    1164              :             ctx->add_padding = add_zeros_and_len_padding;
    1165              :             ctx->get_padding = get_zeros_and_len_padding;
    1166              :             break;
    1167              : #endif
    1168              : #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
    1169              :         case MBEDTLS_PADDING_ZEROS:
    1170              :             ctx->add_padding = add_zeros_padding;
    1171              :             ctx->get_padding = get_zeros_padding;
    1172              :             break;
    1173              : #endif
    1174              :         case MBEDTLS_PADDING_NONE:
    1175              :             ctx->add_padding = NULL;
    1176              :             ctx->get_padding = get_no_padding;
    1177              :             break;
    1178              : 
    1179              :         default:
    1180              :             return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1181              :     }
    1182              : 
    1183              :     return 0;
    1184              : }
    1185              : #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
    1186              : 
    1187              : #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
    1188            0 : int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx,
    1189              :                              unsigned char *tag, size_t tag_len)
    1190              : {
    1191            0 :     if (ctx->cipher_info == NULL) {
    1192            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1193              :     }
    1194              : 
    1195            0 :     if (MBEDTLS_ENCRYPT != ctx->operation) {
    1196            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1197              :     }
    1198              : 
    1199              : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1200              :     if (ctx->psa_enabled == 1) {
    1201              :         /* While PSA Crypto has an API for multipart
    1202              :          * operations, we currently don't make it
    1203              :          * accessible through the cipher layer. */
    1204              :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1205              :     }
    1206              : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1207              : 
    1208              : #if defined(MBEDTLS_GCM_C)
    1209            0 :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1210              :         size_t output_length;
    1211              :         /* The code here doesn't yet support alternative implementations
    1212              :          * that can delay up to a block of output. */
    1213            0 :         return mbedtls_gcm_finish((mbedtls_gcm_context *) ctx->cipher_ctx,
    1214              :                                   NULL, 0, &output_length,
    1215              :                                   tag, tag_len);
    1216              :     }
    1217              : #endif
    1218              : 
    1219              : #if defined(MBEDTLS_CHACHAPOLY_C)
    1220            0 :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1221              :         /* Don't allow truncated MAC for Poly1305 */
    1222            0 :         if (tag_len != 16U) {
    1223            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1224              :         }
    1225              : 
    1226            0 :         return mbedtls_chachapoly_finish(
    1227            0 :             (mbedtls_chachapoly_context *) ctx->cipher_ctx, tag);
    1228              :     }
    1229              : #endif
    1230              : 
    1231            0 :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1232              : }
    1233              : 
    1234            0 : int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx,
    1235              :                              const unsigned char *tag, size_t tag_len)
    1236              : {
    1237              :     unsigned char check_tag[16];
    1238            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1239              : 
    1240            0 :     if (ctx->cipher_info == NULL) {
    1241            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1242              :     }
    1243              : 
    1244            0 :     if (MBEDTLS_DECRYPT != ctx->operation) {
    1245            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1246              :     }
    1247              : 
    1248              : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1249              :     if (ctx->psa_enabled == 1) {
    1250              :         /* While PSA Crypto has an API for multipart
    1251              :          * operations, we currently don't make it
    1252              :          * accessible through the cipher layer. */
    1253              :         return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1254              :     }
    1255              : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1256              : 
    1257              :     /* Status to return on a non-authenticated algorithm. */
    1258            0 :     ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1259              : 
    1260              : #if defined(MBEDTLS_GCM_C)
    1261            0 :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1262              :         size_t output_length;
    1263              :         /* The code here doesn't yet support alternative implementations
    1264              :          * that can delay up to a block of output. */
    1265              : 
    1266            0 :         if (tag_len > sizeof(check_tag)) {
    1267            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1268              :         }
    1269              : 
    1270            0 :         if (0 != (ret = mbedtls_gcm_finish(
    1271            0 :                       (mbedtls_gcm_context *) ctx->cipher_ctx,
    1272              :                       NULL, 0, &output_length,
    1273              :                       check_tag, tag_len))) {
    1274            0 :             return ret;
    1275              :         }
    1276              : 
    1277              :         /* Check the tag in "constant-time" */
    1278            0 :         if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {
    1279            0 :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1280            0 :             goto exit;
    1281              :         }
    1282              :     }
    1283              : #endif /* MBEDTLS_GCM_C */
    1284              : 
    1285              : #if defined(MBEDTLS_CHACHAPOLY_C)
    1286            0 :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1287              :         /* Don't allow truncated MAC for Poly1305 */
    1288            0 :         if (tag_len != sizeof(check_tag)) {
    1289            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1290              :         }
    1291              : 
    1292            0 :         ret = mbedtls_chachapoly_finish(
    1293            0 :             (mbedtls_chachapoly_context *) ctx->cipher_ctx, check_tag);
    1294            0 :         if (ret != 0) {
    1295            0 :             return ret;
    1296              :         }
    1297              : 
    1298              :         /* Check the tag in "constant-time" */
    1299            0 :         if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {
    1300            0 :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1301            0 :             goto exit;
    1302              :         }
    1303              :     }
    1304              : #endif /* MBEDTLS_CHACHAPOLY_C */
    1305              : 
    1306            0 : exit:
    1307            0 :     mbedtls_platform_zeroize(check_tag, tag_len);
    1308            0 :     return ret;
    1309              : }
    1310              : #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
    1311              : 
    1312              : /*
    1313              :  * Packet-oriented wrapper for non-AEAD modes
    1314              :  */
    1315            0 : int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx,
    1316              :                          const unsigned char *iv, size_t iv_len,
    1317              :                          const unsigned char *input, size_t ilen,
    1318              :                          unsigned char *output, size_t *olen)
    1319              : {
    1320            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1321              :     size_t finish_olen;
    1322              : 
    1323              : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1324              :     if (ctx->psa_enabled == 1) {
    1325              :         /* As in the non-PSA case, we don't check that
    1326              :          * a key has been set. If not, the key slot will
    1327              :          * still be in its default state of 0, which is
    1328              :          * guaranteed to be invalid, hence the PSA-call
    1329              :          * below will gracefully fail. */
    1330              :         mbedtls_cipher_context_psa * const cipher_psa =
    1331              :             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
    1332              : 
    1333              :         psa_status_t status;
    1334              :         psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
    1335              :         size_t part_len;
    1336              : 
    1337              :         if (ctx->operation == MBEDTLS_DECRYPT) {
    1338              :             status = psa_cipher_decrypt_setup(&cipher_op,
    1339              :                                               cipher_psa->slot,
    1340              :                                               cipher_psa->alg);
    1341              :         } else if (ctx->operation == MBEDTLS_ENCRYPT) {
    1342              :             status = psa_cipher_encrypt_setup(&cipher_op,
    1343              :                                               cipher_psa->slot,
    1344              :                                               cipher_psa->alg);
    1345              :         } else {
    1346              :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1347              :         }
    1348              : 
    1349              :         /* In the following, we can immediately return on an error,
    1350              :          * because the PSA Crypto API guarantees that cipher operations
    1351              :          * are terminated by unsuccessful calls to psa_cipher_update(),
    1352              :          * and by any call to psa_cipher_finish(). */
    1353              :         if (status != PSA_SUCCESS) {
    1354              :             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1355              :         }
    1356              : 
    1357              :         if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) != MBEDTLS_MODE_ECB) {
    1358              :             status = psa_cipher_set_iv(&cipher_op, iv, iv_len);
    1359              :             if (status != PSA_SUCCESS) {
    1360              :                 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1361              :             }
    1362              :         }
    1363              : 
    1364              :         status = psa_cipher_update(&cipher_op,
    1365              :                                    input, ilen,
    1366              :                                    output, ilen, olen);
    1367              :         if (status != PSA_SUCCESS) {
    1368              :             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1369              :         }
    1370              : 
    1371              :         status = psa_cipher_finish(&cipher_op,
    1372              :                                    output + *olen, ilen - *olen,
    1373              :                                    &part_len);
    1374              :         if (status != PSA_SUCCESS) {
    1375              :             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1376              :         }
    1377              : 
    1378              :         *olen += part_len;
    1379              :         return 0;
    1380              :     }
    1381              : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1382              : 
    1383            0 :     if ((ret = mbedtls_cipher_set_iv(ctx, iv, iv_len)) != 0) {
    1384            0 :         return ret;
    1385              :     }
    1386              : 
    1387            0 :     if ((ret = mbedtls_cipher_reset(ctx)) != 0) {
    1388            0 :         return ret;
    1389              :     }
    1390              : 
    1391            0 :     if ((ret = mbedtls_cipher_update(ctx, input, ilen,
    1392              :                                      output, olen)) != 0) {
    1393            0 :         return ret;
    1394              :     }
    1395              : 
    1396            0 :     if ((ret = mbedtls_cipher_finish(ctx, output + *olen,
    1397              :                                      &finish_olen)) != 0) {
    1398            0 :         return ret;
    1399              :     }
    1400              : 
    1401            0 :     *olen += finish_olen;
    1402              : 
    1403            0 :     return 0;
    1404              : }
    1405              : 
    1406              : #if defined(MBEDTLS_CIPHER_MODE_AEAD)
    1407              : /*
    1408              :  * Packet-oriented encryption for AEAD modes: internal function used by
    1409              :  * mbedtls_cipher_auth_encrypt_ext().
    1410              :  */
    1411            0 : static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx,
    1412              :                                        const unsigned char *iv, size_t iv_len,
    1413              :                                        const unsigned char *ad, size_t ad_len,
    1414              :                                        const unsigned char *input, size_t ilen,
    1415              :                                        unsigned char *output, size_t *olen,
    1416              :                                        unsigned char *tag, size_t tag_len)
    1417              : {
    1418              : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1419              :     if (ctx->psa_enabled == 1) {
    1420              :         /* As in the non-PSA case, we don't check that
    1421              :          * a key has been set. If not, the key slot will
    1422              :          * still be in its default state of 0, which is
    1423              :          * guaranteed to be invalid, hence the PSA-call
    1424              :          * below will gracefully fail. */
    1425              :         mbedtls_cipher_context_psa * const cipher_psa =
    1426              :             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
    1427              : 
    1428              :         psa_status_t status;
    1429              : 
    1430              :         /* PSA Crypto API always writes the authentication tag
    1431              :          * at the end of the encrypted message. */
    1432              :         if (output == NULL || tag != output + ilen) {
    1433              :             return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1434              :         }
    1435              : 
    1436              :         status = psa_aead_encrypt(cipher_psa->slot,
    1437              :                                   cipher_psa->alg,
    1438              :                                   iv, iv_len,
    1439              :                                   ad, ad_len,
    1440              :                                   input, ilen,
    1441              :                                   output, ilen + tag_len, olen);
    1442              :         if (status != PSA_SUCCESS) {
    1443              :             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1444              :         }
    1445              : 
    1446              :         *olen -= tag_len;
    1447              :         return 0;
    1448              :     }
    1449              : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1450              : 
    1451              : #if defined(MBEDTLS_GCM_C)
    1452            0 :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1453            0 :         *olen = ilen;
    1454            0 :         return mbedtls_gcm_crypt_and_tag(ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
    1455              :                                          ilen, iv, iv_len, ad, ad_len,
    1456              :                                          input, output, tag_len, tag);
    1457              :     }
    1458              : #endif /* MBEDTLS_GCM_C */
    1459              : #if defined(MBEDTLS_CCM_C)
    1460              :     if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1461              :         *olen = ilen;
    1462              :         return mbedtls_ccm_encrypt_and_tag(ctx->cipher_ctx, ilen,
    1463              :                                            iv, iv_len, ad, ad_len, input, output,
    1464              :                                            tag, tag_len);
    1465              :     }
    1466              : #endif /* MBEDTLS_CCM_C */
    1467              : #if defined(MBEDTLS_CHACHAPOLY_C)
    1468            0 :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1469              :         /* ChachaPoly has fixed length nonce and MAC (tag) */
    1470            0 :         if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
    1471              :             (tag_len != 16U)) {
    1472            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1473              :         }
    1474              : 
    1475            0 :         *olen = ilen;
    1476            0 :         return mbedtls_chachapoly_encrypt_and_tag(ctx->cipher_ctx,
    1477              :                                                   ilen, iv, ad, ad_len, input, output, tag);
    1478              :     }
    1479              : #endif /* MBEDTLS_CHACHAPOLY_C */
    1480              : 
    1481            0 :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1482              : }
    1483              : 
    1484              : /*
    1485              :  * Packet-oriented encryption for AEAD modes: internal function used by
    1486              :  * mbedtls_cipher_auth_encrypt_ext().
    1487              :  */
    1488            0 : static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx,
    1489              :                                        const unsigned char *iv, size_t iv_len,
    1490              :                                        const unsigned char *ad, size_t ad_len,
    1491              :                                        const unsigned char *input, size_t ilen,
    1492              :                                        unsigned char *output, size_t *olen,
    1493              :                                        const unsigned char *tag, size_t tag_len)
    1494              : {
    1495              : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1496              :     if (ctx->psa_enabled == 1) {
    1497              :         /* As in the non-PSA case, we don't check that
    1498              :          * a key has been set. If not, the key slot will
    1499              :          * still be in its default state of 0, which is
    1500              :          * guaranteed to be invalid, hence the PSA-call
    1501              :          * below will gracefully fail. */
    1502              :         mbedtls_cipher_context_psa * const cipher_psa =
    1503              :             (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
    1504              : 
    1505              :         psa_status_t status;
    1506              : 
    1507              :         /* PSA Crypto API always writes the authentication tag
    1508              :          * at the end of the encrypted message. */
    1509              :         if (input == NULL || tag != input + ilen) {
    1510              :             return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1511              :         }
    1512              : 
    1513              :         status = psa_aead_decrypt(cipher_psa->slot,
    1514              :                                   cipher_psa->alg,
    1515              :                                   iv, iv_len,
    1516              :                                   ad, ad_len,
    1517              :                                   input, ilen + tag_len,
    1518              :                                   output, ilen, olen);
    1519              :         if (status == PSA_ERROR_INVALID_SIGNATURE) {
    1520              :             return MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1521              :         } else if (status != PSA_SUCCESS) {
    1522              :             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    1523              :         }
    1524              : 
    1525              :         return 0;
    1526              :     }
    1527              : #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
    1528              : 
    1529              : #if defined(MBEDTLS_GCM_C)
    1530            0 :     if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1531            0 :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1532              : 
    1533            0 :         *olen = ilen;
    1534            0 :         ret = mbedtls_gcm_auth_decrypt(ctx->cipher_ctx, ilen,
    1535              :                                        iv, iv_len, ad, ad_len,
    1536              :                                        tag, tag_len, input, output);
    1537              : 
    1538            0 :         if (ret == MBEDTLS_ERR_GCM_AUTH_FAILED) {
    1539            0 :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1540              :         }
    1541              : 
    1542            0 :         return ret;
    1543              :     }
    1544              : #endif /* MBEDTLS_GCM_C */
    1545              : #if defined(MBEDTLS_CCM_C)
    1546              :     if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
    1547              :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1548              : 
    1549              :         *olen = ilen;
    1550              :         ret = mbedtls_ccm_auth_decrypt(ctx->cipher_ctx, ilen,
    1551              :                                        iv, iv_len, ad, ad_len,
    1552              :                                        input, output, tag, tag_len);
    1553              : 
    1554              :         if (ret == MBEDTLS_ERR_CCM_AUTH_FAILED) {
    1555              :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1556              :         }
    1557              : 
    1558              :         return ret;
    1559              :     }
    1560              : #endif /* MBEDTLS_CCM_C */
    1561              : #if defined(MBEDTLS_CHACHAPOLY_C)
    1562            0 :     if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
    1563            0 :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1564              : 
    1565              :         /* ChachaPoly has fixed length nonce and MAC (tag) */
    1566            0 :         if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
    1567              :             (tag_len != 16U)) {
    1568            0 :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1569              :         }
    1570              : 
    1571            0 :         *olen = ilen;
    1572            0 :         ret = mbedtls_chachapoly_auth_decrypt(ctx->cipher_ctx, ilen,
    1573              :                                               iv, ad, ad_len, tag, input, output);
    1574              : 
    1575            0 :         if (ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) {
    1576            0 :             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
    1577              :         }
    1578              : 
    1579            0 :         return ret;
    1580              :     }
    1581              : #endif /* MBEDTLS_CHACHAPOLY_C */
    1582              : 
    1583            0 :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1584              : }
    1585              : #endif /* MBEDTLS_CIPHER_MODE_AEAD */
    1586              : 
    1587              : #if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
    1588              : /*
    1589              :  * Packet-oriented encryption for AEAD/NIST_KW: public function.
    1590              :  */
    1591            0 : int mbedtls_cipher_auth_encrypt_ext(mbedtls_cipher_context_t *ctx,
    1592              :                                     const unsigned char *iv, size_t iv_len,
    1593              :                                     const unsigned char *ad, size_t ad_len,
    1594              :                                     const unsigned char *input, size_t ilen,
    1595              :                                     unsigned char *output, size_t output_len,
    1596              :                                     size_t *olen, size_t tag_len)
    1597              : {
    1598              : #if defined(MBEDTLS_NIST_KW_C)
    1599              :     if (
    1600              : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1601              :         ctx->psa_enabled == 0 &&
    1602              : #endif
    1603              :         (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1604              :          MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {
    1605              :         mbedtls_nist_kw_mode_t mode =
    1606              :             (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?
    1607              :             MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
    1608              : 
    1609              :         /* There is no iv, tag or ad associated with KW and KWP,
    1610              :          * so these length should be 0 as documented. */
    1611              :         if (iv_len != 0 || tag_len != 0 || ad_len != 0) {
    1612              :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1613              :         }
    1614              : 
    1615              :         (void) iv;
    1616              :         (void) ad;
    1617              : 
    1618              :         return mbedtls_nist_kw_wrap(ctx->cipher_ctx, mode, input, ilen,
    1619              :                                     output, olen, output_len);
    1620              :     }
    1621              : #endif /* MBEDTLS_NIST_KW_C */
    1622              : 
    1623              : #if defined(MBEDTLS_CIPHER_MODE_AEAD)
    1624              :     /* AEAD case: check length before passing on to shared function */
    1625            0 :     if (output_len < ilen + tag_len) {
    1626            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1627              :     }
    1628              : 
    1629            0 :     int ret = mbedtls_cipher_aead_encrypt(ctx, iv, iv_len, ad, ad_len,
    1630              :                                           input, ilen, output, olen,
    1631              :                                           output + ilen, tag_len);
    1632            0 :     *olen += tag_len;
    1633            0 :     return ret;
    1634              : #else
    1635              :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1636              : #endif /* MBEDTLS_CIPHER_MODE_AEAD */
    1637              : }
    1638              : 
    1639              : /*
    1640              :  * Packet-oriented decryption for AEAD/NIST_KW: public function.
    1641              :  */
    1642            0 : int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx,
    1643              :                                     const unsigned char *iv, size_t iv_len,
    1644              :                                     const unsigned char *ad, size_t ad_len,
    1645              :                                     const unsigned char *input, size_t ilen,
    1646              :                                     unsigned char *output, size_t output_len,
    1647              :                                     size_t *olen, size_t tag_len)
    1648              : {
    1649              : #if defined(MBEDTLS_NIST_KW_C)
    1650              :     if (
    1651              : #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
    1652              :         ctx->psa_enabled == 0 &&
    1653              : #endif
    1654              :         (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
    1655              :          MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {
    1656              :         mbedtls_nist_kw_mode_t mode =
    1657              :             (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?
    1658              :             MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
    1659              : 
    1660              :         /* There is no iv, tag or ad associated with KW and KWP,
    1661              :          * so these length should be 0 as documented. */
    1662              :         if (iv_len != 0 || tag_len != 0 || ad_len != 0) {
    1663              :             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1664              :         }
    1665              : 
    1666              :         (void) iv;
    1667              :         (void) ad;
    1668              : 
    1669              :         return mbedtls_nist_kw_unwrap(ctx->cipher_ctx, mode, input, ilen,
    1670              :                                       output, olen, output_len);
    1671              :     }
    1672              : #endif /* MBEDTLS_NIST_KW_C */
    1673              : 
    1674              : #if defined(MBEDTLS_CIPHER_MODE_AEAD)
    1675              :     /* AEAD case: check length before passing on to shared function */
    1676            0 :     if (ilen < tag_len || output_len < ilen - tag_len) {
    1677            0 :         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
    1678              :     }
    1679              : 
    1680            0 :     return mbedtls_cipher_aead_decrypt(ctx, iv, iv_len, ad, ad_len,
    1681              :                                        input, ilen - tag_len, output, olen,
    1682            0 :                                        input + ilen - tag_len, tag_len);
    1683              : #else
    1684              :     return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    1685              : #endif /* MBEDTLS_CIPHER_MODE_AEAD */
    1686              : }
    1687              : #endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
    1688              : 
    1689              : #endif /* MBEDTLS_CIPHER_C */
        

Generated by: LCOV version 2.0-1