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