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

Generated by: LCOV version 2.0-1