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