1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * PSA cipher driver entry points 3a8e1175bSopenharmony_ci */ 4a8e1175bSopenharmony_ci/* 5a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 6a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 7a8e1175bSopenharmony_ci */ 8a8e1175bSopenharmony_ci 9a8e1175bSopenharmony_ci#include "common.h" 10a8e1175bSopenharmony_ci 11a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C) 12a8e1175bSopenharmony_ci 13a8e1175bSopenharmony_ci#include "psa_crypto_cipher.h" 14a8e1175bSopenharmony_ci#include "psa_crypto_core.h" 15a8e1175bSopenharmony_ci#include "psa_crypto_random_impl.h" 16a8e1175bSopenharmony_ci 17a8e1175bSopenharmony_ci#include "mbedtls/cipher.h" 18a8e1175bSopenharmony_ci#include "mbedtls/error.h" 19a8e1175bSopenharmony_ci 20a8e1175bSopenharmony_ci#include <string.h> 21a8e1175bSopenharmony_ci 22a8e1175bSopenharmony_ci/* mbedtls_cipher_values_from_psa() below only checks if the proper build symbols 23a8e1175bSopenharmony_ci * are enabled, but it does not provide any compatibility check between them 24a8e1175bSopenharmony_ci * (i.e. if the specified key works with the specified algorithm). This helper 25a8e1175bSopenharmony_ci * function is meant to provide this support. 26a8e1175bSopenharmony_ci * mbedtls_cipher_info_from_psa() might be used for the same purpose, but it 27a8e1175bSopenharmony_ci * requires CIPHER_C to be enabled. 28a8e1175bSopenharmony_ci */ 29a8e1175bSopenharmony_cistatic psa_status_t mbedtls_cipher_validate_values( 30a8e1175bSopenharmony_ci psa_algorithm_t alg, 31a8e1175bSopenharmony_ci psa_key_type_t key_type) 32a8e1175bSopenharmony_ci{ 33a8e1175bSopenharmony_ci /* Reduce code size - hinting to the compiler about what it can assume allows the compiler to 34a8e1175bSopenharmony_ci eliminate bits of the logic below. */ 35a8e1175bSopenharmony_ci#if !defined(PSA_WANT_KEY_TYPE_AES) 36a8e1175bSopenharmony_ci MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_AES); 37a8e1175bSopenharmony_ci#endif 38a8e1175bSopenharmony_ci#if !defined(PSA_WANT_KEY_TYPE_ARIA) 39a8e1175bSopenharmony_ci MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA); 40a8e1175bSopenharmony_ci#endif 41a8e1175bSopenharmony_ci#if !defined(PSA_WANT_KEY_TYPE_CAMELLIA) 42a8e1175bSopenharmony_ci MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA); 43a8e1175bSopenharmony_ci#endif 44a8e1175bSopenharmony_ci#if !defined(PSA_WANT_KEY_TYPE_CHACHA20) 45a8e1175bSopenharmony_ci MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20); 46a8e1175bSopenharmony_ci#endif 47a8e1175bSopenharmony_ci#if !defined(PSA_WANT_KEY_TYPE_DES) 48a8e1175bSopenharmony_ci MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_DES); 49a8e1175bSopenharmony_ci#endif 50a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_CCM) 51a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0)); 52a8e1175bSopenharmony_ci#endif 53a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_GCM) 54a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0)); 55a8e1175bSopenharmony_ci#endif 56a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_STREAM_CIPHER) 57a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER); 58a8e1175bSopenharmony_ci#endif 59a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_CHACHA20_POLY1305) 60a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)); 61a8e1175bSopenharmony_ci#endif 62a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) 63a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_CCM_STAR_NO_TAG); 64a8e1175bSopenharmony_ci#endif 65a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_CTR) 66a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_CTR); 67a8e1175bSopenharmony_ci#endif 68a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_CFB) 69a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_CFB); 70a8e1175bSopenharmony_ci#endif 71a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_OFB) 72a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_OFB); 73a8e1175bSopenharmony_ci#endif 74a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_XTS) 75a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_XTS); 76a8e1175bSopenharmony_ci#endif 77a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_ECB_NO_PADDING) 78a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING); 79a8e1175bSopenharmony_ci#endif 80a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_CBC_NO_PADDING) 81a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING); 82a8e1175bSopenharmony_ci#endif 83a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_CBC_PKCS7) 84a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7); 85a8e1175bSopenharmony_ci#endif 86a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_CMAC) 87a8e1175bSopenharmony_ci MBEDTLS_ASSUME(alg != PSA_ALG_CMAC); 88a8e1175bSopenharmony_ci#endif 89a8e1175bSopenharmony_ci 90a8e1175bSopenharmony_ci if (alg == PSA_ALG_STREAM_CIPHER || 91a8e1175bSopenharmony_ci alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) { 92a8e1175bSopenharmony_ci if (key_type == PSA_KEY_TYPE_CHACHA20) { 93a8e1175bSopenharmony_ci return PSA_SUCCESS; 94a8e1175bSopenharmony_ci } 95a8e1175bSopenharmony_ci } 96a8e1175bSopenharmony_ci 97a8e1175bSopenharmony_ci if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) || 98a8e1175bSopenharmony_ci alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) || 99a8e1175bSopenharmony_ci alg == PSA_ALG_CCM_STAR_NO_TAG) { 100a8e1175bSopenharmony_ci if (key_type == PSA_KEY_TYPE_AES || 101a8e1175bSopenharmony_ci key_type == PSA_KEY_TYPE_ARIA || 102a8e1175bSopenharmony_ci key_type == PSA_KEY_TYPE_CAMELLIA) { 103a8e1175bSopenharmony_ci return PSA_SUCCESS; 104a8e1175bSopenharmony_ci } 105a8e1175bSopenharmony_ci } 106a8e1175bSopenharmony_ci 107a8e1175bSopenharmony_ci if (alg == PSA_ALG_CTR || 108a8e1175bSopenharmony_ci alg == PSA_ALG_CFB || 109a8e1175bSopenharmony_ci alg == PSA_ALG_OFB || 110a8e1175bSopenharmony_ci alg == PSA_ALG_XTS || 111a8e1175bSopenharmony_ci alg == PSA_ALG_ECB_NO_PADDING || 112a8e1175bSopenharmony_ci alg == PSA_ALG_CBC_NO_PADDING || 113a8e1175bSopenharmony_ci alg == PSA_ALG_CBC_PKCS7 || 114a8e1175bSopenharmony_ci alg == PSA_ALG_CMAC) { 115a8e1175bSopenharmony_ci if (key_type == PSA_KEY_TYPE_AES || 116a8e1175bSopenharmony_ci key_type == PSA_KEY_TYPE_ARIA || 117a8e1175bSopenharmony_ci key_type == PSA_KEY_TYPE_DES || 118a8e1175bSopenharmony_ci key_type == PSA_KEY_TYPE_CAMELLIA) { 119a8e1175bSopenharmony_ci return PSA_SUCCESS; 120a8e1175bSopenharmony_ci } 121a8e1175bSopenharmony_ci } 122a8e1175bSopenharmony_ci 123a8e1175bSopenharmony_ci return PSA_ERROR_NOT_SUPPORTED; 124a8e1175bSopenharmony_ci} 125a8e1175bSopenharmony_ci 126a8e1175bSopenharmony_cipsa_status_t mbedtls_cipher_values_from_psa( 127a8e1175bSopenharmony_ci psa_algorithm_t alg, 128a8e1175bSopenharmony_ci psa_key_type_t key_type, 129a8e1175bSopenharmony_ci size_t *key_bits, 130a8e1175bSopenharmony_ci mbedtls_cipher_mode_t *mode, 131a8e1175bSopenharmony_ci mbedtls_cipher_id_t *cipher_id) 132a8e1175bSopenharmony_ci{ 133a8e1175bSopenharmony_ci mbedtls_cipher_id_t cipher_id_tmp; 134a8e1175bSopenharmony_ci /* Only DES modifies key_bits */ 135a8e1175bSopenharmony_ci#if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) 136a8e1175bSopenharmony_ci (void) key_bits; 137a8e1175bSopenharmony_ci#endif 138a8e1175bSopenharmony_ci 139a8e1175bSopenharmony_ci if (PSA_ALG_IS_AEAD(alg)) { 140a8e1175bSopenharmony_ci alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0); 141a8e1175bSopenharmony_ci } 142a8e1175bSopenharmony_ci 143a8e1175bSopenharmony_ci if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) { 144a8e1175bSopenharmony_ci switch (alg) { 145a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER) 146a8e1175bSopenharmony_ci case PSA_ALG_STREAM_CIPHER: 147a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_STREAM; 148a8e1175bSopenharmony_ci break; 149a8e1175bSopenharmony_ci#endif 150a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR) 151a8e1175bSopenharmony_ci case PSA_ALG_CTR: 152a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_CTR; 153a8e1175bSopenharmony_ci break; 154a8e1175bSopenharmony_ci#endif 155a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB) 156a8e1175bSopenharmony_ci case PSA_ALG_CFB: 157a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_CFB; 158a8e1175bSopenharmony_ci break; 159a8e1175bSopenharmony_ci#endif 160a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) 161a8e1175bSopenharmony_ci case PSA_ALG_OFB: 162a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_OFB; 163a8e1175bSopenharmony_ci break; 164a8e1175bSopenharmony_ci#endif 165a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) 166a8e1175bSopenharmony_ci case PSA_ALG_ECB_NO_PADDING: 167a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_ECB; 168a8e1175bSopenharmony_ci break; 169a8e1175bSopenharmony_ci#endif 170a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) 171a8e1175bSopenharmony_ci case PSA_ALG_CBC_NO_PADDING: 172a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_CBC; 173a8e1175bSopenharmony_ci break; 174a8e1175bSopenharmony_ci#endif 175a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) 176a8e1175bSopenharmony_ci case PSA_ALG_CBC_PKCS7: 177a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_CBC; 178a8e1175bSopenharmony_ci break; 179a8e1175bSopenharmony_ci#endif 180a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG) 181a8e1175bSopenharmony_ci case PSA_ALG_CCM_STAR_NO_TAG: 182a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG; 183a8e1175bSopenharmony_ci break; 184a8e1175bSopenharmony_ci#endif 185a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) 186a8e1175bSopenharmony_ci case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0): 187a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_CCM; 188a8e1175bSopenharmony_ci break; 189a8e1175bSopenharmony_ci#endif 190a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) 191a8e1175bSopenharmony_ci case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0): 192a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_GCM; 193a8e1175bSopenharmony_ci break; 194a8e1175bSopenharmony_ci#endif 195a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) 196a8e1175bSopenharmony_ci case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0): 197a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_CHACHAPOLY; 198a8e1175bSopenharmony_ci break; 199a8e1175bSopenharmony_ci#endif 200a8e1175bSopenharmony_ci default: 201a8e1175bSopenharmony_ci return PSA_ERROR_NOT_SUPPORTED; 202a8e1175bSopenharmony_ci } 203a8e1175bSopenharmony_ci } else if (alg == PSA_ALG_CMAC) { 204a8e1175bSopenharmony_ci *mode = MBEDTLS_MODE_ECB; 205a8e1175bSopenharmony_ci } else { 206a8e1175bSopenharmony_ci return PSA_ERROR_NOT_SUPPORTED; 207a8e1175bSopenharmony_ci } 208a8e1175bSopenharmony_ci 209a8e1175bSopenharmony_ci switch (key_type) { 210a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES) 211a8e1175bSopenharmony_ci case PSA_KEY_TYPE_AES: 212a8e1175bSopenharmony_ci cipher_id_tmp = MBEDTLS_CIPHER_ID_AES; 213a8e1175bSopenharmony_ci break; 214a8e1175bSopenharmony_ci#endif 215a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA) 216a8e1175bSopenharmony_ci case PSA_KEY_TYPE_ARIA: 217a8e1175bSopenharmony_ci cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA; 218a8e1175bSopenharmony_ci break; 219a8e1175bSopenharmony_ci#endif 220a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) 221a8e1175bSopenharmony_ci case PSA_KEY_TYPE_DES: 222a8e1175bSopenharmony_ci /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES, 223a8e1175bSopenharmony_ci * and 192 for three-key Triple-DES. */ 224a8e1175bSopenharmony_ci if (*key_bits == 64) { 225a8e1175bSopenharmony_ci cipher_id_tmp = MBEDTLS_CIPHER_ID_DES; 226a8e1175bSopenharmony_ci } else { 227a8e1175bSopenharmony_ci cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES; 228a8e1175bSopenharmony_ci } 229a8e1175bSopenharmony_ci /* mbedtls doesn't recognize two-key Triple-DES as an algorithm, 230a8e1175bSopenharmony_ci * but two-key Triple-DES is functionally three-key Triple-DES 231a8e1175bSopenharmony_ci * with K1=K3, so that's how we present it to mbedtls. */ 232a8e1175bSopenharmony_ci if (*key_bits == 128) { 233a8e1175bSopenharmony_ci *key_bits = 192; 234a8e1175bSopenharmony_ci } 235a8e1175bSopenharmony_ci break; 236a8e1175bSopenharmony_ci#endif 237a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA) 238a8e1175bSopenharmony_ci case PSA_KEY_TYPE_CAMELLIA: 239a8e1175bSopenharmony_ci cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA; 240a8e1175bSopenharmony_ci break; 241a8e1175bSopenharmony_ci#endif 242a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20) 243a8e1175bSopenharmony_ci case PSA_KEY_TYPE_CHACHA20: 244a8e1175bSopenharmony_ci cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20; 245a8e1175bSopenharmony_ci break; 246a8e1175bSopenharmony_ci#endif 247a8e1175bSopenharmony_ci default: 248a8e1175bSopenharmony_ci return PSA_ERROR_NOT_SUPPORTED; 249a8e1175bSopenharmony_ci } 250a8e1175bSopenharmony_ci if (cipher_id != NULL) { 251a8e1175bSopenharmony_ci *cipher_id = cipher_id_tmp; 252a8e1175bSopenharmony_ci } 253a8e1175bSopenharmony_ci 254a8e1175bSopenharmony_ci return mbedtls_cipher_validate_values(alg, key_type); 255a8e1175bSopenharmony_ci} 256a8e1175bSopenharmony_ci 257a8e1175bSopenharmony_ci#if defined(MBEDTLS_CIPHER_C) 258a8e1175bSopenharmony_ciconst mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( 259a8e1175bSopenharmony_ci psa_algorithm_t alg, 260a8e1175bSopenharmony_ci psa_key_type_t key_type, 261a8e1175bSopenharmony_ci size_t key_bits, 262a8e1175bSopenharmony_ci mbedtls_cipher_id_t *cipher_id) 263a8e1175bSopenharmony_ci{ 264a8e1175bSopenharmony_ci mbedtls_cipher_mode_t mode; 265a8e1175bSopenharmony_ci psa_status_t status; 266a8e1175bSopenharmony_ci mbedtls_cipher_id_t cipher_id_tmp; 267a8e1175bSopenharmony_ci 268a8e1175bSopenharmony_ci status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp); 269a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 270a8e1175bSopenharmony_ci return NULL; 271a8e1175bSopenharmony_ci } 272a8e1175bSopenharmony_ci if (cipher_id != NULL) { 273a8e1175bSopenharmony_ci *cipher_id = cipher_id_tmp; 274a8e1175bSopenharmony_ci } 275a8e1175bSopenharmony_ci 276a8e1175bSopenharmony_ci return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode); 277a8e1175bSopenharmony_ci} 278a8e1175bSopenharmony_ci#endif /* MBEDTLS_CIPHER_C */ 279a8e1175bSopenharmony_ci 280a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) 281a8e1175bSopenharmony_ci 282a8e1175bSopenharmony_cistatic psa_status_t psa_cipher_setup( 283a8e1175bSopenharmony_ci mbedtls_psa_cipher_operation_t *operation, 284a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 285a8e1175bSopenharmony_ci const uint8_t *key_buffer, size_t key_buffer_size, 286a8e1175bSopenharmony_ci psa_algorithm_t alg, 287a8e1175bSopenharmony_ci mbedtls_operation_t cipher_operation) 288a8e1175bSopenharmony_ci{ 289a8e1175bSopenharmony_ci int ret = 0; 290a8e1175bSopenharmony_ci size_t key_bits; 291a8e1175bSopenharmony_ci const mbedtls_cipher_info_t *cipher_info = NULL; 292a8e1175bSopenharmony_ci psa_key_type_t key_type = attributes->type; 293a8e1175bSopenharmony_ci 294a8e1175bSopenharmony_ci (void) key_buffer_size; 295a8e1175bSopenharmony_ci 296a8e1175bSopenharmony_ci mbedtls_cipher_init(&operation->ctx.cipher); 297a8e1175bSopenharmony_ci 298a8e1175bSopenharmony_ci operation->alg = alg; 299a8e1175bSopenharmony_ci key_bits = attributes->bits; 300a8e1175bSopenharmony_ci cipher_info = mbedtls_cipher_info_from_psa(alg, key_type, 301a8e1175bSopenharmony_ci key_bits, NULL); 302a8e1175bSopenharmony_ci if (cipher_info == NULL) { 303a8e1175bSopenharmony_ci return PSA_ERROR_NOT_SUPPORTED; 304a8e1175bSopenharmony_ci } 305a8e1175bSopenharmony_ci 306a8e1175bSopenharmony_ci ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info); 307a8e1175bSopenharmony_ci if (ret != 0) { 308a8e1175bSopenharmony_ci goto exit; 309a8e1175bSopenharmony_ci } 310a8e1175bSopenharmony_ci 311a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) 312a8e1175bSopenharmony_ci if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) { 313a8e1175bSopenharmony_ci /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */ 314a8e1175bSopenharmony_ci uint8_t keys[24]; 315a8e1175bSopenharmony_ci memcpy(keys, key_buffer, 16); 316a8e1175bSopenharmony_ci memcpy(keys + 16, key_buffer, 8); 317a8e1175bSopenharmony_ci ret = mbedtls_cipher_setkey(&operation->ctx.cipher, 318a8e1175bSopenharmony_ci keys, 319a8e1175bSopenharmony_ci 192, cipher_operation); 320a8e1175bSopenharmony_ci } else 321a8e1175bSopenharmony_ci#endif 322a8e1175bSopenharmony_ci { 323a8e1175bSopenharmony_ci ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer, 324a8e1175bSopenharmony_ci (int) key_bits, cipher_operation); 325a8e1175bSopenharmony_ci } 326a8e1175bSopenharmony_ci if (ret != 0) { 327a8e1175bSopenharmony_ci goto exit; 328a8e1175bSopenharmony_ci } 329a8e1175bSopenharmony_ci 330a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \ 331a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) 332a8e1175bSopenharmony_ci switch (alg) { 333a8e1175bSopenharmony_ci case PSA_ALG_CBC_NO_PADDING: 334a8e1175bSopenharmony_ci ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher, 335a8e1175bSopenharmony_ci MBEDTLS_PADDING_NONE); 336a8e1175bSopenharmony_ci break; 337a8e1175bSopenharmony_ci case PSA_ALG_CBC_PKCS7: 338a8e1175bSopenharmony_ci ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher, 339a8e1175bSopenharmony_ci MBEDTLS_PADDING_PKCS7); 340a8e1175bSopenharmony_ci break; 341a8e1175bSopenharmony_ci default: 342a8e1175bSopenharmony_ci /* The algorithm doesn't involve padding. */ 343a8e1175bSopenharmony_ci ret = 0; 344a8e1175bSopenharmony_ci break; 345a8e1175bSopenharmony_ci } 346a8e1175bSopenharmony_ci if (ret != 0) { 347a8e1175bSopenharmony_ci goto exit; 348a8e1175bSopenharmony_ci } 349a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING || 350a8e1175bSopenharmony_ci MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */ 351a8e1175bSopenharmony_ci 352a8e1175bSopenharmony_ci operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 : 353a8e1175bSopenharmony_ci PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type)); 354a8e1175bSopenharmony_ci operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg); 355a8e1175bSopenharmony_ci 356a8e1175bSopenharmony_ciexit: 357a8e1175bSopenharmony_ci return mbedtls_to_psa_error(ret); 358a8e1175bSopenharmony_ci} 359a8e1175bSopenharmony_ci 360a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_cipher_encrypt_setup( 361a8e1175bSopenharmony_ci mbedtls_psa_cipher_operation_t *operation, 362a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 363a8e1175bSopenharmony_ci const uint8_t *key_buffer, size_t key_buffer_size, 364a8e1175bSopenharmony_ci psa_algorithm_t alg) 365a8e1175bSopenharmony_ci{ 366a8e1175bSopenharmony_ci return psa_cipher_setup(operation, attributes, 367a8e1175bSopenharmony_ci key_buffer, key_buffer_size, 368a8e1175bSopenharmony_ci alg, MBEDTLS_ENCRYPT); 369a8e1175bSopenharmony_ci} 370a8e1175bSopenharmony_ci 371a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_cipher_decrypt_setup( 372a8e1175bSopenharmony_ci mbedtls_psa_cipher_operation_t *operation, 373a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 374a8e1175bSopenharmony_ci const uint8_t *key_buffer, size_t key_buffer_size, 375a8e1175bSopenharmony_ci psa_algorithm_t alg) 376a8e1175bSopenharmony_ci{ 377a8e1175bSopenharmony_ci return psa_cipher_setup(operation, attributes, 378a8e1175bSopenharmony_ci key_buffer, key_buffer_size, 379a8e1175bSopenharmony_ci alg, MBEDTLS_DECRYPT); 380a8e1175bSopenharmony_ci} 381a8e1175bSopenharmony_ci 382a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_cipher_set_iv( 383a8e1175bSopenharmony_ci mbedtls_psa_cipher_operation_t *operation, 384a8e1175bSopenharmony_ci const uint8_t *iv, size_t iv_length) 385a8e1175bSopenharmony_ci{ 386a8e1175bSopenharmony_ci if (iv_length != operation->iv_length) { 387a8e1175bSopenharmony_ci return PSA_ERROR_INVALID_ARGUMENT; 388a8e1175bSopenharmony_ci } 389a8e1175bSopenharmony_ci 390a8e1175bSopenharmony_ci return mbedtls_to_psa_error( 391a8e1175bSopenharmony_ci mbedtls_cipher_set_iv(&operation->ctx.cipher, 392a8e1175bSopenharmony_ci iv, iv_length)); 393a8e1175bSopenharmony_ci} 394a8e1175bSopenharmony_ci 395a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) 396a8e1175bSopenharmony_ci/** Process input for which the algorithm is set to ECB mode. 397a8e1175bSopenharmony_ci * 398a8e1175bSopenharmony_ci * This requires manual processing, since the PSA API is defined as being 399a8e1175bSopenharmony_ci * able to process arbitrary-length calls to psa_cipher_update() with ECB mode, 400a8e1175bSopenharmony_ci * but the underlying mbedtls_cipher_update only takes full blocks. 401a8e1175bSopenharmony_ci * 402a8e1175bSopenharmony_ci * \param ctx The mbedtls cipher context to use. It must have been 403a8e1175bSopenharmony_ci * set up for ECB. 404a8e1175bSopenharmony_ci * \param[in] input The input plaintext or ciphertext to process. 405a8e1175bSopenharmony_ci * \param input_length The number of bytes to process from \p input. 406a8e1175bSopenharmony_ci * This does not need to be aligned to a block boundary. 407a8e1175bSopenharmony_ci * If there is a partial block at the end of the input, 408a8e1175bSopenharmony_ci * it is stored in \p ctx for future processing. 409a8e1175bSopenharmony_ci * \param output The buffer where the output is written. It must be 410a8e1175bSopenharmony_ci * at least `BS * floor((p + input_length) / BS)` bytes 411a8e1175bSopenharmony_ci * long, where `p` is the number of bytes in the 412a8e1175bSopenharmony_ci * unprocessed partial block in \p ctx (with 413a8e1175bSopenharmony_ci * `0 <= p <= BS - 1`) and `BS` is the block size. 414a8e1175bSopenharmony_ci * \param output_length On success, the number of bytes written to \p output. 415a8e1175bSopenharmony_ci * \c 0 on error. 416a8e1175bSopenharmony_ci * 417a8e1175bSopenharmony_ci * \return #PSA_SUCCESS or an error from a hardware accelerator 418a8e1175bSopenharmony_ci */ 419a8e1175bSopenharmony_cistatic psa_status_t psa_cipher_update_ecb( 420a8e1175bSopenharmony_ci mbedtls_cipher_context_t *ctx, 421a8e1175bSopenharmony_ci const uint8_t *input, 422a8e1175bSopenharmony_ci size_t input_length, 423a8e1175bSopenharmony_ci uint8_t *output, 424a8e1175bSopenharmony_ci size_t *output_length) 425a8e1175bSopenharmony_ci{ 426a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 427a8e1175bSopenharmony_ci size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); 428a8e1175bSopenharmony_ci size_t internal_output_length = 0; 429a8e1175bSopenharmony_ci *output_length = 0; 430a8e1175bSopenharmony_ci 431a8e1175bSopenharmony_ci if (input_length == 0) { 432a8e1175bSopenharmony_ci status = PSA_SUCCESS; 433a8e1175bSopenharmony_ci goto exit; 434a8e1175bSopenharmony_ci } 435a8e1175bSopenharmony_ci 436a8e1175bSopenharmony_ci if (ctx->unprocessed_len > 0) { 437a8e1175bSopenharmony_ci /* Fill up to block size, and run the block if there's a full one. */ 438a8e1175bSopenharmony_ci size_t bytes_to_copy = block_size - ctx->unprocessed_len; 439a8e1175bSopenharmony_ci 440a8e1175bSopenharmony_ci if (input_length < bytes_to_copy) { 441a8e1175bSopenharmony_ci bytes_to_copy = input_length; 442a8e1175bSopenharmony_ci } 443a8e1175bSopenharmony_ci 444a8e1175bSopenharmony_ci memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), 445a8e1175bSopenharmony_ci input, bytes_to_copy); 446a8e1175bSopenharmony_ci input_length -= bytes_to_copy; 447a8e1175bSopenharmony_ci input += bytes_to_copy; 448a8e1175bSopenharmony_ci ctx->unprocessed_len += bytes_to_copy; 449a8e1175bSopenharmony_ci 450a8e1175bSopenharmony_ci if (ctx->unprocessed_len == block_size) { 451a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 452a8e1175bSopenharmony_ci mbedtls_cipher_update(ctx, 453a8e1175bSopenharmony_ci ctx->unprocessed_data, 454a8e1175bSopenharmony_ci block_size, 455a8e1175bSopenharmony_ci output, &internal_output_length)); 456a8e1175bSopenharmony_ci 457a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 458a8e1175bSopenharmony_ci goto exit; 459a8e1175bSopenharmony_ci } 460a8e1175bSopenharmony_ci 461a8e1175bSopenharmony_ci output += internal_output_length; 462a8e1175bSopenharmony_ci *output_length += internal_output_length; 463a8e1175bSopenharmony_ci ctx->unprocessed_len = 0; 464a8e1175bSopenharmony_ci } 465a8e1175bSopenharmony_ci } 466a8e1175bSopenharmony_ci 467a8e1175bSopenharmony_ci while (input_length >= block_size) { 468a8e1175bSopenharmony_ci /* Run all full blocks we have, one by one */ 469a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 470a8e1175bSopenharmony_ci mbedtls_cipher_update(ctx, input, 471a8e1175bSopenharmony_ci block_size, 472a8e1175bSopenharmony_ci output, &internal_output_length)); 473a8e1175bSopenharmony_ci 474a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 475a8e1175bSopenharmony_ci goto exit; 476a8e1175bSopenharmony_ci } 477a8e1175bSopenharmony_ci 478a8e1175bSopenharmony_ci input_length -= block_size; 479a8e1175bSopenharmony_ci input += block_size; 480a8e1175bSopenharmony_ci 481a8e1175bSopenharmony_ci output += internal_output_length; 482a8e1175bSopenharmony_ci *output_length += internal_output_length; 483a8e1175bSopenharmony_ci } 484a8e1175bSopenharmony_ci 485a8e1175bSopenharmony_ci if (input_length > 0) { 486a8e1175bSopenharmony_ci /* Save unprocessed bytes for later processing */ 487a8e1175bSopenharmony_ci memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), 488a8e1175bSopenharmony_ci input, input_length); 489a8e1175bSopenharmony_ci ctx->unprocessed_len += input_length; 490a8e1175bSopenharmony_ci } 491a8e1175bSopenharmony_ci 492a8e1175bSopenharmony_ci status = PSA_SUCCESS; 493a8e1175bSopenharmony_ci 494a8e1175bSopenharmony_ciexit: 495a8e1175bSopenharmony_ci return status; 496a8e1175bSopenharmony_ci} 497a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */ 498a8e1175bSopenharmony_ci 499a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_cipher_update( 500a8e1175bSopenharmony_ci mbedtls_psa_cipher_operation_t *operation, 501a8e1175bSopenharmony_ci const uint8_t *input, size_t input_length, 502a8e1175bSopenharmony_ci uint8_t *output, size_t output_size, size_t *output_length) 503a8e1175bSopenharmony_ci{ 504a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 505a8e1175bSopenharmony_ci size_t expected_output_size; 506a8e1175bSopenharmony_ci 507a8e1175bSopenharmony_ci if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) { 508a8e1175bSopenharmony_ci /* Take the unprocessed partial block left over from previous 509a8e1175bSopenharmony_ci * update calls, if any, plus the input to this call. Remove 510a8e1175bSopenharmony_ci * the last partial block, if any. You get the data that will be 511a8e1175bSopenharmony_ci * output in this call. */ 512a8e1175bSopenharmony_ci expected_output_size = 513a8e1175bSopenharmony_ci (operation->ctx.cipher.unprocessed_len + input_length) 514a8e1175bSopenharmony_ci / operation->block_length * operation->block_length; 515a8e1175bSopenharmony_ci } else { 516a8e1175bSopenharmony_ci expected_output_size = input_length; 517a8e1175bSopenharmony_ci } 518a8e1175bSopenharmony_ci 519a8e1175bSopenharmony_ci if (output_size < expected_output_size) { 520a8e1175bSopenharmony_ci return PSA_ERROR_BUFFER_TOO_SMALL; 521a8e1175bSopenharmony_ci } 522a8e1175bSopenharmony_ci 523a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) 524a8e1175bSopenharmony_ci if (operation->alg == PSA_ALG_ECB_NO_PADDING) { 525a8e1175bSopenharmony_ci /* mbedtls_cipher_update has an API inconsistency: it will only 526a8e1175bSopenharmony_ci * process a single block at a time in ECB mode. Abstract away that 527a8e1175bSopenharmony_ci * inconsistency here to match the PSA API behaviour. */ 528a8e1175bSopenharmony_ci status = psa_cipher_update_ecb(&operation->ctx.cipher, 529a8e1175bSopenharmony_ci input, 530a8e1175bSopenharmony_ci input_length, 531a8e1175bSopenharmony_ci output, 532a8e1175bSopenharmony_ci output_length); 533a8e1175bSopenharmony_ci } else 534a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */ 535a8e1175bSopenharmony_ci if (input_length == 0) { 536a8e1175bSopenharmony_ci /* There is no input, nothing to be done */ 537a8e1175bSopenharmony_ci *output_length = 0; 538a8e1175bSopenharmony_ci status = PSA_SUCCESS; 539a8e1175bSopenharmony_ci } else { 540a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 541a8e1175bSopenharmony_ci mbedtls_cipher_update(&operation->ctx.cipher, input, 542a8e1175bSopenharmony_ci input_length, output, output_length)); 543a8e1175bSopenharmony_ci 544a8e1175bSopenharmony_ci if (*output_length > output_size) { 545a8e1175bSopenharmony_ci return PSA_ERROR_CORRUPTION_DETECTED; 546a8e1175bSopenharmony_ci } 547a8e1175bSopenharmony_ci } 548a8e1175bSopenharmony_ci 549a8e1175bSopenharmony_ci return status; 550a8e1175bSopenharmony_ci} 551a8e1175bSopenharmony_ci 552a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_cipher_finish( 553a8e1175bSopenharmony_ci mbedtls_psa_cipher_operation_t *operation, 554a8e1175bSopenharmony_ci uint8_t *output, size_t output_size, size_t *output_length) 555a8e1175bSopenharmony_ci{ 556a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_GENERIC_ERROR; 557a8e1175bSopenharmony_ci uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH]; 558a8e1175bSopenharmony_ci 559a8e1175bSopenharmony_ci if (operation->ctx.cipher.unprocessed_len != 0) { 560a8e1175bSopenharmony_ci if (operation->alg == PSA_ALG_ECB_NO_PADDING || 561a8e1175bSopenharmony_ci operation->alg == PSA_ALG_CBC_NO_PADDING) { 562a8e1175bSopenharmony_ci status = PSA_ERROR_INVALID_ARGUMENT; 563a8e1175bSopenharmony_ci goto exit; 564a8e1175bSopenharmony_ci } 565a8e1175bSopenharmony_ci } 566a8e1175bSopenharmony_ci 567a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 568a8e1175bSopenharmony_ci mbedtls_cipher_finish(&operation->ctx.cipher, 569a8e1175bSopenharmony_ci temp_output_buffer, 570a8e1175bSopenharmony_ci output_length)); 571a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 572a8e1175bSopenharmony_ci goto exit; 573a8e1175bSopenharmony_ci } 574a8e1175bSopenharmony_ci 575a8e1175bSopenharmony_ci if (*output_length == 0) { 576a8e1175bSopenharmony_ci ; /* Nothing to copy. Note that output may be NULL in this case. */ 577a8e1175bSopenharmony_ci } else if (output_size >= *output_length) { 578a8e1175bSopenharmony_ci memcpy(output, temp_output_buffer, *output_length); 579a8e1175bSopenharmony_ci } else { 580a8e1175bSopenharmony_ci status = PSA_ERROR_BUFFER_TOO_SMALL; 581a8e1175bSopenharmony_ci } 582a8e1175bSopenharmony_ci 583a8e1175bSopenharmony_ciexit: 584a8e1175bSopenharmony_ci mbedtls_platform_zeroize(temp_output_buffer, 585a8e1175bSopenharmony_ci sizeof(temp_output_buffer)); 586a8e1175bSopenharmony_ci 587a8e1175bSopenharmony_ci return status; 588a8e1175bSopenharmony_ci} 589a8e1175bSopenharmony_ci 590a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_cipher_abort( 591a8e1175bSopenharmony_ci mbedtls_psa_cipher_operation_t *operation) 592a8e1175bSopenharmony_ci{ 593a8e1175bSopenharmony_ci /* Sanity check (shouldn't happen: operation->alg should 594a8e1175bSopenharmony_ci * always have been initialized to a valid value). */ 595a8e1175bSopenharmony_ci if (!PSA_ALG_IS_CIPHER(operation->alg)) { 596a8e1175bSopenharmony_ci return PSA_ERROR_BAD_STATE; 597a8e1175bSopenharmony_ci } 598a8e1175bSopenharmony_ci 599a8e1175bSopenharmony_ci mbedtls_cipher_free(&operation->ctx.cipher); 600a8e1175bSopenharmony_ci 601a8e1175bSopenharmony_ci return PSA_SUCCESS; 602a8e1175bSopenharmony_ci} 603a8e1175bSopenharmony_ci 604a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_cipher_encrypt( 605a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 606a8e1175bSopenharmony_ci const uint8_t *key_buffer, 607a8e1175bSopenharmony_ci size_t key_buffer_size, 608a8e1175bSopenharmony_ci psa_algorithm_t alg, 609a8e1175bSopenharmony_ci const uint8_t *iv, 610a8e1175bSopenharmony_ci size_t iv_length, 611a8e1175bSopenharmony_ci const uint8_t *input, 612a8e1175bSopenharmony_ci size_t input_length, 613a8e1175bSopenharmony_ci uint8_t *output, 614a8e1175bSopenharmony_ci size_t output_size, 615a8e1175bSopenharmony_ci size_t *output_length) 616a8e1175bSopenharmony_ci{ 617a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 618a8e1175bSopenharmony_ci mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT; 619a8e1175bSopenharmony_ci size_t update_output_length, finish_output_length; 620a8e1175bSopenharmony_ci 621a8e1175bSopenharmony_ci status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes, 622a8e1175bSopenharmony_ci key_buffer, key_buffer_size, 623a8e1175bSopenharmony_ci alg); 624a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 625a8e1175bSopenharmony_ci goto exit; 626a8e1175bSopenharmony_ci } 627a8e1175bSopenharmony_ci 628a8e1175bSopenharmony_ci if (iv_length > 0) { 629a8e1175bSopenharmony_ci status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length); 630a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 631a8e1175bSopenharmony_ci goto exit; 632a8e1175bSopenharmony_ci } 633a8e1175bSopenharmony_ci } 634a8e1175bSopenharmony_ci 635a8e1175bSopenharmony_ci status = mbedtls_psa_cipher_update(&operation, input, input_length, 636a8e1175bSopenharmony_ci output, output_size, 637a8e1175bSopenharmony_ci &update_output_length); 638a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 639a8e1175bSopenharmony_ci goto exit; 640a8e1175bSopenharmony_ci } 641a8e1175bSopenharmony_ci 642a8e1175bSopenharmony_ci status = mbedtls_psa_cipher_finish( 643a8e1175bSopenharmony_ci &operation, 644a8e1175bSopenharmony_ci mbedtls_buffer_offset(output, update_output_length), 645a8e1175bSopenharmony_ci output_size - update_output_length, &finish_output_length); 646a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 647a8e1175bSopenharmony_ci goto exit; 648a8e1175bSopenharmony_ci } 649a8e1175bSopenharmony_ci 650a8e1175bSopenharmony_ci *output_length = update_output_length + finish_output_length; 651a8e1175bSopenharmony_ci 652a8e1175bSopenharmony_ciexit: 653a8e1175bSopenharmony_ci if (status == PSA_SUCCESS) { 654a8e1175bSopenharmony_ci status = mbedtls_psa_cipher_abort(&operation); 655a8e1175bSopenharmony_ci } else { 656a8e1175bSopenharmony_ci mbedtls_psa_cipher_abort(&operation); 657a8e1175bSopenharmony_ci } 658a8e1175bSopenharmony_ci 659a8e1175bSopenharmony_ci return status; 660a8e1175bSopenharmony_ci} 661a8e1175bSopenharmony_ci 662a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_cipher_decrypt( 663a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 664a8e1175bSopenharmony_ci const uint8_t *key_buffer, 665a8e1175bSopenharmony_ci size_t key_buffer_size, 666a8e1175bSopenharmony_ci psa_algorithm_t alg, 667a8e1175bSopenharmony_ci const uint8_t *input, 668a8e1175bSopenharmony_ci size_t input_length, 669a8e1175bSopenharmony_ci uint8_t *output, 670a8e1175bSopenharmony_ci size_t output_size, 671a8e1175bSopenharmony_ci size_t *output_length) 672a8e1175bSopenharmony_ci{ 673a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 674a8e1175bSopenharmony_ci mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT; 675a8e1175bSopenharmony_ci size_t olength, accumulated_length; 676a8e1175bSopenharmony_ci 677a8e1175bSopenharmony_ci status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes, 678a8e1175bSopenharmony_ci key_buffer, key_buffer_size, 679a8e1175bSopenharmony_ci alg); 680a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 681a8e1175bSopenharmony_ci goto exit; 682a8e1175bSopenharmony_ci } 683a8e1175bSopenharmony_ci 684a8e1175bSopenharmony_ci if (operation.iv_length > 0) { 685a8e1175bSopenharmony_ci status = mbedtls_psa_cipher_set_iv(&operation, 686a8e1175bSopenharmony_ci input, operation.iv_length); 687a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 688a8e1175bSopenharmony_ci goto exit; 689a8e1175bSopenharmony_ci } 690a8e1175bSopenharmony_ci } 691a8e1175bSopenharmony_ci 692a8e1175bSopenharmony_ci status = mbedtls_psa_cipher_update( 693a8e1175bSopenharmony_ci &operation, 694a8e1175bSopenharmony_ci mbedtls_buffer_offset_const(input, operation.iv_length), 695a8e1175bSopenharmony_ci input_length - operation.iv_length, 696a8e1175bSopenharmony_ci output, output_size, &olength); 697a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 698a8e1175bSopenharmony_ci goto exit; 699a8e1175bSopenharmony_ci } 700a8e1175bSopenharmony_ci 701a8e1175bSopenharmony_ci accumulated_length = olength; 702a8e1175bSopenharmony_ci 703a8e1175bSopenharmony_ci status = mbedtls_psa_cipher_finish( 704a8e1175bSopenharmony_ci &operation, 705a8e1175bSopenharmony_ci mbedtls_buffer_offset(output, accumulated_length), 706a8e1175bSopenharmony_ci output_size - accumulated_length, &olength); 707a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 708a8e1175bSopenharmony_ci goto exit; 709a8e1175bSopenharmony_ci } 710a8e1175bSopenharmony_ci 711a8e1175bSopenharmony_ci *output_length = accumulated_length + olength; 712a8e1175bSopenharmony_ci 713a8e1175bSopenharmony_ciexit: 714a8e1175bSopenharmony_ci if (status == PSA_SUCCESS) { 715a8e1175bSopenharmony_ci status = mbedtls_psa_cipher_abort(&operation); 716a8e1175bSopenharmony_ci } else { 717a8e1175bSopenharmony_ci mbedtls_psa_cipher_abort(&operation); 718a8e1175bSopenharmony_ci } 719a8e1175bSopenharmony_ci 720a8e1175bSopenharmony_ci return status; 721a8e1175bSopenharmony_ci} 722a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ 723a8e1175bSopenharmony_ci 724a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */ 725