Path: blob/master/thirdparty/mbedtls/library/cipher.c
21409 views
/**1* \file cipher.c2*3* \brief Generic cipher wrapper for Mbed TLS4*5* \author Adriaan de Jong <[email protected]>6*7* Copyright The Mbed TLS Contributors8* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later9*/1011#include "common.h"1213#if defined(MBEDTLS_CIPHER_C)1415#include "mbedtls/cipher.h"16#include "cipher_invasive.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"2223#include <stdlib.h>24#include <string.h>2526#if defined(MBEDTLS_CHACHAPOLY_C)27#include "mbedtls/chachapoly.h"28#endif2930#if defined(MBEDTLS_GCM_C)31#include "mbedtls/gcm.h"32#endif3334#if defined(MBEDTLS_CCM_C)35#include "mbedtls/ccm.h"36#endif3738#if defined(MBEDTLS_CHACHA20_C)39#include "mbedtls/chacha20.h"40#endif4142#if defined(MBEDTLS_CMAC_C)43#include "mbedtls/cmac.h"44#endif4546#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)47#include "psa/crypto.h"48#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */4950#if defined(MBEDTLS_NIST_KW_C)51#include "mbedtls/nist_kw.h"52#endif5354#include "mbedtls/platform.h"5556static int supported_init = 0;5758static inline const mbedtls_cipher_base_t *mbedtls_cipher_get_base(59const mbedtls_cipher_info_t *info)60{61return mbedtls_cipher_base_lookup_table[info->base_idx];62}6364const int *mbedtls_cipher_list(void)65{66const mbedtls_cipher_definition_t *def;67int *type;6869if (!supported_init) {70def = mbedtls_cipher_definitions;71type = mbedtls_cipher_supported;7273while (def->type != 0) {74*type++ = (*def++).type;75}7677*type = 0;7879supported_init = 1;80}8182return mbedtls_cipher_supported;83}8485const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(86const mbedtls_cipher_type_t cipher_type)87{88const mbedtls_cipher_definition_t *def;8990for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {91if (def->type == cipher_type) {92return def->info;93}94}9596return NULL;97}9899const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(100const char *cipher_name)101{102const mbedtls_cipher_definition_t *def;103104if (NULL == cipher_name) {105return NULL;106}107108for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {109if (!strcmp(def->info->name, cipher_name)) {110return def->info;111}112}113114return NULL;115}116117const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(118const mbedtls_cipher_id_t cipher_id,119int key_bitlen,120const mbedtls_cipher_mode_t mode)121{122const mbedtls_cipher_definition_t *def;123124for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {125if (mbedtls_cipher_get_base(def->info)->cipher == cipher_id &&126mbedtls_cipher_info_get_key_bitlen(def->info) == (unsigned) key_bitlen &&127def->info->mode == mode) {128return def->info;129}130}131132return NULL;133}134135#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)136static inline psa_key_type_t mbedtls_psa_translate_cipher_type(137mbedtls_cipher_type_t cipher)138{139switch (cipher) {140case MBEDTLS_CIPHER_AES_128_CCM:141case MBEDTLS_CIPHER_AES_192_CCM:142case MBEDTLS_CIPHER_AES_256_CCM:143case MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:144case MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:145case MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:146case MBEDTLS_CIPHER_AES_128_GCM:147case MBEDTLS_CIPHER_AES_192_GCM:148case MBEDTLS_CIPHER_AES_256_GCM:149case MBEDTLS_CIPHER_AES_128_CBC:150case MBEDTLS_CIPHER_AES_192_CBC:151case MBEDTLS_CIPHER_AES_256_CBC:152case MBEDTLS_CIPHER_AES_128_ECB:153case MBEDTLS_CIPHER_AES_192_ECB:154case MBEDTLS_CIPHER_AES_256_ECB:155return PSA_KEY_TYPE_AES;156157/* ARIA not yet supported in PSA. */158/* case MBEDTLS_CIPHER_ARIA_128_CCM:159case MBEDTLS_CIPHER_ARIA_192_CCM:160case MBEDTLS_CIPHER_ARIA_256_CCM:161case MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:162case MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:163case MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:164case MBEDTLS_CIPHER_ARIA_128_GCM:165case MBEDTLS_CIPHER_ARIA_192_GCM:166case MBEDTLS_CIPHER_ARIA_256_GCM:167case MBEDTLS_CIPHER_ARIA_128_CBC:168case MBEDTLS_CIPHER_ARIA_192_CBC:169case MBEDTLS_CIPHER_ARIA_256_CBC:170return( PSA_KEY_TYPE_ARIA ); */171172default:173return 0;174}175}176177static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode(178mbedtls_cipher_mode_t mode, size_t taglen)179{180switch (mode) {181case MBEDTLS_MODE_ECB:182return PSA_ALG_ECB_NO_PADDING;183case MBEDTLS_MODE_GCM:184return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, taglen);185case MBEDTLS_MODE_CCM:186return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen);187case MBEDTLS_MODE_CCM_STAR_NO_TAG:188return PSA_ALG_CCM_STAR_NO_TAG;189case MBEDTLS_MODE_CBC:190if (taglen == 0) {191return PSA_ALG_CBC_NO_PADDING;192} else {193return 0;194}195default:196return 0;197}198}199#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */200201void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx)202{203memset(ctx, 0, sizeof(mbedtls_cipher_context_t));204}205206void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)207{208if (ctx == NULL) {209return;210}211212#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)213if (ctx->psa_enabled == 1) {214if (ctx->cipher_ctx != NULL) {215mbedtls_cipher_context_psa * const cipher_psa =216(mbedtls_cipher_context_psa *) ctx->cipher_ctx;217218if (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}222223mbedtls_zeroize_and_free(cipher_psa, sizeof(*cipher_psa));224}225226mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));227return;228}229#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */230231#if defined(MBEDTLS_CMAC_C)232if (ctx->cmac_ctx) {233mbedtls_zeroize_and_free(ctx->cmac_ctx,234sizeof(mbedtls_cmac_context_t));235}236#endif237238if (ctx->cipher_ctx) {239mbedtls_cipher_get_base(ctx->cipher_info)->ctx_free_func(ctx->cipher_ctx);240}241242mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));243}244245int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx,246const mbedtls_cipher_info_t *cipher_info)247{248if (cipher_info == NULL) {249return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;250}251252memset(ctx, 0, sizeof(mbedtls_cipher_context_t));253254if (mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func != NULL) {255ctx->cipher_ctx = mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func();256if (ctx->cipher_ctx == NULL) {257return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;258}259}260261ctx->cipher_info = cipher_info;262263return 0;264}265266#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)267int mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx,268const mbedtls_cipher_info_t *cipher_info,269size_t taglen)270{271psa_algorithm_t alg;272mbedtls_cipher_context_psa *cipher_psa;273274if (NULL == cipher_info || NULL == ctx) {275return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;276}277278/* Check that the underlying cipher mode and cipher type are279* supported by the underlying PSA Crypto implementation. */280alg = mbedtls_psa_translate_cipher_mode(((mbedtls_cipher_mode_t) cipher_info->mode), taglen);281if (alg == 0) {282return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;283}284if (mbedtls_psa_translate_cipher_type(((mbedtls_cipher_type_t) cipher_info->type)) == 0) {285return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;286}287288memset(ctx, 0, sizeof(mbedtls_cipher_context_t));289290cipher_psa = mbedtls_calloc(1, sizeof(mbedtls_cipher_context_psa));291if (cipher_psa == NULL) {292return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;293}294cipher_psa->alg = alg;295ctx->cipher_ctx = cipher_psa;296ctx->cipher_info = cipher_info;297ctx->psa_enabled = 1;298return 0;299}300#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */301302int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,303const unsigned char *key,304int key_bitlen,305const mbedtls_operation_t operation)306{307if (operation != MBEDTLS_ENCRYPT && operation != MBEDTLS_DECRYPT) {308return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;309}310if (ctx->cipher_info == NULL) {311return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;312}313#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)314if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) &&315MBEDTLS_DECRYPT == operation) {316return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;317}318#endif319320#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)321if (ctx->psa_enabled == 1) {322mbedtls_cipher_context_psa * const cipher_psa =323(mbedtls_cipher_context_psa *) ctx->cipher_ctx;324325size_t const key_bytelen = ((size_t) key_bitlen + 7) / 8;326327psa_status_t status;328psa_key_type_t key_type;329psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;330331/* PSA Crypto API only accepts byte-aligned keys. */332if (key_bitlen % 8 != 0) {333return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;334}335336/* Don't allow keys to be set multiple times. */337if (cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET) {338return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;339}340341key_type = mbedtls_psa_translate_cipher_type(342((mbedtls_cipher_type_t) ctx->cipher_info->type));343if (key_type == 0) {344return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;345}346psa_set_key_type(&attributes, key_type);347348/* Mbed TLS' cipher layer doesn't enforce the mode of operation349* (encrypt vs. decrypt): it is possible to setup a key for encryption350* and use it for AEAD decryption. Until tests relying on this351* are changed, allow any usage in PSA. */352psa_set_key_usage_flags(&attributes,353PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);354psa_set_key_algorithm(&attributes, cipher_psa->alg);355356status = psa_import_key(&attributes, key, key_bytelen,357&cipher_psa->slot);358switch (status) {359case PSA_SUCCESS:360break;361case PSA_ERROR_INSUFFICIENT_MEMORY:362return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;363case PSA_ERROR_NOT_SUPPORTED:364return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;365default:366return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;367}368/* Indicate that we own the key slot and need to369* destroy it in mbedtls_cipher_free(). */370cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;371372ctx->key_bitlen = key_bitlen;373ctx->operation = operation;374return 0;375}376#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */377378if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN) == 0 &&379(int) mbedtls_cipher_info_get_key_bitlen(ctx->cipher_info) != key_bitlen) {380return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;381}382383ctx->key_bitlen = key_bitlen;384ctx->operation = operation;385386#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)387/*388* For OFB, CFB and CTR mode always use the encryption key schedule389*/390if (MBEDTLS_ENCRYPT == operation ||391MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||392MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||393MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {394return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key,395ctx->key_bitlen);396}397398if (MBEDTLS_DECRYPT == operation) {399return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_dec_func(ctx->cipher_ctx, key,400ctx->key_bitlen);401}402#else403if (operation == MBEDTLS_ENCRYPT || operation == MBEDTLS_DECRYPT) {404return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key,405ctx->key_bitlen);406}407#endif408409return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;410}411412int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,413const unsigned char *iv,414size_t iv_len)415{416size_t actual_iv_size;417418if (ctx->cipher_info == NULL) {419return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;420}421#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)422if (ctx->psa_enabled == 1) {423/* While PSA Crypto has an API for multipart424* operations, we currently don't make it425* accessible through the cipher layer. */426return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;427}428#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */429430/* avoid buffer overflow in ctx->iv */431if (iv_len > MBEDTLS_MAX_IV_LENGTH) {432return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;433}434435if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN) != 0) {436actual_iv_size = iv_len;437} else {438actual_iv_size = mbedtls_cipher_info_get_iv_size(ctx->cipher_info);439440/* avoid reading past the end of input buffer */441if (actual_iv_size > iv_len) {442return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;443}444}445446#if defined(MBEDTLS_CHACHA20_C)447if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20) {448/* Even though the actual_iv_size is overwritten with a correct value449* of 12 from the cipher info, return an error to indicate that450* the input iv_len is wrong. */451if (iv_len != 12) {452return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;453}454455if (0 != mbedtls_chacha20_starts((mbedtls_chacha20_context *) ctx->cipher_ctx,456iv,4570U)) { /* Initial counter value */458return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;459}460}461#if defined(MBEDTLS_CHACHAPOLY_C)462if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305 &&463iv_len != 12) {464return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;465}466#endif467#endif468469#if defined(MBEDTLS_GCM_C)470if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {471return mbedtls_gcm_starts((mbedtls_gcm_context *) ctx->cipher_ctx,472ctx->operation,473iv, iv_len);474}475#endif476477#if defined(MBEDTLS_CCM_C)478if (MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {479int set_lengths_result;480int ccm_star_mode;481482set_lengths_result = mbedtls_ccm_set_lengths(483(mbedtls_ccm_context *) ctx->cipher_ctx,4840, 0, 0);485if (set_lengths_result != 0) {486return set_lengths_result;487}488489if (ctx->operation == MBEDTLS_DECRYPT) {490ccm_star_mode = MBEDTLS_CCM_STAR_DECRYPT;491} else if (ctx->operation == MBEDTLS_ENCRYPT) {492ccm_star_mode = MBEDTLS_CCM_STAR_ENCRYPT;493} else {494return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;495}496497return mbedtls_ccm_starts((mbedtls_ccm_context *) ctx->cipher_ctx,498ccm_star_mode,499iv, iv_len);500}501#endif502503if (actual_iv_size != 0) {504memcpy(ctx->iv, iv, actual_iv_size);505ctx->iv_size = actual_iv_size;506}507508return 0;509}510511int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx)512{513if (ctx->cipher_info == NULL) {514return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;515}516517#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)518if (ctx->psa_enabled == 1) {519/* We don't support resetting PSA-based520* cipher contexts, yet. */521return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;522}523#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */524525ctx->unprocessed_len = 0;526527return 0;528}529530#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)531int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx,532const unsigned char *ad, size_t ad_len)533{534if (ctx->cipher_info == NULL) {535return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;536}537538#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)539if (ctx->psa_enabled == 1) {540/* While PSA Crypto has an API for multipart541* operations, we currently don't make it542* accessible through the cipher layer. */543return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;544}545#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */546547#if defined(MBEDTLS_GCM_C)548if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {549return mbedtls_gcm_update_ad((mbedtls_gcm_context *) ctx->cipher_ctx,550ad, ad_len);551}552#endif553554#if defined(MBEDTLS_CHACHAPOLY_C)555if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {556int result;557mbedtls_chachapoly_mode_t mode;558559mode = (ctx->operation == MBEDTLS_ENCRYPT)560? MBEDTLS_CHACHAPOLY_ENCRYPT561: MBEDTLS_CHACHAPOLY_DECRYPT;562563result = mbedtls_chachapoly_starts((mbedtls_chachapoly_context *) ctx->cipher_ctx,564ctx->iv,565mode);566if (result != 0) {567return result;568}569570return mbedtls_chachapoly_update_aad((mbedtls_chachapoly_context *) ctx->cipher_ctx,571ad, ad_len);572}573#endif574575return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;576}577#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */578579int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *input,580size_t ilen, unsigned char *output, size_t *olen)581{582int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;583size_t block_size;584585if (ctx->cipher_info == NULL) {586return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;587}588589#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)590if (ctx->psa_enabled == 1) {591/* While PSA Crypto has an API for multipart592* operations, we currently don't make it593* accessible through the cipher layer. */594return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;595}596#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */597598*olen = 0;599block_size = mbedtls_cipher_get_block_size(ctx);600if (0 == block_size) {601return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;602}603604if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_ECB) {605if (ilen != block_size) {606return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;607}608609*olen = ilen;610611if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ecb_func(ctx->cipher_ctx,612ctx->operation, input,613output))) {614return ret;615}616617return 0;618}619620#if defined(MBEDTLS_GCM_C)621if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_GCM) {622return mbedtls_gcm_update((mbedtls_gcm_context *) ctx->cipher_ctx,623input, ilen,624output, ilen, olen);625}626#endif627628#if defined(MBEDTLS_CCM_C)629if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CCM_STAR_NO_TAG) {630return mbedtls_ccm_update((mbedtls_ccm_context *) ctx->cipher_ctx,631input, ilen,632output, ilen, olen);633}634#endif635636#if defined(MBEDTLS_CHACHAPOLY_C)637if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305) {638*olen = ilen;639return mbedtls_chachapoly_update((mbedtls_chachapoly_context *) ctx->cipher_ctx,640ilen, input, output);641}642#endif643644if (input == output &&645(ctx->unprocessed_len != 0 || ilen % block_size)) {646return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;647}648649#if defined(MBEDTLS_CIPHER_MODE_CBC)650if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CBC) {651size_t copy_len = 0;652653/*654* If there is not enough data for a full block, cache it.655*/656if ((ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&657ilen <= block_size - ctx->unprocessed_len) ||658(ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&659ilen < block_size - ctx->unprocessed_len) ||660(ctx->operation == MBEDTLS_ENCRYPT &&661ilen < block_size - ctx->unprocessed_len)) {662memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,663ilen);664665ctx->unprocessed_len += ilen;666return 0;667}668669/*670* Process cached data first671*/672if (0 != ctx->unprocessed_len) {673copy_len = block_size - ctx->unprocessed_len;674675memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,676copy_len);677678if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,679ctx->operation,680block_size, ctx->iv,681ctx->682unprocessed_data,683output))) {684return ret;685}686687*olen += block_size;688output += block_size;689ctx->unprocessed_len = 0;690691input += copy_len;692ilen -= copy_len;693}694695/*696* Cache final, incomplete block697*/698if (0 != ilen) {699/* Encryption: only cache partial blocks700* Decryption w/ padding: always keep at least one whole block701* Decryption w/o padding: only cache partial blocks702*/703copy_len = ilen % block_size;704if (copy_len == 0 &&705ctx->operation == MBEDTLS_DECRYPT &&706NULL != ctx->add_padding) {707copy_len = block_size;708}709710memcpy(ctx->unprocessed_data, &(input[ilen - copy_len]),711copy_len);712713ctx->unprocessed_len += copy_len;714ilen -= copy_len;715}716717/*718* Process remaining full blocks719*/720if (ilen) {721if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,722ctx->operation,723ilen, ctx->iv,724input,725output))) {726return ret;727}728729*olen += ilen;730}731732return 0;733}734#endif /* MBEDTLS_CIPHER_MODE_CBC */735736#if defined(MBEDTLS_CIPHER_MODE_CFB)737if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CFB) {738if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cfb_func(ctx->cipher_ctx,739ctx->operation, ilen,740&ctx->unprocessed_len,741ctx->iv,742input, output))) {743return ret;744}745746*olen = ilen;747748return 0;749}750#endif /* MBEDTLS_CIPHER_MODE_CFB */751752#if defined(MBEDTLS_CIPHER_MODE_OFB)753if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_OFB) {754if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ofb_func(ctx->cipher_ctx,755ilen,756&ctx->unprocessed_len,757ctx->iv,758input, output))) {759return ret;760}761762*olen = ilen;763764return 0;765}766#endif /* MBEDTLS_CIPHER_MODE_OFB */767768#if defined(MBEDTLS_CIPHER_MODE_CTR)769if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CTR) {770if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ctr_func(ctx->cipher_ctx,771ilen,772&ctx->unprocessed_len,773ctx->iv,774ctx->unprocessed_data,775input, output))) {776return ret;777}778779*olen = ilen;780781return 0;782}783#endif /* MBEDTLS_CIPHER_MODE_CTR */784785#if defined(MBEDTLS_CIPHER_MODE_XTS)786if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_XTS) {787if (ctx->unprocessed_len > 0) {788/* We can only process an entire data unit at a time. */789return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;790}791792ret = mbedtls_cipher_get_base(ctx->cipher_info)->xts_func(ctx->cipher_ctx,793ctx->operation,794ilen,795ctx->iv,796input,797output);798if (ret != 0) {799return ret;800}801802*olen = ilen;803804return 0;805}806#endif /* MBEDTLS_CIPHER_MODE_XTS */807808#if defined(MBEDTLS_CIPHER_MODE_STREAM)809if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_STREAM) {810if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->stream_func(ctx->cipher_ctx,811ilen, input,812output))) {813return ret;814}815816*olen = ilen;817818return 0;819}820#endif /* MBEDTLS_CIPHER_MODE_STREAM */821822return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;823}824825#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_len829*/830static void add_pkcs_padding(unsigned char *output, size_t output_len,831size_t data_len)832{833size_t padding_len = output_len - data_len;834unsigned char i;835836for (i = 0; i < padding_len; i++) {837output[data_len + i] = (unsigned char) padding_len;838}839}840841/*842* Get the length of the PKCS7 padding.843*844* Note: input_len must be the block size of the cipher.845*/846MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,847size_t input_len,848size_t *data_len,849size_t *invalid_padding)850{851size_t i, pad_idx;852unsigned char padding_len;853854if (NULL == input || NULL == data_len) {855return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;856}857858padding_len = input[input_len - 1];859860mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);861bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));862863/* The number of bytes checked must be independent of padding_len,864* so pick input_len, which is usually 8 or 16 (one block) */865pad_idx = input_len - padding_len;866for (i = 0; i < input_len; i++) {867mbedtls_ct_condition_t in_padding = mbedtls_ct_uint_ge(i, pad_idx);868mbedtls_ct_condition_t different = mbedtls_ct_uint_ne(input[i], padding_len);869bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different));870}871872/* If the padding is invalid, set the output length to 0 */873*data_len = mbedtls_ct_if(bad, 0, input_len - padding_len);874875*invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX);876return 0;877}878#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */879880#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)881/*882* One and zeros padding: fill with 80 00 ... 00883*/884static void add_one_and_zeros_padding(unsigned char *output,885size_t output_len, size_t data_len)886{887size_t padding_len = output_len - data_len;888unsigned char i = 0;889890output[data_len] = 0x80;891for (i = 1; i < padding_len; i++) {892output[data_len + i] = 0x00;893}894}895896static int get_one_and_zeros_padding(unsigned char *input, size_t input_len,897size_t *data_len, size_t *invalid_padding)898{899if (NULL == input || NULL == data_len) {900return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;901}902903mbedtls_ct_condition_t in_padding = MBEDTLS_CT_TRUE;904mbedtls_ct_condition_t bad = MBEDTLS_CT_TRUE;905906*data_len = 0;907908for (ptrdiff_t i = (ptrdiff_t) (input_len) - 1; i >= 0; i--) {909mbedtls_ct_condition_t is_nonzero = mbedtls_ct_bool(input[i]);910911mbedtls_ct_condition_t hit_first_nonzero = mbedtls_ct_bool_and(is_nonzero, in_padding);912913*data_len = mbedtls_ct_size_if(hit_first_nonzero, i, *data_len);914915bad = mbedtls_ct_bool_if(hit_first_nonzero, mbedtls_ct_uint_ne(input[i], 0x80), bad);916917in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_bool_not(is_nonzero));918}919920*invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX);921return 0;922}923#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */924925#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)926/*927* Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length928*/929static void add_zeros_and_len_padding(unsigned char *output,930size_t output_len, size_t data_len)931{932size_t padding_len = output_len - data_len;933unsigned char i = 0;934935for (i = 1; i < padding_len; i++) {936output[data_len + i - 1] = 0x00;937}938output[output_len - 1] = (unsigned char) padding_len;939}940941static int get_zeros_and_len_padding(unsigned char *input, size_t input_len,942size_t *data_len, size_t *invalid_padding)943{944size_t i, pad_idx;945unsigned char padding_len;946mbedtls_ct_condition_t bad;947948if (NULL == input || NULL == data_len) {949return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;950}951952padding_len = input[input_len - 1];953*data_len = input_len - padding_len;954955/* Avoid logical || since it results in a branch */956bad = mbedtls_ct_uint_gt(padding_len, input_len);957bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));958959/* The number of bytes checked must be independent of padding_len */960pad_idx = input_len - padding_len;961for (i = 0; i < input_len - 1; i++) {962mbedtls_ct_condition_t is_padding = mbedtls_ct_uint_ge(i, pad_idx);963mbedtls_ct_condition_t nonzero_pad_byte;964nonzero_pad_byte = mbedtls_ct_bool_if_else_0(is_padding, mbedtls_ct_bool(input[i]));965bad = mbedtls_ct_bool_or(bad, nonzero_pad_byte);966}967968*invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX);969return 0;970}971#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */972973#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)974/*975* Zero padding: fill with 00 ... 00976*/977static void add_zeros_padding(unsigned char *output,978size_t output_len, size_t data_len)979{980memset(output + data_len, 0, output_len - data_len);981}982983static int get_zeros_padding(unsigned char *input, size_t input_len,984size_t *data_len, size_t *invalid_padding)985{986size_t i;987mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE, prev_done;988989if (NULL == input || NULL == data_len) {990return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;991}992993*data_len = 0;994for (i = input_len; i > 0; i--) {995prev_done = done;996done = mbedtls_ct_bool_or(done, mbedtls_ct_uint_ne(input[i-1], 0));997*data_len = mbedtls_ct_size_if(mbedtls_ct_bool_ne(done, prev_done), i, *data_len);998}9991000*invalid_padding = 0;1001return 0;1002}1003#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */10041005/*1006* No padding: don't pad :)1007*1008* There is no add_padding function (check for NULL in mbedtls_cipher_finish)1009* but a trivial get_padding function1010*/1011static int get_no_padding(unsigned char *input, size_t input_len,1012size_t *data_len, size_t *invalid_padding)1013{1014if (NULL == input || NULL == data_len) {1015return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1016}10171018*data_len = input_len;1019*invalid_padding = 0;1020return 0;1021}1022#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */10231024int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx,1025unsigned char *output, size_t *olen,1026size_t *invalid_padding)1027{1028if (ctx->cipher_info == NULL) {1029return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1030}10311032#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)1033if (ctx->psa_enabled == 1) {1034/* While PSA Crypto has an API for multipart1035* operations, we currently don't make it1036* accessible through the cipher layer. */1037return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1038}1039#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */10401041*olen = 0;1042*invalid_padding = 0;10431044#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)1045/* CBC mode requires padding so we make sure a call to1046* mbedtls_cipher_set_padding_mode has been done successfully. */1047if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1048if (ctx->get_padding == NULL) {1049return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1050}1051}1052#endif10531054if (MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||1055MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||1056MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||1057MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||1058MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||1059MBEDTLS_MODE_XTS == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||1060MBEDTLS_MODE_STREAM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1061return 0;1062}10631064if ((MBEDTLS_CIPHER_CHACHA20 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) ||1065(MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type))) {1066return 0;1067}10681069if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1070if (ctx->unprocessed_len != 0) {1071return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;1072}10731074return 0;1075}10761077#if defined(MBEDTLS_CIPHER_MODE_CBC)1078if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1079int ret = 0;10801081if (MBEDTLS_ENCRYPT == ctx->operation) {1082/* check for 'no padding' mode */1083if (NULL == ctx->add_padding) {1084if (0 != ctx->unprocessed_len) {1085return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;1086}10871088return 0;1089}10901091ctx->add_padding(ctx->unprocessed_data, mbedtls_cipher_get_iv_size(ctx),1092ctx->unprocessed_len);1093} else if (mbedtls_cipher_get_block_size(ctx) != ctx->unprocessed_len) {1094/*1095* For decrypt operations, expect a full block,1096* or an empty block if no padding1097*/1098if (NULL == ctx->add_padding && 0 == ctx->unprocessed_len) {1099return 0;1100}11011102return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;1103}11041105/* cipher block */1106if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,1107ctx->operation,1108mbedtls_cipher_get_block_size(1109ctx),1110ctx->iv,1111ctx->unprocessed_data,1112output))) {1113return ret;1114}11151116/* Set output size for decryption */1117if (MBEDTLS_DECRYPT == ctx->operation) {1118return ctx->get_padding(output, mbedtls_cipher_get_block_size(ctx),1119olen, invalid_padding);1120}11211122/* Set output size for encryption */1123*olen = mbedtls_cipher_get_block_size(ctx);1124return 0;1125}1126#else1127((void) output);1128#endif /* MBEDTLS_CIPHER_MODE_CBC */11291130return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1131}11321133int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,1134unsigned char *output, size_t *olen)1135{1136size_t invalid_padding = 0;1137int ret = mbedtls_cipher_finish_padded(ctx, output, olen,1138&invalid_padding);1139if (ret == 0) {1140ret = mbedtls_ct_error_if_else_0(invalid_padding,1141MBEDTLS_ERR_CIPHER_INVALID_PADDING);1142}1143return ret;1144}11451146#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)1147int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,1148mbedtls_cipher_padding_t mode)1149{1150if (NULL == ctx->cipher_info ||1151MBEDTLS_MODE_CBC != ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1152return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1153}11541155#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)1156if (ctx->psa_enabled == 1) {1157/* While PSA Crypto knows about CBC padding1158* schemes, we currently don't make them1159* accessible through the cipher layer. */1160if (mode != MBEDTLS_PADDING_NONE) {1161return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1162}11631164return 0;1165}1166#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */11671168switch (mode) {1169#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)1170case MBEDTLS_PADDING_PKCS7:1171ctx->add_padding = add_pkcs_padding;1172ctx->get_padding = mbedtls_get_pkcs_padding;1173break;1174#endif1175#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)1176case MBEDTLS_PADDING_ONE_AND_ZEROS:1177ctx->add_padding = add_one_and_zeros_padding;1178ctx->get_padding = get_one_and_zeros_padding;1179break;1180#endif1181#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)1182case MBEDTLS_PADDING_ZEROS_AND_LEN:1183ctx->add_padding = add_zeros_and_len_padding;1184ctx->get_padding = get_zeros_and_len_padding;1185break;1186#endif1187#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)1188case MBEDTLS_PADDING_ZEROS:1189ctx->add_padding = add_zeros_padding;1190ctx->get_padding = get_zeros_padding;1191break;1192#endif1193case MBEDTLS_PADDING_NONE:1194ctx->add_padding = NULL;1195ctx->get_padding = get_no_padding;1196break;11971198default:1199return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1200}12011202return 0;1203}1204#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */12051206#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)1207int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx,1208unsigned char *tag, size_t tag_len)1209{1210if (ctx->cipher_info == NULL) {1211return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1212}12131214if (MBEDTLS_ENCRYPT != ctx->operation) {1215return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1216}12171218#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)1219if (ctx->psa_enabled == 1) {1220/* While PSA Crypto has an API for multipart1221* operations, we currently don't make it1222* accessible through the cipher layer. */1223return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1224}1225#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */12261227#if defined(MBEDTLS_GCM_C)1228if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1229size_t output_length;1230/* The code here doesn't yet support alternative implementations1231* that can delay up to a block of output. */1232return mbedtls_gcm_finish((mbedtls_gcm_context *) ctx->cipher_ctx,1233NULL, 0, &output_length,1234tag, tag_len);1235}1236#endif12371238#if defined(MBEDTLS_CHACHAPOLY_C)1239if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {1240/* Don't allow truncated MAC for Poly1305 */1241if (tag_len != 16U) {1242return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1243}12441245return mbedtls_chachapoly_finish(1246(mbedtls_chachapoly_context *) ctx->cipher_ctx, tag);1247}1248#endif12491250return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1251}12521253int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx,1254const unsigned char *tag, size_t tag_len)1255{1256unsigned char check_tag[16];1257int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;12581259if (ctx->cipher_info == NULL) {1260return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1261}12621263if (MBEDTLS_DECRYPT != ctx->operation) {1264return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1265}12661267#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)1268if (ctx->psa_enabled == 1) {1269/* While PSA Crypto has an API for multipart1270* operations, we currently don't make it1271* accessible through the cipher layer. */1272return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1273}1274#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */12751276/* Status to return on a non-authenticated algorithm. */1277ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;12781279#if defined(MBEDTLS_GCM_C)1280if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1281size_t output_length;1282/* The code here doesn't yet support alternative implementations1283* that can delay up to a block of output. */12841285if (tag_len > sizeof(check_tag)) {1286return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1287}12881289if (0 != (ret = mbedtls_gcm_finish(1290(mbedtls_gcm_context *) ctx->cipher_ctx,1291NULL, 0, &output_length,1292check_tag, tag_len))) {1293return ret;1294}12951296/* Check the tag in "constant-time" */1297if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {1298ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;1299goto exit;1300}1301}1302#endif /* MBEDTLS_GCM_C */13031304#if defined(MBEDTLS_CHACHAPOLY_C)1305if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {1306/* Don't allow truncated MAC for Poly1305 */1307if (tag_len != sizeof(check_tag)) {1308return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1309}13101311ret = mbedtls_chachapoly_finish(1312(mbedtls_chachapoly_context *) ctx->cipher_ctx, check_tag);1313if (ret != 0) {1314return ret;1315}13161317/* Check the tag in "constant-time" */1318if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) {1319ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;1320goto exit;1321}1322}1323#endif /* MBEDTLS_CHACHAPOLY_C */13241325exit:1326mbedtls_platform_zeroize(check_tag, tag_len);1327return ret;1328}1329#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */13301331/*1332* Packet-oriented wrapper for non-AEAD modes1333*/1334int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx,1335const unsigned char *iv, size_t iv_len,1336const unsigned char *input, size_t ilen,1337unsigned char *output, size_t *olen)1338{1339int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1340size_t finish_olen;13411342#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)1343if (ctx->psa_enabled == 1) {1344/* As in the non-PSA case, we don't check that1345* a key has been set. If not, the key slot will1346* still be in its default state of 0, which is1347* guaranteed to be invalid, hence the PSA-call1348* below will gracefully fail. */1349mbedtls_cipher_context_psa * const cipher_psa =1350(mbedtls_cipher_context_psa *) ctx->cipher_ctx;13511352psa_status_t status;1353psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;1354size_t part_len;13551356if (ctx->operation == MBEDTLS_DECRYPT) {1357status = psa_cipher_decrypt_setup(&cipher_op,1358cipher_psa->slot,1359cipher_psa->alg);1360} else if (ctx->operation == MBEDTLS_ENCRYPT) {1361status = psa_cipher_encrypt_setup(&cipher_op,1362cipher_psa->slot,1363cipher_psa->alg);1364} else {1365return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1366}13671368/* In the following, we can immediately return on an error,1369* because the PSA Crypto API guarantees that cipher operations1370* are terminated by unsuccessful calls to psa_cipher_update(),1371* and by any call to psa_cipher_finish(). */1372if (status != PSA_SUCCESS) {1373return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;1374}13751376if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) != MBEDTLS_MODE_ECB) {1377status = psa_cipher_set_iv(&cipher_op, iv, iv_len);1378if (status != PSA_SUCCESS) {1379return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;1380}1381}13821383status = psa_cipher_update(&cipher_op,1384input, ilen,1385output, ilen, olen);1386if (status != PSA_SUCCESS) {1387return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;1388}13891390status = psa_cipher_finish(&cipher_op,1391output + *olen, ilen - *olen,1392&part_len);1393if (status != PSA_SUCCESS) {1394return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;1395}13961397*olen += part_len;1398return 0;1399}1400#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */14011402if ((ret = mbedtls_cipher_set_iv(ctx, iv, iv_len)) != 0) {1403return ret;1404}14051406if ((ret = mbedtls_cipher_reset(ctx)) != 0) {1407return ret;1408}14091410if ((ret = mbedtls_cipher_update(ctx, input, ilen,1411output, olen)) != 0) {1412return ret;1413}14141415size_t invalid_padding = 0;1416if ((ret = mbedtls_cipher_finish_padded(ctx, output + *olen,1417&finish_olen,1418&invalid_padding)) != 0) {1419return ret;1420}1421*olen += finish_olen;14221423ret = mbedtls_ct_error_if_else_0(invalid_padding,1424MBEDTLS_ERR_CIPHER_INVALID_PADDING);1425return ret;1426}14271428#if defined(MBEDTLS_CIPHER_MODE_AEAD)1429/*1430* Packet-oriented encryption for AEAD modes: internal function used by1431* mbedtls_cipher_auth_encrypt_ext().1432*/1433static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx,1434const unsigned char *iv, size_t iv_len,1435const unsigned char *ad, size_t ad_len,1436const unsigned char *input, size_t ilen,1437unsigned char *output, size_t *olen,1438unsigned char *tag, size_t tag_len)1439{1440#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)1441if (ctx->psa_enabled == 1) {1442/* As in the non-PSA case, we don't check that1443* a key has been set. If not, the key slot will1444* still be in its default state of 0, which is1445* guaranteed to be invalid, hence the PSA-call1446* below will gracefully fail. */1447mbedtls_cipher_context_psa * const cipher_psa =1448(mbedtls_cipher_context_psa *) ctx->cipher_ctx;14491450psa_status_t status;14511452/* PSA Crypto API always writes the authentication tag1453* at the end of the encrypted message. */1454if (output == NULL || tag != output + ilen) {1455return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1456}14571458status = psa_aead_encrypt(cipher_psa->slot,1459cipher_psa->alg,1460iv, iv_len,1461ad, ad_len,1462input, ilen,1463output, ilen + tag_len, olen);1464if (status != PSA_SUCCESS) {1465return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;1466}14671468*olen -= tag_len;1469return 0;1470}1471#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */14721473#if defined(MBEDTLS_GCM_C)1474if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1475*olen = ilen;1476return mbedtls_gcm_crypt_and_tag(ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,1477ilen, iv, iv_len, ad, ad_len,1478input, output, tag_len, tag);1479}1480#endif /* MBEDTLS_GCM_C */1481#if defined(MBEDTLS_CCM_C)1482if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1483*olen = ilen;1484return mbedtls_ccm_encrypt_and_tag(ctx->cipher_ctx, ilen,1485iv, iv_len, ad, ad_len, input, output,1486tag, tag_len);1487}1488#endif /* MBEDTLS_CCM_C */1489#if defined(MBEDTLS_CHACHAPOLY_C)1490if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {1491/* ChachaPoly has fixed length nonce and MAC (tag) */1492if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||1493(tag_len != 16U)) {1494return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1495}14961497*olen = ilen;1498return mbedtls_chachapoly_encrypt_and_tag(ctx->cipher_ctx,1499ilen, iv, ad, ad_len, input, output, tag);1500}1501#endif /* MBEDTLS_CHACHAPOLY_C */15021503return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1504}15051506/*1507* Packet-oriented encryption for AEAD modes: internal function used by1508* mbedtls_cipher_auth_encrypt_ext().1509*/1510static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx,1511const unsigned char *iv, size_t iv_len,1512const unsigned char *ad, size_t ad_len,1513const unsigned char *input, size_t ilen,1514unsigned char *output, size_t *olen,1515const unsigned char *tag, size_t tag_len)1516{1517#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)1518if (ctx->psa_enabled == 1) {1519/* As in the non-PSA case, we don't check that1520* a key has been set. If not, the key slot will1521* still be in its default state of 0, which is1522* guaranteed to be invalid, hence the PSA-call1523* below will gracefully fail. */1524mbedtls_cipher_context_psa * const cipher_psa =1525(mbedtls_cipher_context_psa *) ctx->cipher_ctx;15261527psa_status_t status;15281529/* PSA Crypto API always writes the authentication tag1530* at the end of the encrypted message. */1531if (input == NULL || tag != input + ilen) {1532return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1533}15341535status = psa_aead_decrypt(cipher_psa->slot,1536cipher_psa->alg,1537iv, iv_len,1538ad, ad_len,1539input, ilen + tag_len,1540output, ilen, olen);1541if (status == PSA_ERROR_INVALID_SIGNATURE) {1542return MBEDTLS_ERR_CIPHER_AUTH_FAILED;1543} else if (status != PSA_SUCCESS) {1544return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;1545}15461547return 0;1548}1549#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */15501551#if defined(MBEDTLS_GCM_C)1552if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1553int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;15541555*olen = ilen;1556ret = mbedtls_gcm_auth_decrypt(ctx->cipher_ctx, ilen,1557iv, iv_len, ad, ad_len,1558tag, tag_len, input, output);15591560if (ret == MBEDTLS_ERR_GCM_AUTH_FAILED) {1561ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;1562}15631564return ret;1565}1566#endif /* MBEDTLS_GCM_C */1567#if defined(MBEDTLS_CCM_C)1568if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {1569int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;15701571*olen = ilen;1572ret = mbedtls_ccm_auth_decrypt(ctx->cipher_ctx, ilen,1573iv, iv_len, ad, ad_len,1574input, output, tag, tag_len);15751576if (ret == MBEDTLS_ERR_CCM_AUTH_FAILED) {1577ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;1578}15791580return ret;1581}1582#endif /* MBEDTLS_CCM_C */1583#if defined(MBEDTLS_CHACHAPOLY_C)1584if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {1585int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;15861587/* ChachaPoly has fixed length nonce and MAC (tag) */1588if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||1589(tag_len != 16U)) {1590return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1591}15921593*olen = ilen;1594ret = mbedtls_chachapoly_auth_decrypt(ctx->cipher_ctx, ilen,1595iv, ad, ad_len, tag, input, output);15961597if (ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) {1598ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;1599}16001601return ret;1602}1603#endif /* MBEDTLS_CHACHAPOLY_C */16041605return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1606}1607#endif /* MBEDTLS_CIPHER_MODE_AEAD */16081609#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)1610/*1611* Packet-oriented encryption for AEAD/NIST_KW: public function.1612*/1613int mbedtls_cipher_auth_encrypt_ext(mbedtls_cipher_context_t *ctx,1614const unsigned char *iv, size_t iv_len,1615const unsigned char *ad, size_t ad_len,1616const unsigned char *input, size_t ilen,1617unsigned char *output, size_t output_len,1618size_t *olen, size_t tag_len)1619{1620#if defined(MBEDTLS_NIST_KW_C)1621if (1622#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)1623ctx->psa_enabled == 0 &&1624#endif1625(MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||1626MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {1627mbedtls_nist_kw_mode_t mode =1628(MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?1629MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;16301631/* There is no iv, tag or ad associated with KW and KWP,1632* so these length should be 0 as documented. */1633if (iv_len != 0 || tag_len != 0 || ad_len != 0) {1634return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1635}16361637(void) iv;1638(void) ad;16391640return mbedtls_nist_kw_wrap(ctx->cipher_ctx, mode, input, ilen,1641output, olen, output_len);1642}1643#endif /* MBEDTLS_NIST_KW_C */16441645#if defined(MBEDTLS_CIPHER_MODE_AEAD)1646/* AEAD case: check length before passing on to shared function */1647if (output_len < ilen + tag_len) {1648return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1649}16501651int ret = mbedtls_cipher_aead_encrypt(ctx, iv, iv_len, ad, ad_len,1652input, ilen, output, olen,1653output + ilen, tag_len);1654*olen += tag_len;1655return ret;1656#else1657return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1658#endif /* MBEDTLS_CIPHER_MODE_AEAD */1659}16601661/*1662* Packet-oriented decryption for AEAD/NIST_KW: public function.1663*/1664int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx,1665const unsigned char *iv, size_t iv_len,1666const unsigned char *ad, size_t ad_len,1667const unsigned char *input, size_t ilen,1668unsigned char *output, size_t output_len,1669size_t *olen, size_t tag_len)1670{1671#if defined(MBEDTLS_NIST_KW_C)1672if (1673#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)1674ctx->psa_enabled == 0 &&1675#endif1676(MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||1677MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {1678mbedtls_nist_kw_mode_t mode =1679(MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?1680MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;16811682/* There is no iv, tag or ad associated with KW and KWP,1683* so these length should be 0 as documented. */1684if (iv_len != 0 || tag_len != 0 || ad_len != 0) {1685return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1686}16871688(void) iv;1689(void) ad;16901691return mbedtls_nist_kw_unwrap(ctx->cipher_ctx, mode, input, ilen,1692output, olen, output_len);1693}1694#endif /* MBEDTLS_NIST_KW_C */16951696#if defined(MBEDTLS_CIPHER_MODE_AEAD)1697/* AEAD case: check length before passing on to shared function */1698if (ilen < tag_len || output_len < ilen - tag_len) {1699return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;1700}17011702return mbedtls_cipher_aead_decrypt(ctx, iv, iv_len, ad, ad_len,1703input, ilen - tag_len, output, olen,1704input + ilen - tag_len, tag_len);1705#else1706return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;1707#endif /* MBEDTLS_CIPHER_MODE_AEAD */1708}1709#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */17101711#endif /* MBEDTLS_CIPHER_C */171217131714