1b0563631STom Van Eyck /* 2b0563631STom Van Eyck * PSA crypto layer on top of Mbed TLS crypto 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 #include "psa_crypto_core_common.h" 11b0563631STom Van Eyck 12b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 13b0563631STom Van Eyck 14b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_CONFIG) 15b0563631STom Van Eyck #include "check_crypto_config.h" 16b0563631STom Van Eyck #endif 17b0563631STom Van Eyck 18b0563631STom Van Eyck #include "psa/crypto.h" 19b0563631STom Van Eyck #include "psa/crypto_values.h" 20b0563631STom Van Eyck 21b0563631STom Van Eyck #include "psa_crypto_cipher.h" 22b0563631STom Van Eyck #include "psa_crypto_core.h" 23b0563631STom Van Eyck #include "psa_crypto_invasive.h" 24b0563631STom Van Eyck #include "psa_crypto_driver_wrappers.h" 25b0563631STom Van Eyck #include "psa_crypto_driver_wrappers_no_static.h" 26b0563631STom Van Eyck #include "psa_crypto_ecp.h" 27b0563631STom Van Eyck #include "psa_crypto_ffdh.h" 28b0563631STom Van Eyck #include "psa_crypto_hash.h" 29b0563631STom Van Eyck #include "psa_crypto_mac.h" 30b0563631STom Van Eyck #include "psa_crypto_rsa.h" 31b0563631STom Van Eyck #include "psa_crypto_ecp.h" 32b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 33b0563631STom Van Eyck #include "psa_crypto_se.h" 34b0563631STom Van Eyck #endif 35b0563631STom Van Eyck #include "psa_crypto_slot_management.h" 36b0563631STom Van Eyck /* Include internal declarations that are useful for implementing persistently 37b0563631STom Van Eyck * stored keys. */ 38b0563631STom Van Eyck #include "psa_crypto_storage.h" 39b0563631STom Van Eyck 40b0563631STom Van Eyck #include "psa_crypto_random_impl.h" 41b0563631STom Van Eyck 42b0563631STom Van Eyck #include <stdlib.h> 43b0563631STom Van Eyck #include <string.h> 44b0563631STom Van Eyck #include "mbedtls/platform.h" 45b0563631STom Van Eyck 46b0563631STom Van Eyck #include "mbedtls/aes.h" 47b0563631STom Van Eyck #include "mbedtls/asn1.h" 48b0563631STom Van Eyck #include "mbedtls/asn1write.h" 49b0563631STom Van Eyck #include "mbedtls/bignum.h" 50b0563631STom Van Eyck #include "mbedtls/camellia.h" 51b0563631STom Van Eyck #include "mbedtls/chacha20.h" 52b0563631STom Van Eyck #include "mbedtls/chachapoly.h" 53b0563631STom Van Eyck #include "mbedtls/cipher.h" 54b0563631STom Van Eyck #include "mbedtls/ccm.h" 55b0563631STom Van Eyck #include "mbedtls/cmac.h" 56b0563631STom Van Eyck #include "mbedtls/constant_time.h" 57b0563631STom Van Eyck #include "mbedtls/des.h" 58b0563631STom Van Eyck #include "mbedtls/ecdh.h" 59b0563631STom Van Eyck #include "mbedtls/ecp.h" 60b0563631STom Van Eyck #include "mbedtls/entropy.h" 61b0563631STom Van Eyck #include "mbedtls/error.h" 62b0563631STom Van Eyck #include "mbedtls/gcm.h" 63b0563631STom Van Eyck #include "mbedtls/md5.h" 64b0563631STom Van Eyck #include "mbedtls/pk.h" 65b0563631STom Van Eyck #include "pk_wrap.h" 66b0563631STom Van Eyck #include "mbedtls/platform_util.h" 67b0563631STom Van Eyck #include "mbedtls/error.h" 68b0563631STom Van Eyck #include "mbedtls/ripemd160.h" 69b0563631STom Van Eyck #include "mbedtls/rsa.h" 70b0563631STom Van Eyck #include "mbedtls/sha1.h" 71b0563631STom Van Eyck #include "mbedtls/sha256.h" 72b0563631STom Van Eyck #include "mbedtls/sha512.h" 73b0563631STom Van Eyck #include "mbedtls/psa_util.h" 74b0563631STom Van Eyck #include "mbedtls/threading.h" 75b0563631STom Van Eyck 76b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ 77b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \ 78b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) 79b0563631STom Van Eyck #define BUILTIN_ALG_ANY_HKDF 1 80b0563631STom Van Eyck #endif 81b0563631STom Van Eyck 82b0563631STom Van Eyck /****************************************************************/ 83b0563631STom Van Eyck /* Global data, support functions and library management */ 84b0563631STom Van Eyck /****************************************************************/ 85b0563631STom Van Eyck 86b0563631STom Van Eyck static int key_type_is_raw_bytes(psa_key_type_t type) 87b0563631STom Van Eyck { 88b0563631STom Van Eyck return PSA_KEY_TYPE_IS_UNSTRUCTURED(type); 89b0563631STom Van Eyck } 90b0563631STom Van Eyck 91b0563631STom Van Eyck /* Values for psa_global_data_t::rng_state */ 92b0563631STom Van Eyck #define RNG_NOT_INITIALIZED 0 93b0563631STom Van Eyck #define RNG_INITIALIZED 1 94b0563631STom Van Eyck #define RNG_SEEDED 2 95b0563631STom Van Eyck 96b0563631STom Van Eyck /* IDs for PSA crypto subsystems. Starts at 1 to catch potential uninitialized 97b0563631STom Van Eyck * variables as arguments. */ 98b0563631STom Van Eyck typedef enum { 99b0563631STom Van Eyck PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS = 1, 100b0563631STom Van Eyck PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS, 101b0563631STom Van Eyck PSA_CRYPTO_SUBSYSTEM_RNG, 102b0563631STom Van Eyck PSA_CRYPTO_SUBSYSTEM_TRANSACTION, 103b0563631STom Van Eyck } mbedtls_psa_crypto_subsystem; 104b0563631STom Van Eyck 105b0563631STom Van Eyck /* Initialization flags for global_data::initialized */ 106b0563631STom Van Eyck #define PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED 0x01 107b0563631STom Van Eyck #define PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED 0x02 108b0563631STom Van Eyck #define PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED 0x04 109b0563631STom Van Eyck 110b0563631STom Van Eyck #define PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED ( \ 111b0563631STom Van Eyck PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED | \ 112b0563631STom Van Eyck PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED | \ 113b0563631STom Van Eyck PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED) 114b0563631STom Van Eyck 115b0563631STom Van Eyck typedef struct { 116b0563631STom Van Eyck uint8_t initialized; 117b0563631STom Van Eyck uint8_t rng_state; 118b0563631STom Van Eyck mbedtls_psa_random_context_t rng; 119b0563631STom Van Eyck } psa_global_data_t; 120b0563631STom Van Eyck 121b0563631STom Van Eyck static psa_global_data_t global_data; 122b0563631STom Van Eyck 123b0563631STom Van Eyck static uint8_t psa_get_initialized(void) 124b0563631STom Van Eyck { 125b0563631STom Van Eyck uint8_t initialized; 126b0563631STom Van Eyck 127b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 128b0563631STom Van Eyck mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); 129b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 130b0563631STom Van Eyck 131b0563631STom Van Eyck initialized = global_data.rng_state == RNG_SEEDED; 132b0563631STom Van Eyck 133b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 134b0563631STom Van Eyck mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); 135b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 136b0563631STom Van Eyck 137b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 138b0563631STom Van Eyck mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); 139b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 140b0563631STom Van Eyck 141b0563631STom Van Eyck initialized = 142b0563631STom Van Eyck (initialized && (global_data.initialized == PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED)); 143b0563631STom Van Eyck 144b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 145b0563631STom Van Eyck mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); 146b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 147b0563631STom Van Eyck 148b0563631STom Van Eyck return initialized; 149b0563631STom Van Eyck } 150b0563631STom Van Eyck 151b0563631STom Van Eyck static uint8_t psa_get_drivers_initialized(void) 152b0563631STom Van Eyck { 153b0563631STom Van Eyck uint8_t initialized; 154b0563631STom Van Eyck 155b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 156b0563631STom Van Eyck mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); 157b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 158b0563631STom Van Eyck 159b0563631STom Van Eyck initialized = (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED) != 0; 160b0563631STom Van Eyck 161b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 162b0563631STom Van Eyck mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); 163b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 164b0563631STom Van Eyck 165b0563631STom Van Eyck return initialized; 166b0563631STom Van Eyck } 167b0563631STom Van Eyck 168b0563631STom Van Eyck #define GUARD_MODULE_INITIALIZED \ 169b0563631STom Van Eyck if (psa_get_initialized() == 0) \ 170b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 171b0563631STom Van Eyck 172b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 173b0563631STom Van Eyck 174b0563631STom Van Eyck /* Declare a local copy of an input buffer and a variable that will be used 175b0563631STom Van Eyck * to store a pointer to the start of the buffer. 176b0563631STom Van Eyck * 177b0563631STom Van Eyck * Note: This macro must be called before any operations which may jump to 178b0563631STom Van Eyck * the exit label, so that the local input copy object is safe to be freed. 179b0563631STom Van Eyck * 180b0563631STom Van Eyck * Assumptions: 181b0563631STom Van Eyck * - input is the name of a pointer to the buffer to be copied 182b0563631STom Van Eyck * - The name LOCAL_INPUT_COPY_OF_input is unused in the current scope 183b0563631STom Van Eyck * - input_copy_name is a name that is unused in the current scope 184b0563631STom Van Eyck */ 185b0563631STom Van Eyck #define LOCAL_INPUT_DECLARE(input, input_copy_name) \ 186b0563631STom Van Eyck psa_crypto_local_input_t LOCAL_INPUT_COPY_OF_##input = PSA_CRYPTO_LOCAL_INPUT_INIT; \ 187b0563631STom Van Eyck const uint8_t *input_copy_name = NULL; 188b0563631STom Van Eyck 189b0563631STom Van Eyck /* Allocate a copy of the buffer input and set the pointer input_copy to 190b0563631STom Van Eyck * point to the start of the copy. 191b0563631STom Van Eyck * 192b0563631STom Van Eyck * Assumptions: 193b0563631STom Van Eyck * - psa_status_t status exists 194b0563631STom Van Eyck * - An exit label is declared 195b0563631STom Van Eyck * - input is the name of a pointer to the buffer to be copied 196b0563631STom Van Eyck * - LOCAL_INPUT_DECLARE(input, input_copy) has previously been called 197b0563631STom Van Eyck */ 198b0563631STom Van Eyck #define LOCAL_INPUT_ALLOC(input, length, input_copy) \ 199b0563631STom Van Eyck status = psa_crypto_local_input_alloc(input, length, \ 200b0563631STom Van Eyck &LOCAL_INPUT_COPY_OF_##input); \ 201b0563631STom Van Eyck if (status != PSA_SUCCESS) { \ 202b0563631STom Van Eyck goto exit; \ 203b0563631STom Van Eyck } \ 204b0563631STom Van Eyck input_copy = LOCAL_INPUT_COPY_OF_##input.buffer; 205b0563631STom Van Eyck 206b0563631STom Van Eyck /* Free the local input copy allocated previously by LOCAL_INPUT_ALLOC() 207b0563631STom Van Eyck * 208b0563631STom Van Eyck * Assumptions: 209b0563631STom Van Eyck * - input_copy is the name of the input copy pointer set by LOCAL_INPUT_ALLOC() 210b0563631STom Van Eyck * - input is the name of the original buffer that was copied 211b0563631STom Van Eyck */ 212b0563631STom Van Eyck #define LOCAL_INPUT_FREE(input, input_copy) \ 213b0563631STom Van Eyck input_copy = NULL; \ 214b0563631STom Van Eyck psa_crypto_local_input_free(&LOCAL_INPUT_COPY_OF_##input); 215b0563631STom Van Eyck 216b0563631STom Van Eyck /* Declare a local copy of an output buffer and a variable that will be used 217b0563631STom Van Eyck * to store a pointer to the start of the buffer. 218b0563631STom Van Eyck * 219b0563631STom Van Eyck * Note: This macro must be called before any operations which may jump to 220b0563631STom Van Eyck * the exit label, so that the local output copy object is safe to be freed. 221b0563631STom Van Eyck * 222b0563631STom Van Eyck * Assumptions: 223b0563631STom Van Eyck * - output is the name of a pointer to the buffer to be copied 224b0563631STom Van Eyck * - The name LOCAL_OUTPUT_COPY_OF_output is unused in the current scope 225b0563631STom Van Eyck * - output_copy_name is a name that is unused in the current scope 226b0563631STom Van Eyck */ 227b0563631STom Van Eyck #define LOCAL_OUTPUT_DECLARE(output, output_copy_name) \ 228b0563631STom Van Eyck psa_crypto_local_output_t LOCAL_OUTPUT_COPY_OF_##output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; \ 229b0563631STom Van Eyck uint8_t *output_copy_name = NULL; 230b0563631STom Van Eyck 231b0563631STom Van Eyck /* Allocate a copy of the buffer output and set the pointer output_copy to 232b0563631STom Van Eyck * point to the start of the copy. 233b0563631STom Van Eyck * 234b0563631STom Van Eyck * Assumptions: 235b0563631STom Van Eyck * - psa_status_t status exists 236b0563631STom Van Eyck * - An exit label is declared 237b0563631STom Van Eyck * - output is the name of a pointer to the buffer to be copied 238b0563631STom Van Eyck * - LOCAL_OUTPUT_DECLARE(output, output_copy) has previously been called 239b0563631STom Van Eyck */ 240b0563631STom Van Eyck #define LOCAL_OUTPUT_ALLOC(output, length, output_copy) \ 241b0563631STom Van Eyck status = psa_crypto_local_output_alloc(output, length, \ 242b0563631STom Van Eyck &LOCAL_OUTPUT_COPY_OF_##output); \ 243b0563631STom Van Eyck if (status != PSA_SUCCESS) { \ 244b0563631STom Van Eyck goto exit; \ 245b0563631STom Van Eyck } \ 246b0563631STom Van Eyck output_copy = LOCAL_OUTPUT_COPY_OF_##output.buffer; 247b0563631STom Van Eyck 248b0563631STom Van Eyck /* Free the local output copy allocated previously by LOCAL_OUTPUT_ALLOC() 249b0563631STom Van Eyck * after first copying back its contents to the original buffer. 250b0563631STom Van Eyck * 251b0563631STom Van Eyck * Assumptions: 252b0563631STom Van Eyck * - psa_status_t status exists 253b0563631STom Van Eyck * - output_copy is the name of the output copy pointer set by LOCAL_OUTPUT_ALLOC() 254b0563631STom Van Eyck * - output is the name of the original buffer that was copied 255b0563631STom Van Eyck */ 256b0563631STom Van Eyck #define LOCAL_OUTPUT_FREE(output, output_copy) \ 257b0563631STom Van Eyck output_copy = NULL; \ 258b0563631STom Van Eyck do { \ 259b0563631STom Van Eyck psa_status_t local_output_status; \ 260b0563631STom Van Eyck local_output_status = psa_crypto_local_output_free(&LOCAL_OUTPUT_COPY_OF_##output); \ 261b0563631STom Van Eyck if (local_output_status != PSA_SUCCESS) { \ 262b0563631STom Van Eyck /* Since this error case is an internal error, it's more serious than \ 263b0563631STom Van Eyck * any existing error code and so it's fine to overwrite the existing \ 264b0563631STom Van Eyck * status. */ \ 265b0563631STom Van Eyck status = local_output_status; \ 266b0563631STom Van Eyck } \ 267b0563631STom Van Eyck } while (0) 268b0563631STom Van Eyck #else /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */ 269b0563631STom Van Eyck #define LOCAL_INPUT_DECLARE(input, input_copy_name) \ 270b0563631STom Van Eyck const uint8_t *input_copy_name = NULL; 271b0563631STom Van Eyck #define LOCAL_INPUT_ALLOC(input, length, input_copy) \ 272b0563631STom Van Eyck input_copy = input; 273b0563631STom Van Eyck #define LOCAL_INPUT_FREE(input, input_copy) \ 274b0563631STom Van Eyck input_copy = NULL; 275b0563631STom Van Eyck #define LOCAL_OUTPUT_DECLARE(output, output_copy_name) \ 276b0563631STom Van Eyck uint8_t *output_copy_name = NULL; 277b0563631STom Van Eyck #define LOCAL_OUTPUT_ALLOC(output, length, output_copy) \ 278b0563631STom Van Eyck output_copy = output; 279b0563631STom Van Eyck #define LOCAL_OUTPUT_FREE(output, output_copy) \ 280b0563631STom Van Eyck output_copy = NULL; 281b0563631STom Van Eyck #endif /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */ 282b0563631STom Van Eyck 283b0563631STom Van Eyck 284b0563631STom Van Eyck int psa_can_do_hash(psa_algorithm_t hash_alg) 285b0563631STom Van Eyck { 286b0563631STom Van Eyck (void) hash_alg; 287b0563631STom Van Eyck return psa_get_drivers_initialized(); 288b0563631STom Van Eyck } 289b0563631STom Van Eyck 290b0563631STom Van Eyck int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg) 291b0563631STom Van Eyck { 292b0563631STom Van Eyck (void) key_type; 293b0563631STom Van Eyck (void) cipher_alg; 294b0563631STom Van Eyck return psa_get_drivers_initialized(); 295b0563631STom Van Eyck } 296b0563631STom Van Eyck 297b0563631STom Van Eyck 298b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \ 299b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \ 300b0563631STom Van Eyck defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) 301b0563631STom Van Eyck static int psa_is_dh_key_size_valid(size_t bits) 302b0563631STom Van Eyck { 303b0563631STom Van Eyck switch (bits) { 304b0563631STom Van Eyck #if defined(PSA_WANT_DH_RFC7919_2048) 305b0563631STom Van Eyck case 2048: 306b0563631STom Van Eyck return 1; 307b0563631STom Van Eyck #endif /* PSA_WANT_DH_RFC7919_2048 */ 308b0563631STom Van Eyck #if defined(PSA_WANT_DH_RFC7919_3072) 309b0563631STom Van Eyck case 3072: 310b0563631STom Van Eyck return 1; 311b0563631STom Van Eyck #endif /* PSA_WANT_DH_RFC7919_3072 */ 312b0563631STom Van Eyck #if defined(PSA_WANT_DH_RFC7919_4096) 313b0563631STom Van Eyck case 4096: 314b0563631STom Van Eyck return 1; 315b0563631STom Van Eyck #endif /* PSA_WANT_DH_RFC7919_4096 */ 316b0563631STom Van Eyck #if defined(PSA_WANT_DH_RFC7919_6144) 317b0563631STom Van Eyck case 6144: 318b0563631STom Van Eyck return 1; 319b0563631STom Van Eyck #endif /* PSA_WANT_DH_RFC7919_6144 */ 320b0563631STom Van Eyck #if defined(PSA_WANT_DH_RFC7919_8192) 321b0563631STom Van Eyck case 8192: 322b0563631STom Van Eyck return 1; 323b0563631STom Van Eyck #endif /* PSA_WANT_DH_RFC7919_8192 */ 324b0563631STom Van Eyck default: 325b0563631STom Van Eyck return 0; 326b0563631STom Van Eyck } 327b0563631STom Van Eyck } 328b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT || 329b0563631STom Van Eyck MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY || 330b0563631STom Van Eyck PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */ 331b0563631STom Van Eyck 332b0563631STom Van Eyck psa_status_t mbedtls_to_psa_error(int ret) 333b0563631STom Van Eyck { 334b0563631STom Van Eyck /* Mbed TLS error codes can combine a high-level error code and a 335b0563631STom Van Eyck * low-level error code. The low-level error usually reflects the 336b0563631STom Van Eyck * root cause better, so dispatch on that preferably. */ 337b0563631STom Van Eyck int low_level_ret = -(-ret & 0x007f); 338b0563631STom Van Eyck switch (low_level_ret != 0 ? low_level_ret : ret) { 339b0563631STom Van Eyck case 0: 340b0563631STom Van Eyck return PSA_SUCCESS; 341b0563631STom Van Eyck 342b0563631STom Van Eyck #if defined(MBEDTLS_AES_C) 343b0563631STom Van Eyck case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH: 344b0563631STom Van Eyck case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH: 345b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 346b0563631STom Van Eyck case MBEDTLS_ERR_AES_BAD_INPUT_DATA: 347b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 348b0563631STom Van Eyck #endif 349b0563631STom Van Eyck 350b0563631STom Van Eyck #if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_ASN1_WRITE_C) 351b0563631STom Van Eyck case MBEDTLS_ERR_ASN1_OUT_OF_DATA: 352b0563631STom Van Eyck case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG: 353b0563631STom Van Eyck case MBEDTLS_ERR_ASN1_INVALID_LENGTH: 354b0563631STom Van Eyck case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH: 355b0563631STom Van Eyck case MBEDTLS_ERR_ASN1_INVALID_DATA: 356b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 357b0563631STom Van Eyck case MBEDTLS_ERR_ASN1_ALLOC_FAILED: 358b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 359b0563631STom Van Eyck case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL: 360b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 361b0563631STom Van Eyck #endif 362b0563631STom Van Eyck 363b0563631STom Van Eyck #if defined(MBEDTLS_CAMELLIA_C) 364b0563631STom Van Eyck case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA: 365b0563631STom Van Eyck case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH: 366b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 367b0563631STom Van Eyck #endif 368b0563631STom Van Eyck 369b0563631STom Van Eyck #if defined(MBEDTLS_CCM_C) 370b0563631STom Van Eyck case MBEDTLS_ERR_CCM_BAD_INPUT: 371b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 372b0563631STom Van Eyck case MBEDTLS_ERR_CCM_AUTH_FAILED: 373b0563631STom Van Eyck return PSA_ERROR_INVALID_SIGNATURE; 374b0563631STom Van Eyck #endif 375b0563631STom Van Eyck 376b0563631STom Van Eyck #if defined(MBEDTLS_CHACHA20_C) 377b0563631STom Van Eyck case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA: 378b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 379b0563631STom Van Eyck #endif 380b0563631STom Van Eyck 381b0563631STom Van Eyck #if defined(MBEDTLS_CHACHAPOLY_C) 382b0563631STom Van Eyck case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE: 383b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 384b0563631STom Van Eyck case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED: 385b0563631STom Van Eyck return PSA_ERROR_INVALID_SIGNATURE; 386b0563631STom Van Eyck #endif 387b0563631STom Van Eyck 388b0563631STom Van Eyck #if defined(MBEDTLS_CIPHER_C) 389b0563631STom Van Eyck case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE: 390b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 391b0563631STom Van Eyck case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA: 392b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 393b0563631STom Van Eyck case MBEDTLS_ERR_CIPHER_ALLOC_FAILED: 394b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 395b0563631STom Van Eyck case MBEDTLS_ERR_CIPHER_INVALID_PADDING: 396b0563631STom Van Eyck return PSA_ERROR_INVALID_PADDING; 397b0563631STom Van Eyck case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED: 398b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 399b0563631STom Van Eyck case MBEDTLS_ERR_CIPHER_AUTH_FAILED: 400b0563631STom Van Eyck return PSA_ERROR_INVALID_SIGNATURE; 401b0563631STom Van Eyck case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT: 402b0563631STom Van Eyck return PSA_ERROR_CORRUPTION_DETECTED; 403b0563631STom Van Eyck #endif 404b0563631STom Van Eyck 405b0563631STom Van Eyck #if !(defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) || \ 406b0563631STom Van Eyck defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)) 407b0563631STom Van Eyck /* Only check CTR_DRBG error codes if underlying mbedtls_xxx 408b0563631STom Van Eyck * functions are passed a CTR_DRBG instance. */ 409b0563631STom Van Eyck case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED: 410b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_ENTROPY; 411b0563631STom Van Eyck case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG: 412b0563631STom Van Eyck case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG: 413b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 414b0563631STom Van Eyck case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR: 415b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_ENTROPY; 416b0563631STom Van Eyck #endif 417b0563631STom Van Eyck 418b0563631STom Van Eyck #if defined(MBEDTLS_DES_C) 419b0563631STom Van Eyck case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH: 420b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 421b0563631STom Van Eyck #endif 422b0563631STom Van Eyck 423b0563631STom Van Eyck case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED: 424b0563631STom Van Eyck case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE: 425b0563631STom Van Eyck case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED: 426b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_ENTROPY; 427b0563631STom Van Eyck 428b0563631STom Van Eyck #if defined(MBEDTLS_GCM_C) 429b0563631STom Van Eyck case MBEDTLS_ERR_GCM_AUTH_FAILED: 430b0563631STom Van Eyck return PSA_ERROR_INVALID_SIGNATURE; 431b0563631STom Van Eyck case MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL: 432b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 433b0563631STom Van Eyck case MBEDTLS_ERR_GCM_BAD_INPUT: 434b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 435b0563631STom Van Eyck #endif 436b0563631STom Van Eyck 437b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \ 438b0563631STom Van Eyck defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE) 439b0563631STom Van Eyck /* Only check HMAC_DRBG error codes if underlying mbedtls_xxx 440b0563631STom Van Eyck * functions are passed a HMAC_DRBG instance. */ 441b0563631STom Van Eyck case MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED: 442b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_ENTROPY; 443b0563631STom Van Eyck case MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG: 444b0563631STom Van Eyck case MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG: 445b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 446b0563631STom Van Eyck case MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR: 447b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_ENTROPY; 448b0563631STom Van Eyck #endif 449b0563631STom Van Eyck 450b0563631STom Van Eyck #if defined(MBEDTLS_MD_LIGHT) 451b0563631STom Van Eyck case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE: 452b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 453b0563631STom Van Eyck case MBEDTLS_ERR_MD_BAD_INPUT_DATA: 454b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 455b0563631STom Van Eyck case MBEDTLS_ERR_MD_ALLOC_FAILED: 456b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 457b0563631STom Van Eyck #if defined(MBEDTLS_FS_IO) 458b0563631STom Van Eyck case MBEDTLS_ERR_MD_FILE_IO_ERROR: 459b0563631STom Van Eyck return PSA_ERROR_STORAGE_FAILURE; 460b0563631STom Van Eyck #endif 461b0563631STom Van Eyck #endif 462b0563631STom Van Eyck 463b0563631STom Van Eyck #if defined(MBEDTLS_BIGNUM_C) 464b0563631STom Van Eyck #if defined(MBEDTLS_FS_IO) 465b0563631STom Van Eyck case MBEDTLS_ERR_MPI_FILE_IO_ERROR: 466b0563631STom Van Eyck return PSA_ERROR_STORAGE_FAILURE; 467b0563631STom Van Eyck #endif 468b0563631STom Van Eyck case MBEDTLS_ERR_MPI_BAD_INPUT_DATA: 469b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 470b0563631STom Van Eyck case MBEDTLS_ERR_MPI_INVALID_CHARACTER: 471b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 472b0563631STom Van Eyck case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL: 473b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 474b0563631STom Van Eyck case MBEDTLS_ERR_MPI_NEGATIVE_VALUE: 475b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 476b0563631STom Van Eyck case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO: 477b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 478b0563631STom Van Eyck case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: 479b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 480b0563631STom Van Eyck case MBEDTLS_ERR_MPI_ALLOC_FAILED: 481b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 482b0563631STom Van Eyck #endif 483b0563631STom Van Eyck 484b0563631STom Van Eyck #if defined(MBEDTLS_PK_C) 485b0563631STom Van Eyck case MBEDTLS_ERR_PK_ALLOC_FAILED: 486b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 487b0563631STom Van Eyck case MBEDTLS_ERR_PK_TYPE_MISMATCH: 488b0563631STom Van Eyck case MBEDTLS_ERR_PK_BAD_INPUT_DATA: 489b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 490b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || defined(MBEDTLS_FS_IO) || \ 491b0563631STom Van Eyck defined(MBEDTLS_PSA_ITS_FILE_C) 492b0563631STom Van Eyck case MBEDTLS_ERR_PK_FILE_IO_ERROR: 493b0563631STom Van Eyck return PSA_ERROR_STORAGE_FAILURE; 494b0563631STom Van Eyck #endif 495b0563631STom Van Eyck case MBEDTLS_ERR_PK_KEY_INVALID_VERSION: 496b0563631STom Van Eyck case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT: 497b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 498b0563631STom Van Eyck case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG: 499b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 500b0563631STom Van Eyck case MBEDTLS_ERR_PK_PASSWORD_REQUIRED: 501b0563631STom Van Eyck case MBEDTLS_ERR_PK_PASSWORD_MISMATCH: 502b0563631STom Van Eyck return PSA_ERROR_NOT_PERMITTED; 503b0563631STom Van Eyck case MBEDTLS_ERR_PK_INVALID_PUBKEY: 504b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 505b0563631STom Van Eyck case MBEDTLS_ERR_PK_INVALID_ALG: 506b0563631STom Van Eyck case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE: 507b0563631STom Van Eyck case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE: 508b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 509b0563631STom Van Eyck case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH: 510b0563631STom Van Eyck return PSA_ERROR_INVALID_SIGNATURE; 511b0563631STom Van Eyck case MBEDTLS_ERR_PK_BUFFER_TOO_SMALL: 512b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 513b0563631STom Van Eyck #endif 514b0563631STom Van Eyck 515b0563631STom Van Eyck case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED: 516b0563631STom Van Eyck return PSA_ERROR_HARDWARE_FAILURE; 517b0563631STom Van Eyck case MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED: 518b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 519b0563631STom Van Eyck 520b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 521b0563631STom Van Eyck case MBEDTLS_ERR_RSA_BAD_INPUT_DATA: 522b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 523b0563631STom Van Eyck case MBEDTLS_ERR_RSA_INVALID_PADDING: 524b0563631STom Van Eyck return PSA_ERROR_INVALID_PADDING; 525b0563631STom Van Eyck case MBEDTLS_ERR_RSA_KEY_GEN_FAILED: 526b0563631STom Van Eyck return PSA_ERROR_HARDWARE_FAILURE; 527b0563631STom Van Eyck case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED: 528b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 529b0563631STom Van Eyck case MBEDTLS_ERR_RSA_PUBLIC_FAILED: 530b0563631STom Van Eyck case MBEDTLS_ERR_RSA_PRIVATE_FAILED: 531b0563631STom Van Eyck return PSA_ERROR_CORRUPTION_DETECTED; 532b0563631STom Van Eyck case MBEDTLS_ERR_RSA_VERIFY_FAILED: 533b0563631STom Van Eyck return PSA_ERROR_INVALID_SIGNATURE; 534b0563631STom Van Eyck case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE: 535b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 536b0563631STom Van Eyck case MBEDTLS_ERR_RSA_RNG_FAILED: 537b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_ENTROPY; 538b0563631STom Van Eyck #endif 539b0563631STom Van Eyck 540b0563631STom Van Eyck #if defined(MBEDTLS_ECP_LIGHT) 541b0563631STom Van Eyck case MBEDTLS_ERR_ECP_BAD_INPUT_DATA: 542b0563631STom Van Eyck case MBEDTLS_ERR_ECP_INVALID_KEY: 543b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 544b0563631STom Van Eyck case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL: 545b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 546b0563631STom Van Eyck case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE: 547b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 548b0563631STom Van Eyck case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH: 549b0563631STom Van Eyck case MBEDTLS_ERR_ECP_VERIFY_FAILED: 550b0563631STom Van Eyck return PSA_ERROR_INVALID_SIGNATURE; 551b0563631STom Van Eyck case MBEDTLS_ERR_ECP_ALLOC_FAILED: 552b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 553b0563631STom Van Eyck case MBEDTLS_ERR_ECP_RANDOM_FAILED: 554b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_ENTROPY; 555b0563631STom Van Eyck 556b0563631STom Van Eyck #if defined(MBEDTLS_ECP_RESTARTABLE) 557b0563631STom Van Eyck case MBEDTLS_ERR_ECP_IN_PROGRESS: 558b0563631STom Van Eyck return PSA_OPERATION_INCOMPLETE; 559b0563631STom Van Eyck #endif 560b0563631STom Van Eyck #endif 561b0563631STom Van Eyck 562b0563631STom Van Eyck case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED: 563b0563631STom Van Eyck return PSA_ERROR_CORRUPTION_DETECTED; 564b0563631STom Van Eyck 565b0563631STom Van Eyck default: 566b0563631STom Van Eyck return PSA_ERROR_GENERIC_ERROR; 567b0563631STom Van Eyck } 568b0563631STom Van Eyck } 569b0563631STom Van Eyck 570b0563631STom Van Eyck /** 571b0563631STom Van Eyck * \brief For output buffers which contain "tags" 572b0563631STom Van Eyck * (outputs that may be checked for validity like 573b0563631STom Van Eyck * hashes, MACs and signatures), fill the unused 574b0563631STom Van Eyck * part of the output buffer (the whole buffer on 575b0563631STom Van Eyck * error, the trailing part on success) with 576b0563631STom Van Eyck * something that isn't a valid tag (barring an 577b0563631STom Van Eyck * attack on the tag and deliberately-crafted 578b0563631STom Van Eyck * input), in case the caller doesn't check the 579b0563631STom Van Eyck * return status properly. 580b0563631STom Van Eyck * 581b0563631STom Van Eyck * \param output_buffer Pointer to buffer to wipe. May not be NULL 582b0563631STom Van Eyck * unless \p output_buffer_size is zero. 583b0563631STom Van Eyck * \param status Status of function called to generate 584b0563631STom Van Eyck * output_buffer originally 585b0563631STom Van Eyck * \param output_buffer_size Size of output buffer. If zero, \p output_buffer 586b0563631STom Van Eyck * could be NULL. 587b0563631STom Van Eyck * \param output_buffer_length Length of data written to output_buffer, must be 588b0563631STom Van Eyck * less than \p output_buffer_size 589b0563631STom Van Eyck */ 590b0563631STom Van Eyck static void psa_wipe_tag_output_buffer(uint8_t *output_buffer, psa_status_t status, 591b0563631STom Van Eyck size_t output_buffer_size, size_t output_buffer_length) 592b0563631STom Van Eyck { 593b0563631STom Van Eyck size_t offset = 0; 594b0563631STom Van Eyck 595b0563631STom Van Eyck if (output_buffer_size == 0) { 596b0563631STom Van Eyck /* If output_buffer_size is 0 then we have nothing to do. We must not 597b0563631STom Van Eyck call memset because output_buffer may be NULL in this case */ 598b0563631STom Van Eyck return; 599b0563631STom Van Eyck } 600b0563631STom Van Eyck 601b0563631STom Van Eyck if (status == PSA_SUCCESS) { 602b0563631STom Van Eyck offset = output_buffer_length; 603b0563631STom Van Eyck } 604b0563631STom Van Eyck 605b0563631STom Van Eyck memset(output_buffer + offset, '!', output_buffer_size - offset); 606b0563631STom Van Eyck } 607b0563631STom Van Eyck 608b0563631STom Van Eyck 609b0563631STom Van Eyck psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type, 610b0563631STom Van Eyck size_t bits) 611b0563631STom Van Eyck { 612b0563631STom Van Eyck /* Check that the bit size is acceptable for the key type */ 613b0563631STom Van Eyck switch (type) { 614b0563631STom Van Eyck case PSA_KEY_TYPE_RAW_DATA: 615b0563631STom Van Eyck case PSA_KEY_TYPE_HMAC: 616b0563631STom Van Eyck case PSA_KEY_TYPE_DERIVE: 617b0563631STom Van Eyck case PSA_KEY_TYPE_PASSWORD: 618b0563631STom Van Eyck case PSA_KEY_TYPE_PASSWORD_HASH: 619b0563631STom Van Eyck break; 620b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_AES) 621b0563631STom Van Eyck case PSA_KEY_TYPE_AES: 622b0563631STom Van Eyck if (bits != 128 && bits != 192 && bits != 256) { 623b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 624b0563631STom Van Eyck } 625b0563631STom Van Eyck break; 626b0563631STom Van Eyck #endif 627b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_ARIA) 628b0563631STom Van Eyck case PSA_KEY_TYPE_ARIA: 629b0563631STom Van Eyck if (bits != 128 && bits != 192 && bits != 256) { 630b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 631b0563631STom Van Eyck } 632b0563631STom Van Eyck break; 633b0563631STom Van Eyck #endif 634b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_CAMELLIA) 635b0563631STom Van Eyck case PSA_KEY_TYPE_CAMELLIA: 636b0563631STom Van Eyck if (bits != 128 && bits != 192 && bits != 256) { 637b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 638b0563631STom Van Eyck } 639b0563631STom Van Eyck break; 640b0563631STom Van Eyck #endif 641b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_DES) 642b0563631STom Van Eyck case PSA_KEY_TYPE_DES: 643b0563631STom Van Eyck if (bits != 64 && bits != 128 && bits != 192) { 644b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 645b0563631STom Van Eyck } 646b0563631STom Van Eyck break; 647b0563631STom Van Eyck #endif 648b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_CHACHA20) 649b0563631STom Van Eyck case PSA_KEY_TYPE_CHACHA20: 650b0563631STom Van Eyck if (bits != 256) { 651b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 652b0563631STom Van Eyck } 653b0563631STom Van Eyck break; 654b0563631STom Van Eyck #endif 655b0563631STom Van Eyck default: 656b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 657b0563631STom Van Eyck } 658b0563631STom Van Eyck if (bits % 8 != 0) { 659b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 660b0563631STom Van Eyck } 661b0563631STom Van Eyck 662b0563631STom Van Eyck return PSA_SUCCESS; 663b0563631STom Van Eyck } 664b0563631STom Van Eyck 665b0563631STom Van Eyck /** Check whether a given key type is valid for use with a given MAC algorithm 666b0563631STom Van Eyck * 667b0563631STom Van Eyck * Upon successful return of this function, the behavior of #PSA_MAC_LENGTH 668b0563631STom Van Eyck * when called with the validated \p algorithm and \p key_type is well-defined. 669b0563631STom Van Eyck * 670b0563631STom Van Eyck * \param[in] algorithm The specific MAC algorithm (can be wildcard). 671b0563631STom Van Eyck * \param[in] key_type The key type of the key to be used with the 672b0563631STom Van Eyck * \p algorithm. 673b0563631STom Van Eyck * 674b0563631STom Van Eyck * \retval #PSA_SUCCESS 675b0563631STom Van Eyck * The \p key_type is valid for use with the \p algorithm 676b0563631STom Van Eyck * \retval #PSA_ERROR_INVALID_ARGUMENT 677b0563631STom Van Eyck * The \p key_type is not valid for use with the \p algorithm 678b0563631STom Van Eyck */ 679b0563631STom Van Eyck MBEDTLS_STATIC_TESTABLE psa_status_t psa_mac_key_can_do( 680b0563631STom Van Eyck psa_algorithm_t algorithm, 681b0563631STom Van Eyck psa_key_type_t key_type) 682b0563631STom Van Eyck { 683b0563631STom Van Eyck if (PSA_ALG_IS_HMAC(algorithm)) { 684b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_HMAC) { 685b0563631STom Van Eyck return PSA_SUCCESS; 686b0563631STom Van Eyck } 687b0563631STom Van Eyck } 688b0563631STom Van Eyck 689b0563631STom Van Eyck if (PSA_ALG_IS_BLOCK_CIPHER_MAC(algorithm)) { 690b0563631STom Van Eyck /* Check that we're calling PSA_BLOCK_CIPHER_BLOCK_LENGTH with a cipher 691b0563631STom Van Eyck * key. */ 692b0563631STom Van Eyck if ((key_type & PSA_KEY_TYPE_CATEGORY_MASK) == 693b0563631STom Van Eyck PSA_KEY_TYPE_CATEGORY_SYMMETRIC) { 694b0563631STom Van Eyck /* PSA_BLOCK_CIPHER_BLOCK_LENGTH returns 1 for stream ciphers and 695b0563631STom Van Eyck * the block length (larger than 1) for block ciphers. */ 696b0563631STom Van Eyck if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1) { 697b0563631STom Van Eyck return PSA_SUCCESS; 698b0563631STom Van Eyck } 699b0563631STom Van Eyck } 700b0563631STom Van Eyck } 701b0563631STom Van Eyck 702b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 703b0563631STom Van Eyck } 704b0563631STom Van Eyck 705b0563631STom Van Eyck psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot, 706b0563631STom Van Eyck size_t buffer_length) 707b0563631STom Van Eyck { 708b0563631STom Van Eyck if (slot->key.data != NULL) { 709b0563631STom Van Eyck return PSA_ERROR_ALREADY_EXISTS; 710b0563631STom Van Eyck } 711b0563631STom Van Eyck 712b0563631STom Van Eyck slot->key.data = mbedtls_calloc(1, buffer_length); 713b0563631STom Van Eyck if (slot->key.data == NULL) { 714b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 715b0563631STom Van Eyck } 716b0563631STom Van Eyck 717b0563631STom Van Eyck slot->key.bytes = buffer_length; 718b0563631STom Van Eyck return PSA_SUCCESS; 719b0563631STom Van Eyck } 720b0563631STom Van Eyck 721b0563631STom Van Eyck psa_status_t psa_copy_key_material_into_slot(psa_key_slot_t *slot, 722b0563631STom Van Eyck const uint8_t *data, 723b0563631STom Van Eyck size_t data_length) 724b0563631STom Van Eyck { 725b0563631STom Van Eyck psa_status_t status = psa_allocate_buffer_to_slot(slot, 726b0563631STom Van Eyck data_length); 727b0563631STom Van Eyck if (status != PSA_SUCCESS) { 728b0563631STom Van Eyck return status; 729b0563631STom Van Eyck } 730b0563631STom Van Eyck 731b0563631STom Van Eyck memcpy(slot->key.data, data, data_length); 732b0563631STom Van Eyck return PSA_SUCCESS; 733b0563631STom Van Eyck } 734b0563631STom Van Eyck 735b0563631STom Van Eyck psa_status_t psa_import_key_into_slot( 736b0563631STom Van Eyck const psa_key_attributes_t *attributes, 737b0563631STom Van Eyck const uint8_t *data, size_t data_length, 738b0563631STom Van Eyck uint8_t *key_buffer, size_t key_buffer_size, 739b0563631STom Van Eyck size_t *key_buffer_length, size_t *bits) 740b0563631STom Van Eyck { 741b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 742b0563631STom Van Eyck psa_key_type_t type = attributes->type; 743b0563631STom Van Eyck 744b0563631STom Van Eyck /* zero-length keys are never supported. */ 745b0563631STom Van Eyck if (data_length == 0) { 746b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 747b0563631STom Van Eyck } 748b0563631STom Van Eyck 749b0563631STom Van Eyck if (key_type_is_raw_bytes(type)) { 750b0563631STom Van Eyck *bits = PSA_BYTES_TO_BITS(data_length); 751b0563631STom Van Eyck 752b0563631STom Van Eyck status = psa_validate_unstructured_key_bit_size(attributes->type, 753b0563631STom Van Eyck *bits); 754b0563631STom Van Eyck if (status != PSA_SUCCESS) { 755b0563631STom Van Eyck return status; 756b0563631STom Van Eyck } 757b0563631STom Van Eyck 758b0563631STom Van Eyck /* Copy the key material. */ 759b0563631STom Van Eyck memcpy(key_buffer, data, data_length); 760b0563631STom Van Eyck *key_buffer_length = data_length; 761b0563631STom Van Eyck (void) key_buffer_size; 762b0563631STom Van Eyck 763b0563631STom Van Eyck return PSA_SUCCESS; 764b0563631STom Van Eyck } else if (PSA_KEY_TYPE_IS_ASYMMETRIC(type)) { 765b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \ 766b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) 767b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_DH(type)) { 768b0563631STom Van Eyck if (psa_is_dh_key_size_valid(PSA_BYTES_TO_BITS(data_length)) == 0) { 769b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 770b0563631STom Van Eyck } 771b0563631STom Van Eyck return mbedtls_psa_ffdh_import_key(attributes, 772b0563631STom Van Eyck data, data_length, 773b0563631STom Van Eyck key_buffer, key_buffer_size, 774b0563631STom Van Eyck key_buffer_length, 775b0563631STom Van Eyck bits); 776b0563631STom Van Eyck } 777b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || 778b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */ 779b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ 780b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) 781b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_ECC(type)) { 782b0563631STom Van Eyck return mbedtls_psa_ecp_import_key(attributes, 783b0563631STom Van Eyck data, data_length, 784b0563631STom Van Eyck key_buffer, key_buffer_size, 785b0563631STom Van Eyck key_buffer_length, 786b0563631STom Van Eyck bits); 787b0563631STom Van Eyck } 788b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || 789b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ 790b0563631STom Van Eyck #if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && \ 791b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || \ 792b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) 793b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_RSA(type)) { 794b0563631STom Van Eyck return mbedtls_psa_rsa_import_key(attributes, 795b0563631STom Van Eyck data, data_length, 796b0563631STom Van Eyck key_buffer, key_buffer_size, 797b0563631STom Van Eyck key_buffer_length, 798b0563631STom Van Eyck bits); 799b0563631STom Van Eyck } 800b0563631STom Van Eyck #endif /* (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && 801b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || 802b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ 803b0563631STom Van Eyck } 804b0563631STom Van Eyck 805b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 806b0563631STom Van Eyck } 807b0563631STom Van Eyck 808b0563631STom Van Eyck /** Calculate the intersection of two algorithm usage policies. 809b0563631STom Van Eyck * 810b0563631STom Van Eyck * Return 0 (which allows no operation) on incompatibility. 811b0563631STom Van Eyck */ 812b0563631STom Van Eyck static psa_algorithm_t psa_key_policy_algorithm_intersection( 813b0563631STom Van Eyck psa_key_type_t key_type, 814b0563631STom Van Eyck psa_algorithm_t alg1, 815b0563631STom Van Eyck psa_algorithm_t alg2) 816b0563631STom Van Eyck { 817b0563631STom Van Eyck /* Common case: both sides actually specify the same policy. */ 818b0563631STom Van Eyck if (alg1 == alg2) { 819b0563631STom Van Eyck return alg1; 820b0563631STom Van Eyck } 821b0563631STom Van Eyck /* If the policies are from the same hash-and-sign family, check 822b0563631STom Van Eyck * if one is a wildcard. If so the other has the specific algorithm. */ 823b0563631STom Van Eyck if (PSA_ALG_IS_SIGN_HASH(alg1) && 824b0563631STom Van Eyck PSA_ALG_IS_SIGN_HASH(alg2) && 825b0563631STom Van Eyck (alg1 & ~PSA_ALG_HASH_MASK) == (alg2 & ~PSA_ALG_HASH_MASK)) { 826b0563631STom Van Eyck if (PSA_ALG_SIGN_GET_HASH(alg1) == PSA_ALG_ANY_HASH) { 827b0563631STom Van Eyck return alg2; 828b0563631STom Van Eyck } 829b0563631STom Van Eyck if (PSA_ALG_SIGN_GET_HASH(alg2) == PSA_ALG_ANY_HASH) { 830b0563631STom Van Eyck return alg1; 831b0563631STom Van Eyck } 832b0563631STom Van Eyck } 833b0563631STom Van Eyck /* If the policies are from the same AEAD family, check whether 834b0563631STom Van Eyck * one of them is a minimum-tag-length wildcard. Calculate the most 835b0563631STom Van Eyck * restrictive tag length. */ 836b0563631STom Van Eyck if (PSA_ALG_IS_AEAD(alg1) && PSA_ALG_IS_AEAD(alg2) && 837b0563631STom Van Eyck (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg1, 0) == 838b0563631STom Van Eyck PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg2, 0))) { 839b0563631STom Van Eyck size_t alg1_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg1); 840b0563631STom Van Eyck size_t alg2_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg2); 841b0563631STom Van Eyck size_t restricted_len = alg1_len > alg2_len ? alg1_len : alg2_len; 842b0563631STom Van Eyck 843b0563631STom Van Eyck /* If both are wildcards, return most restrictive wildcard */ 844b0563631STom Van Eyck if (((alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) && 845b0563631STom Van Eyck ((alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0)) { 846b0563631STom Van Eyck return PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( 847b0563631STom Van Eyck alg1, restricted_len); 848b0563631STom Van Eyck } 849b0563631STom Van Eyck /* If only one is a wildcard, return specific algorithm if compatible. */ 850b0563631STom Van Eyck if (((alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) && 851b0563631STom Van Eyck (alg1_len <= alg2_len)) { 852b0563631STom Van Eyck return alg2; 853b0563631STom Van Eyck } 854b0563631STom Van Eyck if (((alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) && 855b0563631STom Van Eyck (alg2_len <= alg1_len)) { 856b0563631STom Van Eyck return alg1; 857b0563631STom Van Eyck } 858b0563631STom Van Eyck } 859b0563631STom Van Eyck /* If the policies are from the same MAC family, check whether one 860b0563631STom Van Eyck * of them is a minimum-MAC-length policy. Calculate the most 861b0563631STom Van Eyck * restrictive tag length. */ 862b0563631STom Van Eyck if (PSA_ALG_IS_MAC(alg1) && PSA_ALG_IS_MAC(alg2) && 863b0563631STom Van Eyck (PSA_ALG_FULL_LENGTH_MAC(alg1) == 864b0563631STom Van Eyck PSA_ALG_FULL_LENGTH_MAC(alg2))) { 865b0563631STom Van Eyck /* Validate the combination of key type and algorithm. Since the base 866b0563631STom Van Eyck * algorithm of alg1 and alg2 are the same, we only need this once. */ 867b0563631STom Van Eyck if (PSA_SUCCESS != psa_mac_key_can_do(alg1, key_type)) { 868b0563631STom Van Eyck return 0; 869b0563631STom Van Eyck } 870b0563631STom Van Eyck 871b0563631STom Van Eyck /* Get the (exact or at-least) output lengths for both sides of the 872b0563631STom Van Eyck * requested intersection. None of the currently supported algorithms 873b0563631STom Van Eyck * have an output length dependent on the actual key size, so setting it 874b0563631STom Van Eyck * to a bogus value of 0 is currently OK. 875b0563631STom Van Eyck * 876b0563631STom Van Eyck * Note that for at-least-this-length wildcard algorithms, the output 877b0563631STom Van Eyck * length is set to the shortest allowed length, which allows us to 878b0563631STom Van Eyck * calculate the most restrictive tag length for the intersection. */ 879b0563631STom Van Eyck size_t alg1_len = PSA_MAC_LENGTH(key_type, 0, alg1); 880b0563631STom Van Eyck size_t alg2_len = PSA_MAC_LENGTH(key_type, 0, alg2); 881b0563631STom Van Eyck size_t restricted_len = alg1_len > alg2_len ? alg1_len : alg2_len; 882b0563631STom Van Eyck 883b0563631STom Van Eyck /* If both are wildcards, return most restrictive wildcard */ 884b0563631STom Van Eyck if (((alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) && 885b0563631STom Van Eyck ((alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0)) { 886b0563631STom Van Eyck return PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(alg1, restricted_len); 887b0563631STom Van Eyck } 888b0563631STom Van Eyck 889b0563631STom Van Eyck /* If only one is an at-least-this-length policy, the intersection would 890b0563631STom Van Eyck * be the other (fixed-length) policy as long as said fixed length is 891b0563631STom Van Eyck * equal to or larger than the shortest allowed length. */ 892b0563631STom Van Eyck if ((alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) { 893b0563631STom Van Eyck return (alg1_len <= alg2_len) ? alg2 : 0; 894b0563631STom Van Eyck } 895b0563631STom Van Eyck if ((alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) { 896b0563631STom Van Eyck return (alg2_len <= alg1_len) ? alg1 : 0; 897b0563631STom Van Eyck } 898b0563631STom Van Eyck 899b0563631STom Van Eyck /* If none of them are wildcards, check whether they define the same tag 900b0563631STom Van Eyck * length. This is still possible here when one is default-length and 901b0563631STom Van Eyck * the other specific-length. Ensure to always return the 902b0563631STom Van Eyck * specific-length version for the intersection. */ 903b0563631STom Van Eyck if (alg1_len == alg2_len) { 904b0563631STom Van Eyck return PSA_ALG_TRUNCATED_MAC(alg1, alg1_len); 905b0563631STom Van Eyck } 906b0563631STom Van Eyck } 907b0563631STom Van Eyck /* If the policies are incompatible, allow nothing. */ 908b0563631STom Van Eyck return 0; 909b0563631STom Van Eyck } 910b0563631STom Van Eyck 911b0563631STom Van Eyck static int psa_key_algorithm_permits(psa_key_type_t key_type, 912b0563631STom Van Eyck psa_algorithm_t policy_alg, 913b0563631STom Van Eyck psa_algorithm_t requested_alg) 914b0563631STom Van Eyck { 915b0563631STom Van Eyck /* Common case: the policy only allows requested_alg. */ 916b0563631STom Van Eyck if (requested_alg == policy_alg) { 917b0563631STom Van Eyck return 1; 918b0563631STom Van Eyck } 919b0563631STom Van Eyck /* If policy_alg is a hash-and-sign with a wildcard for the hash, 920b0563631STom Van Eyck * and requested_alg is the same hash-and-sign family with any hash, 921b0563631STom Van Eyck * then requested_alg is compliant with policy_alg. */ 922b0563631STom Van Eyck if (PSA_ALG_IS_SIGN_HASH(requested_alg) && 923b0563631STom Van Eyck PSA_ALG_SIGN_GET_HASH(policy_alg) == PSA_ALG_ANY_HASH) { 924b0563631STom Van Eyck return (policy_alg & ~PSA_ALG_HASH_MASK) == 925b0563631STom Van Eyck (requested_alg & ~PSA_ALG_HASH_MASK); 926b0563631STom Van Eyck } 927b0563631STom Van Eyck /* If policy_alg is a wildcard AEAD algorithm of the same base as 928b0563631STom Van Eyck * the requested algorithm, check the requested tag length to be 929b0563631STom Van Eyck * equal-length or longer than the wildcard-specified length. */ 930b0563631STom Van Eyck if (PSA_ALG_IS_AEAD(policy_alg) && 931b0563631STom Van Eyck PSA_ALG_IS_AEAD(requested_alg) && 932b0563631STom Van Eyck (PSA_ALG_AEAD_WITH_SHORTENED_TAG(policy_alg, 0) == 933b0563631STom Van Eyck PSA_ALG_AEAD_WITH_SHORTENED_TAG(requested_alg, 0)) && 934b0563631STom Van Eyck ((policy_alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0)) { 935b0563631STom Van Eyck return PSA_ALG_AEAD_GET_TAG_LENGTH(policy_alg) <= 936b0563631STom Van Eyck PSA_ALG_AEAD_GET_TAG_LENGTH(requested_alg); 937b0563631STom Van Eyck } 938b0563631STom Van Eyck /* If policy_alg is a MAC algorithm of the same base as the requested 939b0563631STom Van Eyck * algorithm, check whether their MAC lengths are compatible. */ 940b0563631STom Van Eyck if (PSA_ALG_IS_MAC(policy_alg) && 941b0563631STom Van Eyck PSA_ALG_IS_MAC(requested_alg) && 942b0563631STom Van Eyck (PSA_ALG_FULL_LENGTH_MAC(policy_alg) == 943b0563631STom Van Eyck PSA_ALG_FULL_LENGTH_MAC(requested_alg))) { 944b0563631STom Van Eyck /* Validate the combination of key type and algorithm. Since the policy 945b0563631STom Van Eyck * and requested algorithms are the same, we only need this once. */ 946b0563631STom Van Eyck if (PSA_SUCCESS != psa_mac_key_can_do(policy_alg, key_type)) { 947b0563631STom Van Eyck return 0; 948b0563631STom Van Eyck } 949b0563631STom Van Eyck 950b0563631STom Van Eyck /* Get both the requested output length for the algorithm which is to be 951b0563631STom Van Eyck * verified, and the default output length for the base algorithm. 952b0563631STom Van Eyck * Note that none of the currently supported algorithms have an output 953b0563631STom Van Eyck * length dependent on actual key size, so setting it to a bogus value 954b0563631STom Van Eyck * of 0 is currently OK. */ 955b0563631STom Van Eyck size_t requested_output_length = PSA_MAC_LENGTH( 956b0563631STom Van Eyck key_type, 0, requested_alg); 957b0563631STom Van Eyck size_t default_output_length = PSA_MAC_LENGTH( 958b0563631STom Van Eyck key_type, 0, 959b0563631STom Van Eyck PSA_ALG_FULL_LENGTH_MAC(requested_alg)); 960b0563631STom Van Eyck 961b0563631STom Van Eyck /* If the policy is default-length, only allow an algorithm with 962b0563631STom Van Eyck * a declared exact-length matching the default. */ 963b0563631STom Van Eyck if (PSA_MAC_TRUNCATED_LENGTH(policy_alg) == 0) { 964b0563631STom Van Eyck return requested_output_length == default_output_length; 965b0563631STom Van Eyck } 966b0563631STom Van Eyck 967b0563631STom Van Eyck /* If the requested algorithm is default-length, allow it if the policy 968b0563631STom Van Eyck * length exactly matches the default length. */ 969b0563631STom Van Eyck if (PSA_MAC_TRUNCATED_LENGTH(requested_alg) == 0 && 970b0563631STom Van Eyck PSA_MAC_TRUNCATED_LENGTH(policy_alg) == default_output_length) { 971b0563631STom Van Eyck return 1; 972b0563631STom Van Eyck } 973b0563631STom Van Eyck 974b0563631STom Van Eyck /* If policy_alg is an at-least-this-length wildcard MAC algorithm, 975b0563631STom Van Eyck * check for the requested MAC length to be equal to or longer than the 976b0563631STom Van Eyck * minimum allowed length. */ 977b0563631STom Van Eyck if ((policy_alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) { 978b0563631STom Van Eyck return PSA_MAC_TRUNCATED_LENGTH(policy_alg) <= 979b0563631STom Van Eyck requested_output_length; 980b0563631STom Van Eyck } 981b0563631STom Van Eyck } 982b0563631STom Van Eyck /* If policy_alg is a generic key agreement operation, then using it for 983b0563631STom Van Eyck * a key derivation with that key agreement should also be allowed. This 984b0563631STom Van Eyck * behaviour is expected to be defined in a future specification version. */ 985b0563631STom Van Eyck if (PSA_ALG_IS_RAW_KEY_AGREEMENT(policy_alg) && 986b0563631STom Van Eyck PSA_ALG_IS_KEY_AGREEMENT(requested_alg)) { 987b0563631STom Van Eyck return PSA_ALG_KEY_AGREEMENT_GET_BASE(requested_alg) == 988b0563631STom Van Eyck policy_alg; 989b0563631STom Van Eyck } 990b0563631STom Van Eyck /* If it isn't explicitly permitted, it's forbidden. */ 991b0563631STom Van Eyck return 0; 992b0563631STom Van Eyck } 993b0563631STom Van Eyck 994b0563631STom Van Eyck /** Test whether a policy permits an algorithm. 995b0563631STom Van Eyck * 996b0563631STom Van Eyck * The caller must test usage flags separately. 997b0563631STom Van Eyck * 998b0563631STom Van Eyck * \note This function requires providing the key type for which the policy is 999b0563631STom Van Eyck * being validated, since some algorithm policy definitions (e.g. MAC) 1000b0563631STom Van Eyck * have different properties depending on what kind of cipher it is 1001b0563631STom Van Eyck * combined with. 1002b0563631STom Van Eyck * 1003b0563631STom Van Eyck * \retval PSA_SUCCESS When \p alg is a specific algorithm 1004b0563631STom Van Eyck * allowed by the \p policy. 1005b0563631STom Van Eyck * \retval PSA_ERROR_INVALID_ARGUMENT When \p alg is not a specific algorithm 1006b0563631STom Van Eyck * \retval PSA_ERROR_NOT_PERMITTED When \p alg is a specific algorithm, but 1007b0563631STom Van Eyck * the \p policy does not allow it. 1008b0563631STom Van Eyck */ 1009b0563631STom Van Eyck static psa_status_t psa_key_policy_permits(const psa_key_policy_t *policy, 1010b0563631STom Van Eyck psa_key_type_t key_type, 1011b0563631STom Van Eyck psa_algorithm_t alg) 1012b0563631STom Van Eyck { 1013b0563631STom Van Eyck /* '0' is not a valid algorithm */ 1014b0563631STom Van Eyck if (alg == 0) { 1015b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 1016b0563631STom Van Eyck } 1017b0563631STom Van Eyck 1018b0563631STom Van Eyck /* A requested algorithm cannot be a wildcard. */ 1019b0563631STom Van Eyck if (PSA_ALG_IS_WILDCARD(alg)) { 1020b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 1021b0563631STom Van Eyck } 1022b0563631STom Van Eyck 1023b0563631STom Van Eyck if (psa_key_algorithm_permits(key_type, policy->alg, alg) || 1024b0563631STom Van Eyck psa_key_algorithm_permits(key_type, policy->alg2, alg)) { 1025b0563631STom Van Eyck return PSA_SUCCESS; 1026b0563631STom Van Eyck } else { 1027b0563631STom Van Eyck return PSA_ERROR_NOT_PERMITTED; 1028b0563631STom Van Eyck } 1029b0563631STom Van Eyck } 1030b0563631STom Van Eyck 1031b0563631STom Van Eyck /** Restrict a key policy based on a constraint. 1032b0563631STom Van Eyck * 1033b0563631STom Van Eyck * \note This function requires providing the key type for which the policy is 1034b0563631STom Van Eyck * being restricted, since some algorithm policy definitions (e.g. MAC) 1035b0563631STom Van Eyck * have different properties depending on what kind of cipher it is 1036b0563631STom Van Eyck * combined with. 1037b0563631STom Van Eyck * 1038b0563631STom Van Eyck * \param[in] key_type The key type for which to restrict the policy 1039b0563631STom Van Eyck * \param[in,out] policy The policy to restrict. 1040b0563631STom Van Eyck * \param[in] constraint The policy constraint to apply. 1041b0563631STom Van Eyck * 1042b0563631STom Van Eyck * \retval #PSA_SUCCESS 1043b0563631STom Van Eyck * \c *policy contains the intersection of the original value of 1044b0563631STom Van Eyck * \c *policy and \c *constraint. 1045b0563631STom Van Eyck * \retval #PSA_ERROR_INVALID_ARGUMENT 1046b0563631STom Van Eyck * \c key_type, \c *policy and \c *constraint are incompatible. 1047b0563631STom Van Eyck * \c *policy is unchanged. 1048b0563631STom Van Eyck */ 1049b0563631STom Van Eyck static psa_status_t psa_restrict_key_policy( 1050b0563631STom Van Eyck psa_key_type_t key_type, 1051b0563631STom Van Eyck psa_key_policy_t *policy, 1052b0563631STom Van Eyck const psa_key_policy_t *constraint) 1053b0563631STom Van Eyck { 1054b0563631STom Van Eyck psa_algorithm_t intersection_alg = 1055b0563631STom Van Eyck psa_key_policy_algorithm_intersection(key_type, policy->alg, 1056b0563631STom Van Eyck constraint->alg); 1057b0563631STom Van Eyck psa_algorithm_t intersection_alg2 = 1058b0563631STom Van Eyck psa_key_policy_algorithm_intersection(key_type, policy->alg2, 1059b0563631STom Van Eyck constraint->alg2); 1060b0563631STom Van Eyck if (intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0) { 1061b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 1062b0563631STom Van Eyck } 1063b0563631STom Van Eyck if (intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0) { 1064b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 1065b0563631STom Van Eyck } 1066b0563631STom Van Eyck policy->usage &= constraint->usage; 1067b0563631STom Van Eyck policy->alg = intersection_alg; 1068b0563631STom Van Eyck policy->alg2 = intersection_alg2; 1069b0563631STom Van Eyck return PSA_SUCCESS; 1070b0563631STom Van Eyck } 1071b0563631STom Van Eyck 1072b0563631STom Van Eyck /** Get the description of a key given its identifier and policy constraints 1073b0563631STom Van Eyck * and lock it. 1074b0563631STom Van Eyck * 1075b0563631STom Van Eyck * The key must have allow all the usage flags set in \p usage. If \p alg is 1076b0563631STom Van Eyck * nonzero, the key must allow operations with this algorithm. If \p alg is 1077b0563631STom Van Eyck * zero, the algorithm is not checked. 1078b0563631STom Van Eyck * 1079b0563631STom Van Eyck * In case of a persistent key, the function loads the description of the key 1080b0563631STom Van Eyck * into a key slot if not already done. 1081b0563631STom Van Eyck * 1082b0563631STom Van Eyck * On success, the returned key slot has been registered for reading. 1083b0563631STom Van Eyck * It is the responsibility of the caller to then unregister 1084b0563631STom Van Eyck * once they have finished reading the contents of the slot. 1085b0563631STom Van Eyck * The caller unregisters by calling psa_unregister_read() or 1086b0563631STom Van Eyck * psa_unregister_read_under_mutex(). psa_unregister_read() must be called 1087b0563631STom Van Eyck * if and only if the caller already holds the global key slot mutex 1088b0563631STom Van Eyck * (when mutexes are enabled). psa_unregister_read_under_mutex() encapsulates 1089b0563631STom Van Eyck * the unregister with mutex lock and unlock operations. 1090b0563631STom Van Eyck */ 1091b0563631STom Van Eyck static psa_status_t psa_get_and_lock_key_slot_with_policy( 1092b0563631STom Van Eyck mbedtls_svc_key_id_t key, 1093b0563631STom Van Eyck psa_key_slot_t **p_slot, 1094b0563631STom Van Eyck psa_key_usage_t usage, 1095b0563631STom Van Eyck psa_algorithm_t alg) 1096b0563631STom Van Eyck { 1097b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 1098b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 1099b0563631STom Van Eyck 1100b0563631STom Van Eyck status = psa_get_and_lock_key_slot(key, p_slot); 1101b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1102b0563631STom Van Eyck return status; 1103b0563631STom Van Eyck } 1104b0563631STom Van Eyck slot = *p_slot; 1105b0563631STom Van Eyck 1106b0563631STom Van Eyck /* Enforce that usage policy for the key slot contains all the flags 1107b0563631STom Van Eyck * required by the usage parameter. There is one exception: public 1108b0563631STom Van Eyck * keys can always be exported, so we treat public key objects as 1109b0563631STom Van Eyck * if they had the export flag. */ 1110b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type)) { 1111b0563631STom Van Eyck usage &= ~PSA_KEY_USAGE_EXPORT; 1112b0563631STom Van Eyck } 1113b0563631STom Van Eyck 1114b0563631STom Van Eyck if ((slot->attr.policy.usage & usage) != usage) { 1115b0563631STom Van Eyck status = PSA_ERROR_NOT_PERMITTED; 1116b0563631STom Van Eyck goto error; 1117b0563631STom Van Eyck } 1118b0563631STom Van Eyck 1119b0563631STom Van Eyck /* Enforce that the usage policy permits the requested algorithm. */ 1120b0563631STom Van Eyck if (alg != 0) { 1121b0563631STom Van Eyck status = psa_key_policy_permits(&slot->attr.policy, 1122b0563631STom Van Eyck slot->attr.type, 1123b0563631STom Van Eyck alg); 1124b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1125b0563631STom Van Eyck goto error; 1126b0563631STom Van Eyck } 1127b0563631STom Van Eyck } 1128b0563631STom Van Eyck 1129b0563631STom Van Eyck return PSA_SUCCESS; 1130b0563631STom Van Eyck 1131b0563631STom Van Eyck error: 1132b0563631STom Van Eyck *p_slot = NULL; 1133b0563631STom Van Eyck psa_unregister_read_under_mutex(slot); 1134b0563631STom Van Eyck 1135b0563631STom Van Eyck return status; 1136b0563631STom Van Eyck } 1137b0563631STom Van Eyck 1138b0563631STom Van Eyck /** Get a key slot containing a transparent key and lock it. 1139b0563631STom Van Eyck * 1140b0563631STom Van Eyck * A transparent key is a key for which the key material is directly 1141b0563631STom Van Eyck * available, as opposed to a key in a secure element and/or to be used 1142b0563631STom Van Eyck * by a secure element. 1143b0563631STom Van Eyck * 1144b0563631STom Van Eyck * This is a temporary function that may be used instead of 1145b0563631STom Van Eyck * psa_get_and_lock_key_slot_with_policy() when there is no opaque key support 1146b0563631STom Van Eyck * for a cryptographic operation. 1147b0563631STom Van Eyck * 1148b0563631STom Van Eyck * On success, the returned key slot has been registered for reading. 1149b0563631STom Van Eyck * It is the responsibility of the caller to then unregister 1150b0563631STom Van Eyck * once they have finished reading the contents of the slot. 1151b0563631STom Van Eyck * The caller unregisters by calling psa_unregister_read() or 1152b0563631STom Van Eyck * psa_unregister_read_under_mutex(). psa_unregister_read() must be called 1153b0563631STom Van Eyck * if and only if the caller already holds the global key slot mutex 1154b0563631STom Van Eyck * (when mutexes are enabled). psa_unregister_read_under_mutex() encapsulates 1155b0563631STom Van Eyck * psa_unregister_read() with mutex lock and unlock operations. 1156b0563631STom Van Eyck */ 1157b0563631STom Van Eyck static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy( 1158b0563631STom Van Eyck mbedtls_svc_key_id_t key, 1159b0563631STom Van Eyck psa_key_slot_t **p_slot, 1160b0563631STom Van Eyck psa_key_usage_t usage, 1161b0563631STom Van Eyck psa_algorithm_t alg) 1162b0563631STom Van Eyck { 1163b0563631STom Van Eyck psa_status_t status = psa_get_and_lock_key_slot_with_policy(key, p_slot, 1164b0563631STom Van Eyck usage, alg); 1165b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1166b0563631STom Van Eyck return status; 1167b0563631STom Van Eyck } 1168b0563631STom Van Eyck 1169b0563631STom Van Eyck if (psa_key_lifetime_is_external((*p_slot)->attr.lifetime)) { 1170b0563631STom Van Eyck psa_unregister_read_under_mutex(*p_slot); 1171b0563631STom Van Eyck *p_slot = NULL; 1172b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 1173b0563631STom Van Eyck } 1174b0563631STom Van Eyck 1175b0563631STom Van Eyck return PSA_SUCCESS; 1176b0563631STom Van Eyck } 1177b0563631STom Van Eyck 1178b0563631STom Van Eyck psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot) 1179b0563631STom Van Eyck { 1180b0563631STom Van Eyck if (slot->key.data != NULL) { 1181b0563631STom Van Eyck mbedtls_zeroize_and_free(slot->key.data, slot->key.bytes); 1182b0563631STom Van Eyck } 1183b0563631STom Van Eyck 1184b0563631STom Van Eyck slot->key.data = NULL; 1185b0563631STom Van Eyck slot->key.bytes = 0; 1186b0563631STom Van Eyck 1187b0563631STom Van Eyck return PSA_SUCCESS; 1188b0563631STom Van Eyck } 1189b0563631STom Van Eyck 1190b0563631STom Van Eyck /** Completely wipe a slot in memory, including its policy. 1191b0563631STom Van Eyck * Persistent storage is not affected. */ 1192b0563631STom Van Eyck psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot) 1193b0563631STom Van Eyck { 1194b0563631STom Van Eyck psa_status_t status = psa_remove_key_data_from_memory(slot); 1195b0563631STom Van Eyck 1196b0563631STom Van Eyck /* 1197b0563631STom Van Eyck * As the return error code may not be handled in case of multiple errors, 1198b0563631STom Van Eyck * do our best to report an unexpected amount of registered readers or 1199b0563631STom Van Eyck * an unexpected state. 1200b0563631STom Van Eyck * Assert with MBEDTLS_TEST_HOOK_TEST_ASSERT that the slot is valid for 1201b0563631STom Van Eyck * wiping. 1202b0563631STom Van Eyck * if the MBEDTLS_TEST_HOOKS configuration option is enabled and the 1203b0563631STom Van Eyck * function is called as part of the execution of a test suite, the 1204b0563631STom Van Eyck * execution of the test suite is stopped in error if the assertion fails. 1205b0563631STom Van Eyck */ 1206b0563631STom Van Eyck switch (slot->state) { 1207b0563631STom Van Eyck case PSA_SLOT_FULL: 1208b0563631STom Van Eyck /* In this state psa_wipe_key_slot() must only be called if the 1209b0563631STom Van Eyck * caller is the last reader. */ 1210b0563631STom Van Eyck case PSA_SLOT_PENDING_DELETION: 1211b0563631STom Van Eyck /* In this state psa_wipe_key_slot() must only be called if the 1212b0563631STom Van Eyck * caller is the last reader. */ 1213*cb034002SJerome Forissier if (slot->var.occupied.registered_readers != 1) { 1214*cb034002SJerome Forissier MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->var.occupied.registered_readers == 1); 1215b0563631STom Van Eyck status = PSA_ERROR_CORRUPTION_DETECTED; 1216b0563631STom Van Eyck } 1217b0563631STom Van Eyck break; 1218b0563631STom Van Eyck case PSA_SLOT_FILLING: 1219b0563631STom Van Eyck /* In this state registered_readers must be 0. */ 1220*cb034002SJerome Forissier if (slot->var.occupied.registered_readers != 0) { 1221*cb034002SJerome Forissier MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->var.occupied.registered_readers == 0); 1222b0563631STom Van Eyck status = PSA_ERROR_CORRUPTION_DETECTED; 1223b0563631STom Van Eyck } 1224b0563631STom Van Eyck break; 1225b0563631STom Van Eyck case PSA_SLOT_EMPTY: 1226b0563631STom Van Eyck /* The slot is already empty, it cannot be wiped. */ 1227b0563631STom Van Eyck MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->state != PSA_SLOT_EMPTY); 1228b0563631STom Van Eyck status = PSA_ERROR_CORRUPTION_DETECTED; 1229b0563631STom Van Eyck break; 1230b0563631STom Van Eyck default: 1231b0563631STom Van Eyck /* The slot's state is invalid. */ 1232b0563631STom Van Eyck status = PSA_ERROR_CORRUPTION_DETECTED; 1233b0563631STom Van Eyck } 1234b0563631STom Van Eyck 1235*cb034002SJerome Forissier #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) 1236*cb034002SJerome Forissier size_t slice_index = slot->slice_index; 1237*cb034002SJerome Forissier #endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ 1238*cb034002SJerome Forissier 1239*cb034002SJerome Forissier 1240b0563631STom Van Eyck /* Multipart operations may still be using the key. This is safe 1241b0563631STom Van Eyck * because all multipart operation objects are independent from 1242b0563631STom Van Eyck * the key slot: if they need to access the key after the setup 1243b0563631STom Van Eyck * phase, they have a copy of the key. Note that this means that 1244b0563631STom Van Eyck * key material can linger until all operations are completed. */ 1245b0563631STom Van Eyck /* At this point, key material and other type-specific content has 1246b0563631STom Van Eyck * been wiped. Clear remaining metadata. We can call memset and not 1247b0563631STom Van Eyck * zeroize because the metadata is not particularly sensitive. 1248b0563631STom Van Eyck * This memset also sets the slot's state to PSA_SLOT_EMPTY. */ 1249b0563631STom Van Eyck memset(slot, 0, sizeof(*slot)); 1250*cb034002SJerome Forissier 1251*cb034002SJerome Forissier #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) 1252*cb034002SJerome Forissier /* If the slot is already corrupted, something went deeply wrong, 1253*cb034002SJerome Forissier * like a thread still using the slot or a stray pointer leading 1254*cb034002SJerome Forissier * to the slot's memory being used for another object. Let the slot 1255*cb034002SJerome Forissier * leak rather than make the corruption worse. */ 1256*cb034002SJerome Forissier if (status == PSA_SUCCESS) { 1257*cb034002SJerome Forissier status = psa_free_key_slot(slice_index, slot); 1258*cb034002SJerome Forissier } 1259*cb034002SJerome Forissier #endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ 1260*cb034002SJerome Forissier 1261b0563631STom Van Eyck return status; 1262b0563631STom Van Eyck } 1263b0563631STom Van Eyck 1264b0563631STom Van Eyck psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key) 1265b0563631STom Van Eyck { 1266b0563631STom Van Eyck psa_key_slot_t *slot; 1267b0563631STom Van Eyck psa_status_t status; /* status of the last operation */ 1268b0563631STom Van Eyck psa_status_t overall_status = PSA_SUCCESS; 1269b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 1270b0563631STom Van Eyck psa_se_drv_table_entry_t *driver; 1271b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 1272b0563631STom Van Eyck 1273b0563631STom Van Eyck if (mbedtls_svc_key_id_is_null(key)) { 1274b0563631STom Van Eyck return PSA_SUCCESS; 1275b0563631STom Van Eyck } 1276b0563631STom Van Eyck 1277b0563631STom Van Eyck /* 1278b0563631STom Van Eyck * Get the description of the key in a key slot, and register to read it. 1279b0563631STom Van Eyck * In the case of a persistent key, this will load the key description 1280b0563631STom Van Eyck * from persistent memory if not done yet. 1281b0563631STom Van Eyck * We cannot avoid this loading as without it we don't know if 1282b0563631STom Van Eyck * the key is operated by an SE or not and this information is needed by 1283b0563631STom Van Eyck * the current implementation. */ 1284b0563631STom Van Eyck status = psa_get_and_lock_key_slot(key, &slot); 1285b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1286b0563631STom Van Eyck return status; 1287b0563631STom Van Eyck } 1288b0563631STom Van Eyck 1289b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 1290b0563631STom Van Eyck /* We cannot unlock between setting the state to PENDING_DELETION 1291b0563631STom Van Eyck * and destroying the key in storage, as otherwise another thread 1292b0563631STom Van Eyck * could load the key into a new slot and the key will not be 1293b0563631STom Van Eyck * fully destroyed. */ 1294b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock( 1295b0563631STom Van Eyck &mbedtls_threading_key_slot_mutex)); 1296b0563631STom Van Eyck 1297b0563631STom Van Eyck if (slot->state == PSA_SLOT_PENDING_DELETION) { 1298b0563631STom Van Eyck /* Another thread has destroyed the key between us locking the slot 1299b0563631STom Van Eyck * and us gaining the mutex. Unregister from the slot, 1300b0563631STom Van Eyck * and report that the key does not exist. */ 1301b0563631STom Van Eyck status = psa_unregister_read(slot); 1302b0563631STom Van Eyck 1303b0563631STom Van Eyck PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( 1304b0563631STom Van Eyck &mbedtls_threading_key_slot_mutex)); 1305b0563631STom Van Eyck return (status == PSA_SUCCESS) ? PSA_ERROR_INVALID_HANDLE : status; 1306b0563631STom Van Eyck } 1307b0563631STom Van Eyck #endif 1308b0563631STom Van Eyck /* Set the key slot containing the key description's state to 1309b0563631STom Van Eyck * PENDING_DELETION. This stops new operations from registering 1310b0563631STom Van Eyck * to read the slot. Current readers can safely continue to access 1311b0563631STom Van Eyck * the key within the slot; the last registered reader will 1312b0563631STom Van Eyck * automatically wipe the slot when they call psa_unregister_read(). 1313b0563631STom Van Eyck * If the key is persistent, we can now delete the copy of the key 1314b0563631STom Van Eyck * from memory. If the key is opaque, we require the driver to 1315b0563631STom Van Eyck * deal with the deletion. */ 1316b0563631STom Van Eyck overall_status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL, 1317b0563631STom Van Eyck PSA_SLOT_PENDING_DELETION); 1318b0563631STom Van Eyck 1319b0563631STom Van Eyck if (overall_status != PSA_SUCCESS) { 1320b0563631STom Van Eyck goto exit; 1321b0563631STom Van Eyck } 1322b0563631STom Van Eyck 1323b0563631STom Van Eyck if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) { 1324b0563631STom Van Eyck /* Refuse the destruction of a read-only key (which may or may not work 1325b0563631STom Van Eyck * if we attempt it, depending on whether the key is merely read-only 1326b0563631STom Van Eyck * by policy or actually physically read-only). 1327b0563631STom Van Eyck * Just do the best we can, which is to wipe the copy in memory 1328b0563631STom Van Eyck * (done in this function's cleanup code). */ 1329b0563631STom Van Eyck overall_status = PSA_ERROR_NOT_PERMITTED; 1330b0563631STom Van Eyck goto exit; 1331b0563631STom Van Eyck } 1332b0563631STom Van Eyck 1333b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 1334b0563631STom Van Eyck driver = psa_get_se_driver_entry(slot->attr.lifetime); 1335b0563631STom Van Eyck if (driver != NULL) { 1336b0563631STom Van Eyck /* For a key in a secure element, we need to do three things: 1337b0563631STom Van Eyck * remove the key file in internal storage, destroy the 1338b0563631STom Van Eyck * key inside the secure element, and update the driver's 1339b0563631STom Van Eyck * persistent data. Start a transaction that will encompass these 1340b0563631STom Van Eyck * three actions. */ 1341b0563631STom Van Eyck psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_DESTROY_KEY); 1342b0563631STom Van Eyck psa_crypto_transaction.key.lifetime = slot->attr.lifetime; 1343b0563631STom Van Eyck psa_crypto_transaction.key.slot = psa_key_slot_get_slot_number(slot); 1344b0563631STom Van Eyck psa_crypto_transaction.key.id = slot->attr.id; 1345b0563631STom Van Eyck status = psa_crypto_save_transaction(); 1346b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1347b0563631STom Van Eyck (void) psa_crypto_stop_transaction(); 1348b0563631STom Van Eyck /* We should still try to destroy the key in the secure 1349b0563631STom Van Eyck * element and the key metadata in storage. This is especially 1350b0563631STom Van Eyck * important if the error is that the storage is full. 1351b0563631STom Van Eyck * But how to do it exactly without risking an inconsistent 1352b0563631STom Van Eyck * state after a reset? 1353b0563631STom Van Eyck * https://github.com/ARMmbed/mbed-crypto/issues/215 1354b0563631STom Van Eyck */ 1355b0563631STom Van Eyck overall_status = status; 1356b0563631STom Van Eyck goto exit; 1357b0563631STom Van Eyck } 1358b0563631STom Van Eyck 1359b0563631STom Van Eyck status = psa_destroy_se_key(driver, 1360b0563631STom Van Eyck psa_key_slot_get_slot_number(slot)); 1361b0563631STom Van Eyck if (overall_status == PSA_SUCCESS) { 1362b0563631STom Van Eyck overall_status = status; 1363b0563631STom Van Eyck } 1364b0563631STom Van Eyck } 1365b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 1366b0563631STom Van Eyck 1367b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) 1368b0563631STom Van Eyck if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { 1369b0563631STom Van Eyck /* Destroy the copy of the persistent key from storage. 1370b0563631STom Van Eyck * The slot will still hold a copy of the key until the last reader 1371b0563631STom Van Eyck * unregisters. */ 1372b0563631STom Van Eyck status = psa_destroy_persistent_key(slot->attr.id); 1373b0563631STom Van Eyck if (overall_status == PSA_SUCCESS) { 1374b0563631STom Van Eyck overall_status = status; 1375b0563631STom Van Eyck } 1376b0563631STom Van Eyck } 1377b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ 1378b0563631STom Van Eyck 1379b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 1380b0563631STom Van Eyck if (driver != NULL) { 1381b0563631STom Van Eyck status = psa_save_se_persistent_data(driver); 1382b0563631STom Van Eyck if (overall_status == PSA_SUCCESS) { 1383b0563631STom Van Eyck overall_status = status; 1384b0563631STom Van Eyck } 1385b0563631STom Van Eyck status = psa_crypto_stop_transaction(); 1386b0563631STom Van Eyck if (overall_status == PSA_SUCCESS) { 1387b0563631STom Van Eyck overall_status = status; 1388b0563631STom Van Eyck } 1389b0563631STom Van Eyck } 1390b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 1391b0563631STom Van Eyck 1392b0563631STom Van Eyck exit: 1393b0563631STom Van Eyck /* Unregister from reading the slot. If we are the last active reader 1394b0563631STom Van Eyck * then this will wipe the slot. */ 1395b0563631STom Van Eyck status = psa_unregister_read(slot); 1396b0563631STom Van Eyck /* Prioritize CORRUPTION_DETECTED from unregistering over 1397b0563631STom Van Eyck * a storage error. */ 1398b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1399b0563631STom Van Eyck overall_status = status; 1400b0563631STom Van Eyck } 1401b0563631STom Van Eyck 1402b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 1403b0563631STom Van Eyck /* Don't overwrite existing errors if the unlock fails. */ 1404b0563631STom Van Eyck status = overall_status; 1405b0563631STom Van Eyck PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( 1406b0563631STom Van Eyck &mbedtls_threading_key_slot_mutex)); 1407b0563631STom Van Eyck #endif 1408b0563631STom Van Eyck 1409b0563631STom Van Eyck return overall_status; 1410b0563631STom Van Eyck } 1411b0563631STom Van Eyck 1412b0563631STom Van Eyck /** Retrieve all the publicly-accessible attributes of a key. 1413b0563631STom Van Eyck */ 1414b0563631STom Van Eyck psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, 1415b0563631STom Van Eyck psa_key_attributes_t *attributes) 1416b0563631STom Van Eyck { 1417b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 1418b0563631STom Van Eyck psa_key_slot_t *slot; 1419b0563631STom Van Eyck 1420b0563631STom Van Eyck psa_reset_key_attributes(attributes); 1421b0563631STom Van Eyck 1422b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy(key, &slot, 0, 0); 1423b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1424b0563631STom Van Eyck return status; 1425b0563631STom Van Eyck } 1426b0563631STom Van Eyck 1427b0563631STom Van Eyck *attributes = slot->attr; 1428b0563631STom Van Eyck 1429b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 1430b0563631STom Van Eyck if (psa_get_se_driver_entry(slot->attr.lifetime) != NULL) { 1431b0563631STom Van Eyck psa_set_key_slot_number(attributes, 1432b0563631STom Van Eyck psa_key_slot_get_slot_number(slot)); 1433b0563631STom Van Eyck } 1434b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 1435b0563631STom Van Eyck 1436b0563631STom Van Eyck return psa_unregister_read_under_mutex(slot); 1437b0563631STom Van Eyck } 1438b0563631STom Van Eyck 1439b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 1440b0563631STom Van Eyck psa_status_t psa_get_key_slot_number( 1441b0563631STom Van Eyck const psa_key_attributes_t *attributes, 1442b0563631STom Van Eyck psa_key_slot_number_t *slot_number) 1443b0563631STom Van Eyck { 1444b0563631STom Van Eyck if (attributes->has_slot_number) { 1445b0563631STom Van Eyck *slot_number = attributes->slot_number; 1446b0563631STom Van Eyck return PSA_SUCCESS; 1447b0563631STom Van Eyck } else { 1448b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 1449b0563631STom Van Eyck } 1450b0563631STom Van Eyck } 1451b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 1452b0563631STom Van Eyck 1453b0563631STom Van Eyck static psa_status_t psa_export_key_buffer_internal(const uint8_t *key_buffer, 1454b0563631STom Van Eyck size_t key_buffer_size, 1455b0563631STom Van Eyck uint8_t *data, 1456b0563631STom Van Eyck size_t data_size, 1457b0563631STom Van Eyck size_t *data_length) 1458b0563631STom Van Eyck { 1459b0563631STom Van Eyck if (key_buffer_size > data_size) { 1460b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 1461b0563631STom Van Eyck } 1462b0563631STom Van Eyck memcpy(data, key_buffer, key_buffer_size); 1463b0563631STom Van Eyck memset(data + key_buffer_size, 0, 1464b0563631STom Van Eyck data_size - key_buffer_size); 1465b0563631STom Van Eyck *data_length = key_buffer_size; 1466b0563631STom Van Eyck return PSA_SUCCESS; 1467b0563631STom Van Eyck } 1468b0563631STom Van Eyck 1469b0563631STom Van Eyck psa_status_t psa_export_key_internal( 1470b0563631STom Van Eyck const psa_key_attributes_t *attributes, 1471b0563631STom Van Eyck const uint8_t *key_buffer, size_t key_buffer_size, 1472b0563631STom Van Eyck uint8_t *data, size_t data_size, size_t *data_length) 1473b0563631STom Van Eyck { 1474b0563631STom Van Eyck psa_key_type_t type = attributes->type; 1475b0563631STom Van Eyck 1476b0563631STom Van Eyck if (key_type_is_raw_bytes(type) || 1477b0563631STom Van Eyck PSA_KEY_TYPE_IS_RSA(type) || 1478b0563631STom Van Eyck PSA_KEY_TYPE_IS_ECC(type) || 1479b0563631STom Van Eyck PSA_KEY_TYPE_IS_DH(type)) { 1480b0563631STom Van Eyck return psa_export_key_buffer_internal( 1481b0563631STom Van Eyck key_buffer, key_buffer_size, 1482b0563631STom Van Eyck data, data_size, data_length); 1483b0563631STom Van Eyck } else { 1484b0563631STom Van Eyck /* This shouldn't happen in the reference implementation, but 1485b0563631STom Van Eyck it is valid for a special-purpose implementation to omit 1486b0563631STom Van Eyck support for exporting certain key types. */ 1487b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 1488b0563631STom Van Eyck } 1489b0563631STom Van Eyck } 1490b0563631STom Van Eyck 1491b0563631STom Van Eyck psa_status_t psa_export_key(mbedtls_svc_key_id_t key, 1492b0563631STom Van Eyck uint8_t *data_external, 1493b0563631STom Van Eyck size_t data_size, 1494b0563631STom Van Eyck size_t *data_length) 1495b0563631STom Van Eyck { 1496b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 1497b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 1498b0563631STom Van Eyck psa_key_slot_t *slot; 1499b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(data_external, data); 1500b0563631STom Van Eyck 1501b0563631STom Van Eyck /* Reject a zero-length output buffer now, since this can never be a 1502b0563631STom Van Eyck * valid key representation. This way we know that data must be a valid 1503b0563631STom Van Eyck * pointer and we can do things like memset(data, ..., data_size). */ 1504b0563631STom Van Eyck if (data_size == 0) { 1505b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 1506b0563631STom Van Eyck } 1507b0563631STom Van Eyck 1508b0563631STom Van Eyck /* Set the key to empty now, so that even when there are errors, we always 1509b0563631STom Van Eyck * set data_length to a value between 0 and data_size. On error, setting 1510b0563631STom Van Eyck * the key to empty is a good choice because an empty key representation is 1511b0563631STom Van Eyck * unlikely to be accepted anywhere. */ 1512b0563631STom Van Eyck *data_length = 0; 1513b0563631STom Van Eyck 1514b0563631STom Van Eyck /* Export requires the EXPORT flag. There is an exception for public keys, 1515b0563631STom Van Eyck * which don't require any flag, but 1516b0563631STom Van Eyck * psa_get_and_lock_key_slot_with_policy() takes care of this. 1517b0563631STom Van Eyck */ 1518b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy(key, &slot, 1519b0563631STom Van Eyck PSA_KEY_USAGE_EXPORT, 0); 1520b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1521b0563631STom Van Eyck return status; 1522b0563631STom Van Eyck } 1523b0563631STom Van Eyck 1524b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(data_external, data_size, data); 1525b0563631STom Van Eyck 1526b0563631STom Van Eyck status = psa_driver_wrapper_export_key(&slot->attr, 1527b0563631STom Van Eyck slot->key.data, slot->key.bytes, 1528b0563631STom Van Eyck data, data_size, data_length); 1529b0563631STom Van Eyck 1530b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 1531b0563631STom Van Eyck exit: 1532b0563631STom Van Eyck #endif 1533b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 1534b0563631STom Van Eyck 1535b0563631STom Van Eyck LOCAL_OUTPUT_FREE(data_external, data); 1536b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 1537b0563631STom Van Eyck } 1538b0563631STom Van Eyck 1539b0563631STom Van Eyck psa_status_t psa_export_public_key_internal( 1540b0563631STom Van Eyck const psa_key_attributes_t *attributes, 1541b0563631STom Van Eyck const uint8_t *key_buffer, 1542b0563631STom Van Eyck size_t key_buffer_size, 1543b0563631STom Van Eyck uint8_t *data, 1544b0563631STom Van Eyck size_t data_size, 1545b0563631STom Van Eyck size_t *data_length) 1546b0563631STom Van Eyck { 1547b0563631STom Van Eyck psa_key_type_t type = attributes->type; 1548b0563631STom Van Eyck 1549b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) && 1550b0563631STom Van Eyck (PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type) || 1551b0563631STom Van Eyck PSA_KEY_TYPE_IS_DH(type))) { 1552b0563631STom Van Eyck /* Exporting public -> public */ 1553b0563631STom Van Eyck return psa_export_key_buffer_internal( 1554b0563631STom Van Eyck key_buffer, key_buffer_size, 1555b0563631STom Van Eyck data, data_size, data_length); 1556b0563631STom Van Eyck } else if (PSA_KEY_TYPE_IS_RSA(type)) { 1557b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \ 1558b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) 1559b0563631STom Van Eyck return mbedtls_psa_rsa_export_public_key(attributes, 1560b0563631STom Van Eyck key_buffer, 1561b0563631STom Van Eyck key_buffer_size, 1562b0563631STom Van Eyck data, 1563b0563631STom Van Eyck data_size, 1564b0563631STom Van Eyck data_length); 1565b0563631STom Van Eyck #else 1566b0563631STom Van Eyck /* We don't know how to convert a private RSA key to public. */ 1567b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 1568b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || 1569b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ 1570b0563631STom Van Eyck } else if (PSA_KEY_TYPE_IS_ECC(type)) { 1571b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ 1572b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) 1573b0563631STom Van Eyck return mbedtls_psa_ecp_export_public_key(attributes, 1574b0563631STom Van Eyck key_buffer, 1575b0563631STom Van Eyck key_buffer_size, 1576b0563631STom Van Eyck data, 1577b0563631STom Van Eyck data_size, 1578b0563631STom Van Eyck data_length); 1579b0563631STom Van Eyck #else 1580b0563631STom Van Eyck /* We don't know how to convert a private ECC key to public */ 1581b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 1582b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || 1583b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ 1584b0563631STom Van Eyck } else if (PSA_KEY_TYPE_IS_DH(type)) { 1585b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \ 1586b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) 1587b0563631STom Van Eyck return mbedtls_psa_ffdh_export_public_key(attributes, 1588b0563631STom Van Eyck key_buffer, 1589b0563631STom Van Eyck key_buffer_size, 1590b0563631STom Van Eyck data, data_size, 1591b0563631STom Van Eyck data_length); 1592b0563631STom Van Eyck #else 1593b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 1594b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || 1595b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */ 1596b0563631STom Van Eyck } else { 1597b0563631STom Van Eyck (void) key_buffer; 1598b0563631STom Van Eyck (void) key_buffer_size; 1599b0563631STom Van Eyck (void) data; 1600b0563631STom Van Eyck (void) data_size; 1601b0563631STom Van Eyck (void) data_length; 1602b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 1603b0563631STom Van Eyck } 1604b0563631STom Van Eyck } 1605b0563631STom Van Eyck 1606b0563631STom Van Eyck psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, 1607b0563631STom Van Eyck uint8_t *data_external, 1608b0563631STom Van Eyck size_t data_size, 1609b0563631STom Van Eyck size_t *data_length) 1610b0563631STom Van Eyck { 1611b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 1612b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 1613b0563631STom Van Eyck psa_key_slot_t *slot; 1614b0563631STom Van Eyck 1615b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(data_external, data); 1616b0563631STom Van Eyck 1617b0563631STom Van Eyck /* Reject a zero-length output buffer now, since this can never be a 1618b0563631STom Van Eyck * valid key representation. This way we know that data must be a valid 1619b0563631STom Van Eyck * pointer and we can do things like memset(data, ..., data_size). */ 1620b0563631STom Van Eyck if (data_size == 0) { 1621b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 1622b0563631STom Van Eyck } 1623b0563631STom Van Eyck 1624b0563631STom Van Eyck /* Set the key to empty now, so that even when there are errors, we always 1625b0563631STom Van Eyck * set data_length to a value between 0 and data_size. On error, setting 1626b0563631STom Van Eyck * the key to empty is a good choice because an empty key representation is 1627b0563631STom Van Eyck * unlikely to be accepted anywhere. */ 1628b0563631STom Van Eyck *data_length = 0; 1629b0563631STom Van Eyck 1630b0563631STom Van Eyck /* Exporting a public key doesn't require a usage flag. */ 1631b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy(key, &slot, 0, 0); 1632b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1633b0563631STom Van Eyck return status; 1634b0563631STom Van Eyck } 1635b0563631STom Van Eyck 1636b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(data_external, data_size, data); 1637b0563631STom Van Eyck 1638b0563631STom Van Eyck if (!PSA_KEY_TYPE_IS_ASYMMETRIC(slot->attr.type)) { 1639b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 1640b0563631STom Van Eyck goto exit; 1641b0563631STom Van Eyck } 1642b0563631STom Van Eyck 1643b0563631STom Van Eyck status = psa_driver_wrapper_export_public_key( 1644b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 1645b0563631STom Van Eyck data, data_size, data_length); 1646b0563631STom Van Eyck 1647b0563631STom Van Eyck exit: 1648b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 1649b0563631STom Van Eyck 1650b0563631STom Van Eyck LOCAL_OUTPUT_FREE(data_external, data); 1651b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 1652b0563631STom Van Eyck } 1653b0563631STom Van Eyck 1654b0563631STom Van Eyck /** Validate that a key policy is internally well-formed. 1655b0563631STom Van Eyck * 1656b0563631STom Van Eyck * This function only rejects invalid policies. It does not validate the 1657b0563631STom Van Eyck * consistency of the policy with respect to other attributes of the key 1658b0563631STom Van Eyck * such as the key type. 1659b0563631STom Van Eyck */ 1660b0563631STom Van Eyck static psa_status_t psa_validate_key_policy(const psa_key_policy_t *policy) 1661b0563631STom Van Eyck { 1662b0563631STom Van Eyck if ((policy->usage & ~(PSA_KEY_USAGE_EXPORT | 1663b0563631STom Van Eyck PSA_KEY_USAGE_COPY | 1664b0563631STom Van Eyck PSA_KEY_USAGE_ENCRYPT | 1665b0563631STom Van Eyck PSA_KEY_USAGE_DECRYPT | 1666b0563631STom Van Eyck PSA_KEY_USAGE_SIGN_MESSAGE | 1667b0563631STom Van Eyck PSA_KEY_USAGE_VERIFY_MESSAGE | 1668b0563631STom Van Eyck PSA_KEY_USAGE_SIGN_HASH | 1669b0563631STom Van Eyck PSA_KEY_USAGE_VERIFY_HASH | 1670b0563631STom Van Eyck PSA_KEY_USAGE_VERIFY_DERIVATION | 1671b0563631STom Van Eyck PSA_KEY_USAGE_DERIVE)) != 0) { 1672b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 1673b0563631STom Van Eyck } 1674b0563631STom Van Eyck 1675b0563631STom Van Eyck return PSA_SUCCESS; 1676b0563631STom Van Eyck } 1677b0563631STom Van Eyck 1678b0563631STom Van Eyck /** Validate the internal consistency of key attributes. 1679b0563631STom Van Eyck * 1680b0563631STom Van Eyck * This function only rejects invalid attribute values. If does not 1681b0563631STom Van Eyck * validate the consistency of the attributes with any key data that may 1682b0563631STom Van Eyck * be involved in the creation of the key. 1683b0563631STom Van Eyck * 1684b0563631STom Van Eyck * Call this function early in the key creation process. 1685b0563631STom Van Eyck * 1686b0563631STom Van Eyck * \param[in] attributes Key attributes for the new key. 1687b0563631STom Van Eyck * \param[out] p_drv On any return, the driver for the key, if any. 1688b0563631STom Van Eyck * NULL for a transparent key. 1689b0563631STom Van Eyck * 1690b0563631STom Van Eyck */ 1691b0563631STom Van Eyck static psa_status_t psa_validate_key_attributes( 1692b0563631STom Van Eyck const psa_key_attributes_t *attributes, 1693b0563631STom Van Eyck psa_se_drv_table_entry_t **p_drv) 1694b0563631STom Van Eyck { 1695b0563631STom Van Eyck psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; 1696b0563631STom Van Eyck psa_key_lifetime_t lifetime = psa_get_key_lifetime(attributes); 1697b0563631STom Van Eyck mbedtls_svc_key_id_t key = psa_get_key_id(attributes); 1698b0563631STom Van Eyck 1699b0563631STom Van Eyck status = psa_validate_key_location(lifetime, p_drv); 1700b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1701b0563631STom Van Eyck return status; 1702b0563631STom Van Eyck } 1703b0563631STom Van Eyck 1704b0563631STom Van Eyck status = psa_validate_key_persistence(lifetime); 1705b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1706b0563631STom Van Eyck return status; 1707b0563631STom Van Eyck } 1708b0563631STom Van Eyck 1709b0563631STom Van Eyck if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) { 1710b0563631STom Van Eyck if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key) != 0) { 1711b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 1712b0563631STom Van Eyck } 1713b0563631STom Van Eyck } else { 1714b0563631STom Van Eyck if (!psa_is_valid_key_id(psa_get_key_id(attributes), 0)) { 1715b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 1716b0563631STom Van Eyck } 1717b0563631STom Van Eyck } 1718b0563631STom Van Eyck 1719b0563631STom Van Eyck status = psa_validate_key_policy(&attributes->policy); 1720b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1721b0563631STom Van Eyck return status; 1722b0563631STom Van Eyck } 1723b0563631STom Van Eyck 1724b0563631STom Van Eyck /* Refuse to create overly large keys. 1725b0563631STom Van Eyck * Note that this doesn't trigger on import if the attributes don't 1726b0563631STom Van Eyck * explicitly specify a size (so psa_get_key_bits returns 0), so 1727b0563631STom Van Eyck * psa_import_key() needs its own checks. */ 1728b0563631STom Van Eyck if (psa_get_key_bits(attributes) > PSA_MAX_KEY_BITS) { 1729b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 1730b0563631STom Van Eyck } 1731b0563631STom Van Eyck 1732b0563631STom Van Eyck return PSA_SUCCESS; 1733b0563631STom Van Eyck } 1734b0563631STom Van Eyck 1735b0563631STom Van Eyck /** Prepare a key slot to receive key material. 1736b0563631STom Van Eyck * 1737b0563631STom Van Eyck * This function allocates a key slot and sets its metadata. 1738b0563631STom Van Eyck * 1739b0563631STom Van Eyck * If this function fails, call psa_fail_key_creation(). 1740b0563631STom Van Eyck * 1741b0563631STom Van Eyck * This function is intended to be used as follows: 1742b0563631STom Van Eyck * -# Call psa_start_key_creation() to allocate a key slot, prepare 1743b0563631STom Van Eyck * it with the specified attributes, and in case of a volatile key assign it 1744b0563631STom Van Eyck * a volatile key identifier. 1745b0563631STom Van Eyck * -# Populate the slot with the key material. 1746b0563631STom Van Eyck * -# Call psa_finish_key_creation() to finalize the creation of the slot. 1747b0563631STom Van Eyck * In case of failure at any step, stop the sequence and call 1748b0563631STom Van Eyck * psa_fail_key_creation(). 1749b0563631STom Van Eyck * 1750b0563631STom Van Eyck * On success, the key slot's state is PSA_SLOT_FILLING. 1751b0563631STom Van Eyck * It is the responsibility of the caller to change the slot's state to 1752b0563631STom Van Eyck * PSA_SLOT_EMPTY/FULL once key creation has finished. 1753b0563631STom Van Eyck * 1754b0563631STom Van Eyck * \param method An identification of the calling function. 1755b0563631STom Van Eyck * \param[in] attributes Key attributes for the new key. 1756b0563631STom Van Eyck * \param[out] p_slot On success, a pointer to the prepared slot. 1757b0563631STom Van Eyck * \param[out] p_drv On any return, the driver for the key, if any. 1758b0563631STom Van Eyck * NULL for a transparent key. 1759b0563631STom Van Eyck * 1760b0563631STom Van Eyck * \retval #PSA_SUCCESS 1761b0563631STom Van Eyck * The key slot is ready to receive key material. 1762b0563631STom Van Eyck * \return If this function fails, the key slot is an invalid state. 1763b0563631STom Van Eyck * You must call psa_fail_key_creation() to wipe and free the slot. 1764b0563631STom Van Eyck */ 1765b0563631STom Van Eyck static psa_status_t psa_start_key_creation( 1766b0563631STom Van Eyck psa_key_creation_method_t method, 1767b0563631STom Van Eyck const psa_key_attributes_t *attributes, 1768b0563631STom Van Eyck psa_key_slot_t **p_slot, 1769b0563631STom Van Eyck psa_se_drv_table_entry_t **p_drv) 1770b0563631STom Van Eyck { 1771b0563631STom Van Eyck psa_status_t status; 1772b0563631STom Van Eyck 1773b0563631STom Van Eyck (void) method; 1774b0563631STom Van Eyck *p_drv = NULL; 1775b0563631STom Van Eyck 1776b0563631STom Van Eyck status = psa_validate_key_attributes(attributes, p_drv); 1777b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1778b0563631STom Van Eyck return status; 1779b0563631STom Van Eyck } 1780b0563631STom Van Eyck 1781*cb034002SJerome Forissier int key_is_volatile = PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime); 1782*cb034002SJerome Forissier psa_key_id_t volatile_key_id; 1783*cb034002SJerome Forissier 1784b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 1785b0563631STom Van Eyck PSA_THREADING_CHK_RET(mbedtls_mutex_lock( 1786b0563631STom Van Eyck &mbedtls_threading_key_slot_mutex)); 1787b0563631STom Van Eyck #endif 1788*cb034002SJerome Forissier status = psa_reserve_free_key_slot( 1789*cb034002SJerome Forissier key_is_volatile ? &volatile_key_id : NULL, 1790*cb034002SJerome Forissier p_slot); 1791b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 1792b0563631STom Van Eyck PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( 1793b0563631STom Van Eyck &mbedtls_threading_key_slot_mutex)); 1794b0563631STom Van Eyck #endif 1795b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1796b0563631STom Van Eyck return status; 1797b0563631STom Van Eyck } 1798*cb034002SJerome Forissier psa_key_slot_t *slot = *p_slot; 1799b0563631STom Van Eyck 1800b0563631STom Van Eyck /* We're storing the declared bit-size of the key. It's up to each 1801b0563631STom Van Eyck * creation mechanism to verify that this information is correct. 1802b0563631STom Van Eyck * It's automatically correct for mechanisms that use the bit-size as 1803b0563631STom Van Eyck * an input (generate, device) but not for those where the bit-size 1804b0563631STom Van Eyck * is optional (import, copy). In case of a volatile key, assign it the 1805b0563631STom Van Eyck * volatile key identifier associated to the slot returned to contain its 1806b0563631STom Van Eyck * definition. */ 1807b0563631STom Van Eyck 1808b0563631STom Van Eyck slot->attr = *attributes; 1809*cb034002SJerome Forissier if (key_is_volatile) { 1810b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) 1811b0563631STom Van Eyck slot->attr.id = volatile_key_id; 1812b0563631STom Van Eyck #else 1813b0563631STom Van Eyck slot->attr.id.key_id = volatile_key_id; 1814b0563631STom Van Eyck #endif 1815b0563631STom Van Eyck } 1816b0563631STom Van Eyck 1817b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 1818b0563631STom Van Eyck /* For a key in a secure element, we need to do three things 1819b0563631STom Van Eyck * when creating or registering a persistent key: 1820b0563631STom Van Eyck * create the key file in internal storage, create the 1821b0563631STom Van Eyck * key inside the secure element, and update the driver's 1822b0563631STom Van Eyck * persistent data. This is done by starting a transaction that will 1823b0563631STom Van Eyck * encompass these three actions. 1824b0563631STom Van Eyck * For registering a volatile key, we just need to find an appropriate 1825b0563631STom Van Eyck * slot number inside the SE. Since the key is designated volatile, creating 1826b0563631STom Van Eyck * a transaction is not required. */ 1827b0563631STom Van Eyck /* The first thing to do is to find a slot number for the new key. 1828b0563631STom Van Eyck * We save the slot number in persistent storage as part of the 1829b0563631STom Van Eyck * transaction data. It will be needed to recover if the power 1830b0563631STom Van Eyck * fails during the key creation process, to clean up on the secure 1831b0563631STom Van Eyck * element side after restarting. Obtaining a slot number from the 1832b0563631STom Van Eyck * secure element driver updates its persistent state, but we do not yet 1833b0563631STom Van Eyck * save the driver's persistent state, so that if the power fails, 1834b0563631STom Van Eyck * we can roll back to a state where the key doesn't exist. */ 1835b0563631STom Van Eyck if (*p_drv != NULL) { 1836b0563631STom Van Eyck psa_key_slot_number_t slot_number; 1837b0563631STom Van Eyck status = psa_find_se_slot_for_key(attributes, method, *p_drv, 1838b0563631STom Van Eyck &slot_number); 1839b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1840b0563631STom Van Eyck return status; 1841b0563631STom Van Eyck } 1842b0563631STom Van Eyck 1843b0563631STom Van Eyck if (!PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime)) { 1844b0563631STom Van Eyck psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_CREATE_KEY); 1845b0563631STom Van Eyck psa_crypto_transaction.key.lifetime = slot->attr.lifetime; 1846b0563631STom Van Eyck psa_crypto_transaction.key.slot = slot_number; 1847b0563631STom Van Eyck psa_crypto_transaction.key.id = slot->attr.id; 1848b0563631STom Van Eyck status = psa_crypto_save_transaction(); 1849b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1850b0563631STom Van Eyck (void) psa_crypto_stop_transaction(); 1851b0563631STom Van Eyck return status; 1852b0563631STom Van Eyck } 1853b0563631STom Van Eyck } 1854b0563631STom Van Eyck 1855b0563631STom Van Eyck status = psa_copy_key_material_into_slot( 1856b0563631STom Van Eyck slot, (uint8_t *) (&slot_number), sizeof(slot_number)); 1857*cb034002SJerome Forissier if (status != PSA_SUCCESS) { 1858*cb034002SJerome Forissier return status; 1859*cb034002SJerome Forissier } 1860b0563631STom Van Eyck } 1861b0563631STom Van Eyck 1862b0563631STom Van Eyck if (*p_drv == NULL && method == PSA_KEY_CREATION_REGISTER) { 1863b0563631STom Van Eyck /* Key registration only makes sense with a secure element. */ 1864b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 1865b0563631STom Van Eyck } 1866b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 1867b0563631STom Van Eyck 1868b0563631STom Van Eyck return PSA_SUCCESS; 1869b0563631STom Van Eyck } 1870b0563631STom Van Eyck 1871b0563631STom Van Eyck /** Finalize the creation of a key once its key material has been set. 1872b0563631STom Van Eyck * 1873b0563631STom Van Eyck * This entails writing the key to persistent storage. 1874b0563631STom Van Eyck * 1875b0563631STom Van Eyck * If this function fails, call psa_fail_key_creation(). 1876b0563631STom Van Eyck * See the documentation of psa_start_key_creation() for the intended use 1877b0563631STom Van Eyck * of this function. 1878b0563631STom Van Eyck * 1879b0563631STom Van Eyck * If the finalization succeeds, the function sets the key slot's state to 1880b0563631STom Van Eyck * PSA_SLOT_FULL, and the key slot can no longer be accessed as part of the 1881b0563631STom Van Eyck * key creation process. 1882b0563631STom Van Eyck * 1883b0563631STom Van Eyck * \param[in,out] slot Pointer to the slot with key material. 1884b0563631STom Van Eyck * \param[in] driver The secure element driver for the key, 1885b0563631STom Van Eyck * or NULL for a transparent key. 1886b0563631STom Van Eyck * \param[out] key On success, identifier of the key. Note that the 1887b0563631STom Van Eyck * key identifier is also stored in the key slot. 1888b0563631STom Van Eyck * 1889b0563631STom Van Eyck * \retval #PSA_SUCCESS 1890b0563631STom Van Eyck * The key was successfully created. 1891b0563631STom Van Eyck * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription 1892b0563631STom Van Eyck * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription 1893b0563631STom Van Eyck * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription 1894b0563631STom Van Eyck * \retval #PSA_ERROR_DATA_INVALID \emptydescription 1895b0563631STom Van Eyck * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription 1896b0563631STom Van Eyck * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription 1897b0563631STom Van Eyck * 1898b0563631STom Van Eyck * \return If this function fails, the key slot is an invalid state. 1899b0563631STom Van Eyck * You must call psa_fail_key_creation() to wipe and free the slot. 1900b0563631STom Van Eyck */ 1901b0563631STom Van Eyck static psa_status_t psa_finish_key_creation( 1902b0563631STom Van Eyck psa_key_slot_t *slot, 1903b0563631STom Van Eyck psa_se_drv_table_entry_t *driver, 1904b0563631STom Van Eyck mbedtls_svc_key_id_t *key) 1905b0563631STom Van Eyck { 1906b0563631STom Van Eyck psa_status_t status = PSA_SUCCESS; 1907b0563631STom Van Eyck (void) slot; 1908b0563631STom Van Eyck (void) driver; 1909b0563631STom Van Eyck 1910b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 1911b0563631STom Van Eyck PSA_THREADING_CHK_RET(mbedtls_mutex_lock( 1912b0563631STom Van Eyck &mbedtls_threading_key_slot_mutex)); 1913b0563631STom Van Eyck #endif 1914b0563631STom Van Eyck 1915b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) 1916b0563631STom Van Eyck if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { 1917b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 1918b0563631STom Van Eyck if (driver != NULL) { 1919b0563631STom Van Eyck psa_se_key_data_storage_t data; 1920b0563631STom Van Eyck psa_key_slot_number_t slot_number = 1921b0563631STom Van Eyck psa_key_slot_get_slot_number(slot); 1922b0563631STom Van Eyck 1923b0563631STom Van Eyck MBEDTLS_STATIC_ASSERT(sizeof(slot_number) == 1924b0563631STom Van Eyck sizeof(data.slot_number), 1925b0563631STom Van Eyck "Slot number size does not match psa_se_key_data_storage_t"); 1926b0563631STom Van Eyck 1927b0563631STom Van Eyck memcpy(&data.slot_number, &slot_number, sizeof(slot_number)); 1928b0563631STom Van Eyck status = psa_save_persistent_key(&slot->attr, 1929b0563631STom Van Eyck (uint8_t *) &data, 1930b0563631STom Van Eyck sizeof(data)); 1931b0563631STom Van Eyck } else 1932b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 1933b0563631STom Van Eyck { 1934b0563631STom Van Eyck /* Key material is saved in export representation in the slot, so 1935b0563631STom Van Eyck * just pass the slot buffer for storage. */ 1936b0563631STom Van Eyck status = psa_save_persistent_key(&slot->attr, 1937b0563631STom Van Eyck slot->key.data, 1938b0563631STom Van Eyck slot->key.bytes); 1939b0563631STom Van Eyck } 1940b0563631STom Van Eyck } 1941b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ 1942b0563631STom Van Eyck 1943b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 1944b0563631STom Van Eyck /* Finish the transaction for a key creation. This does not 1945b0563631STom Van Eyck * happen when registering an existing key. Detect this case 1946b0563631STom Van Eyck * by checking whether a transaction is in progress (actual 1947b0563631STom Van Eyck * creation of a persistent key in a secure element requires a transaction, 1948b0563631STom Van Eyck * but registration or volatile key creation doesn't use one). */ 1949b0563631STom Van Eyck if (driver != NULL && 1950b0563631STom Van Eyck psa_crypto_transaction.unknown.type == PSA_CRYPTO_TRANSACTION_CREATE_KEY) { 1951b0563631STom Van Eyck status = psa_save_se_persistent_data(driver); 1952b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1953b0563631STom Van Eyck psa_destroy_persistent_key(slot->attr.id); 1954b0563631STom Van Eyck 1955b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 1956b0563631STom Van Eyck PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( 1957b0563631STom Van Eyck &mbedtls_threading_key_slot_mutex)); 1958b0563631STom Van Eyck #endif 1959b0563631STom Van Eyck return status; 1960b0563631STom Van Eyck } 1961b0563631STom Van Eyck status = psa_crypto_stop_transaction(); 1962b0563631STom Van Eyck } 1963b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 1964b0563631STom Van Eyck 1965b0563631STom Van Eyck if (status == PSA_SUCCESS) { 1966b0563631STom Van Eyck *key = slot->attr.id; 1967b0563631STom Van Eyck status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING, 1968b0563631STom Van Eyck PSA_SLOT_FULL); 1969b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1970b0563631STom Van Eyck *key = MBEDTLS_SVC_KEY_ID_INIT; 1971b0563631STom Van Eyck } 1972b0563631STom Van Eyck } 1973b0563631STom Van Eyck 1974b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 1975b0563631STom Van Eyck PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( 1976b0563631STom Van Eyck &mbedtls_threading_key_slot_mutex)); 1977b0563631STom Van Eyck #endif 1978b0563631STom Van Eyck return status; 1979b0563631STom Van Eyck } 1980b0563631STom Van Eyck 1981b0563631STom Van Eyck /** Abort the creation of a key. 1982b0563631STom Van Eyck * 1983b0563631STom Van Eyck * You may call this function after calling psa_start_key_creation(), 1984b0563631STom Van Eyck * or after psa_finish_key_creation() fails. In other circumstances, this 1985b0563631STom Van Eyck * function may not clean up persistent storage. 1986b0563631STom Van Eyck * See the documentation of psa_start_key_creation() for the intended use 1987b0563631STom Van Eyck * of this function. Sets the slot's state to PSA_SLOT_EMPTY. 1988b0563631STom Van Eyck * 1989b0563631STom Van Eyck * \param[in,out] slot Pointer to the slot with key material. 1990b0563631STom Van Eyck * \param[in] driver The secure element driver for the key, 1991b0563631STom Van Eyck * or NULL for a transparent key. 1992b0563631STom Van Eyck */ 1993b0563631STom Van Eyck static void psa_fail_key_creation(psa_key_slot_t *slot, 1994b0563631STom Van Eyck psa_se_drv_table_entry_t *driver) 1995b0563631STom Van Eyck { 1996b0563631STom Van Eyck (void) driver; 1997b0563631STom Van Eyck 1998b0563631STom Van Eyck if (slot == NULL) { 1999b0563631STom Van Eyck return; 2000b0563631STom Van Eyck } 2001b0563631STom Van Eyck 2002b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 2003b0563631STom Van Eyck /* If the lock operation fails we still wipe the slot. 2004b0563631STom Van Eyck * Operations will no longer work after a failed lock, 2005b0563631STom Van Eyck * but we still need to wipe the slot of confidential data. */ 2006b0563631STom Van Eyck mbedtls_mutex_lock(&mbedtls_threading_key_slot_mutex); 2007b0563631STom Van Eyck #endif 2008b0563631STom Van Eyck 2009b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 2010b0563631STom Van Eyck /* TODO: If the key has already been created in the secure 2011b0563631STom Van Eyck * element, and the failure happened later (when saving metadata 2012b0563631STom Van Eyck * to internal storage), we need to destroy the key in the secure 2013b0563631STom Van Eyck * element. 2014b0563631STom Van Eyck * https://github.com/ARMmbed/mbed-crypto/issues/217 2015b0563631STom Van Eyck */ 2016b0563631STom Van Eyck 2017b0563631STom Van Eyck /* Abort the ongoing transaction if any (there may not be one if 2018b0563631STom Van Eyck * the creation process failed before starting one, or if the 2019b0563631STom Van Eyck * key creation is a registration of a key in a secure element). 2020b0563631STom Van Eyck * Earlier functions must already have done what it takes to undo any 2021b0563631STom Van Eyck * partial creation. All that's left is to update the transaction data 2022b0563631STom Van Eyck * itself. */ 2023b0563631STom Van Eyck (void) psa_crypto_stop_transaction(); 2024b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 2025b0563631STom Van Eyck 2026b0563631STom Van Eyck psa_wipe_key_slot(slot); 2027b0563631STom Van Eyck 2028b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 2029b0563631STom Van Eyck mbedtls_mutex_unlock(&mbedtls_threading_key_slot_mutex); 2030b0563631STom Van Eyck #endif 2031b0563631STom Van Eyck } 2032b0563631STom Van Eyck 2033b0563631STom Van Eyck /** Validate optional attributes during key creation. 2034b0563631STom Van Eyck * 2035b0563631STom Van Eyck * Some key attributes are optional during key creation. If they are 2036b0563631STom Van Eyck * specified in the attributes structure, check that they are consistent 2037b0563631STom Van Eyck * with the data in the slot. 2038b0563631STom Van Eyck * 2039b0563631STom Van Eyck * This function should be called near the end of key creation, after 2040b0563631STom Van Eyck * the slot in memory is fully populated but before saving persistent data. 2041b0563631STom Van Eyck */ 2042b0563631STom Van Eyck static psa_status_t psa_validate_optional_attributes( 2043b0563631STom Van Eyck const psa_key_slot_t *slot, 2044b0563631STom Van Eyck const psa_key_attributes_t *attributes) 2045b0563631STom Van Eyck { 2046b0563631STom Van Eyck if (attributes->type != 0) { 2047b0563631STom Van Eyck if (attributes->type != slot->attr.type) { 2048b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 2049b0563631STom Van Eyck } 2050b0563631STom Van Eyck } 2051b0563631STom Van Eyck 2052b0563631STom Van Eyck if (attributes->bits != 0) { 2053b0563631STom Van Eyck if (attributes->bits != slot->attr.bits) { 2054b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 2055b0563631STom Van Eyck } 2056b0563631STom Van Eyck } 2057b0563631STom Van Eyck 2058b0563631STom Van Eyck return PSA_SUCCESS; 2059b0563631STom Van Eyck } 2060b0563631STom Van Eyck 2061b0563631STom Van Eyck psa_status_t psa_import_key(const psa_key_attributes_t *attributes, 2062b0563631STom Van Eyck const uint8_t *data_external, 2063b0563631STom Van Eyck size_t data_length, 2064b0563631STom Van Eyck mbedtls_svc_key_id_t *key) 2065b0563631STom Van Eyck { 2066b0563631STom Van Eyck psa_status_t status; 2067b0563631STom Van Eyck LOCAL_INPUT_DECLARE(data_external, data); 2068b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 2069b0563631STom Van Eyck psa_se_drv_table_entry_t *driver = NULL; 2070b0563631STom Van Eyck size_t bits; 2071b0563631STom Van Eyck size_t storage_size = data_length; 2072b0563631STom Van Eyck 2073b0563631STom Van Eyck *key = MBEDTLS_SVC_KEY_ID_INIT; 2074b0563631STom Van Eyck 2075b0563631STom Van Eyck /* Reject zero-length symmetric keys (including raw data key objects). 2076b0563631STom Van Eyck * This also rejects any key which might be encoded as an empty string, 2077b0563631STom Van Eyck * which is never valid. */ 2078b0563631STom Van Eyck if (data_length == 0) { 2079b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 2080b0563631STom Van Eyck } 2081b0563631STom Van Eyck 2082b0563631STom Van Eyck /* Ensure that the bytes-to-bits conversion cannot overflow. */ 2083b0563631STom Van Eyck if (data_length > SIZE_MAX / 8) { 2084b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 2085b0563631STom Van Eyck } 2086b0563631STom Van Eyck 2087b0563631STom Van Eyck LOCAL_INPUT_ALLOC(data_external, data_length, data); 2088b0563631STom Van Eyck 2089b0563631STom Van Eyck status = psa_start_key_creation(PSA_KEY_CREATION_IMPORT, attributes, 2090b0563631STom Van Eyck &slot, &driver); 2091b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2092b0563631STom Van Eyck goto exit; 2093b0563631STom Van Eyck } 2094b0563631STom Van Eyck 2095b0563631STom Van Eyck /* In the case of a transparent key or an opaque key stored in local 2096b0563631STom Van Eyck * storage ( thus not in the case of importing a key in a secure element 2097b0563631STom Van Eyck * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a 2098b0563631STom Van Eyck * buffer to hold the imported key material. */ 2099b0563631STom Van Eyck if (slot->key.data == NULL) { 2100b0563631STom Van Eyck if (psa_key_lifetime_is_external(attributes->lifetime)) { 2101b0563631STom Van Eyck status = psa_driver_wrapper_get_key_buffer_size_from_key_data( 2102b0563631STom Van Eyck attributes, data, data_length, &storage_size); 2103b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2104b0563631STom Van Eyck goto exit; 2105b0563631STom Van Eyck } 2106b0563631STom Van Eyck } 2107b0563631STom Van Eyck status = psa_allocate_buffer_to_slot(slot, storage_size); 2108b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2109b0563631STom Van Eyck goto exit; 2110b0563631STom Van Eyck } 2111b0563631STom Van Eyck } 2112b0563631STom Van Eyck 2113b0563631STom Van Eyck bits = slot->attr.bits; 2114b0563631STom Van Eyck status = psa_driver_wrapper_import_key(attributes, 2115b0563631STom Van Eyck data, data_length, 2116b0563631STom Van Eyck slot->key.data, 2117b0563631STom Van Eyck slot->key.bytes, 2118b0563631STom Van Eyck &slot->key.bytes, &bits); 2119b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2120b0563631STom Van Eyck goto exit; 2121b0563631STom Van Eyck } 2122b0563631STom Van Eyck 2123b0563631STom Van Eyck if (slot->attr.bits == 0) { 2124b0563631STom Van Eyck slot->attr.bits = (psa_key_bits_t) bits; 2125b0563631STom Van Eyck } else if (bits != slot->attr.bits) { 2126b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 2127b0563631STom Van Eyck goto exit; 2128b0563631STom Van Eyck } 2129b0563631STom Van Eyck 2130b0563631STom Van Eyck /* Enforce a size limit, and in particular ensure that the bit 2131b0563631STom Van Eyck * size fits in its representation type.*/ 2132b0563631STom Van Eyck if (bits > PSA_MAX_KEY_BITS) { 2133b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 2134b0563631STom Van Eyck goto exit; 2135b0563631STom Van Eyck } 2136b0563631STom Van Eyck status = psa_validate_optional_attributes(slot, attributes); 2137b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2138b0563631STom Van Eyck goto exit; 2139b0563631STom Van Eyck } 2140b0563631STom Van Eyck 2141b0563631STom Van Eyck status = psa_finish_key_creation(slot, driver, key); 2142b0563631STom Van Eyck exit: 2143b0563631STom Van Eyck LOCAL_INPUT_FREE(data_external, data); 2144b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2145b0563631STom Van Eyck psa_fail_key_creation(slot, driver); 2146b0563631STom Van Eyck } 2147b0563631STom Van Eyck 2148b0563631STom Van Eyck return status; 2149b0563631STom Van Eyck } 2150b0563631STom Van Eyck 2151b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 2152b0563631STom Van Eyck psa_status_t mbedtls_psa_register_se_key( 2153b0563631STom Van Eyck const psa_key_attributes_t *attributes) 2154b0563631STom Van Eyck { 2155b0563631STom Van Eyck psa_status_t status; 2156b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 2157b0563631STom Van Eyck psa_se_drv_table_entry_t *driver = NULL; 2158b0563631STom Van Eyck mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; 2159b0563631STom Van Eyck 2160b0563631STom Van Eyck /* Leaving attributes unspecified is not currently supported. 2161b0563631STom Van Eyck * It could make sense to query the key type and size from the 2162b0563631STom Van Eyck * secure element, but not all secure elements support this 2163b0563631STom Van Eyck * and the driver HAL doesn't currently support it. */ 2164b0563631STom Van Eyck if (psa_get_key_type(attributes) == PSA_KEY_TYPE_NONE) { 2165b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 2166b0563631STom Van Eyck } 2167b0563631STom Van Eyck if (psa_get_key_bits(attributes) == 0) { 2168b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 2169b0563631STom Van Eyck } 2170b0563631STom Van Eyck 2171*cb034002SJerome Forissier /* Not usable with volatile keys, even with an appropriate location, 2172*cb034002SJerome Forissier * due to the API design. 2173*cb034002SJerome Forissier * https://github.com/Mbed-TLS/mbedtls/issues/9253 2174*cb034002SJerome Forissier */ 2175*cb034002SJerome Forissier if (PSA_KEY_LIFETIME_IS_VOLATILE(psa_get_key_lifetime(attributes))) { 2176*cb034002SJerome Forissier return PSA_ERROR_INVALID_ARGUMENT; 2177*cb034002SJerome Forissier } 2178*cb034002SJerome Forissier 2179b0563631STom Van Eyck status = psa_start_key_creation(PSA_KEY_CREATION_REGISTER, attributes, 2180b0563631STom Van Eyck &slot, &driver); 2181b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2182b0563631STom Van Eyck goto exit; 2183b0563631STom Van Eyck } 2184b0563631STom Van Eyck 2185b0563631STom Van Eyck status = psa_finish_key_creation(slot, driver, &key); 2186b0563631STom Van Eyck 2187b0563631STom Van Eyck exit: 2188b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2189b0563631STom Van Eyck psa_fail_key_creation(slot, driver); 2190b0563631STom Van Eyck } 2191b0563631STom Van Eyck 2192b0563631STom Van Eyck /* Registration doesn't keep the key in RAM. */ 2193b0563631STom Van Eyck psa_close_key(key); 2194b0563631STom Van Eyck return status; 2195b0563631STom Van Eyck } 2196b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 2197b0563631STom Van Eyck 2198b0563631STom Van Eyck psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, 2199b0563631STom Van Eyck const psa_key_attributes_t *specified_attributes, 2200b0563631STom Van Eyck mbedtls_svc_key_id_t *target_key) 2201b0563631STom Van Eyck { 2202b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2203b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 2204b0563631STom Van Eyck psa_key_slot_t *source_slot = NULL; 2205b0563631STom Van Eyck psa_key_slot_t *target_slot = NULL; 2206b0563631STom Van Eyck psa_key_attributes_t actual_attributes = *specified_attributes; 2207b0563631STom Van Eyck psa_se_drv_table_entry_t *driver = NULL; 2208b0563631STom Van Eyck size_t storage_size = 0; 2209b0563631STom Van Eyck 2210b0563631STom Van Eyck *target_key = MBEDTLS_SVC_KEY_ID_INIT; 2211b0563631STom Van Eyck 2212b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy( 2213b0563631STom Van Eyck source_key, &source_slot, PSA_KEY_USAGE_COPY, 0); 2214b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2215b0563631STom Van Eyck goto exit; 2216b0563631STom Van Eyck } 2217b0563631STom Van Eyck 2218b0563631STom Van Eyck status = psa_validate_optional_attributes(source_slot, 2219b0563631STom Van Eyck specified_attributes); 2220b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2221b0563631STom Van Eyck goto exit; 2222b0563631STom Van Eyck } 2223b0563631STom Van Eyck 2224b0563631STom Van Eyck /* The target key type and number of bits have been validated by 2225b0563631STom Van Eyck * psa_validate_optional_attributes() to be either equal to zero or 2226b0563631STom Van Eyck * equal to the ones of the source key. So it is safe to inherit 2227b0563631STom Van Eyck * them from the source key now." 2228b0563631STom Van Eyck * */ 2229b0563631STom Van Eyck actual_attributes.bits = source_slot->attr.bits; 2230b0563631STom Van Eyck actual_attributes.type = source_slot->attr.type; 2231b0563631STom Van Eyck 2232b0563631STom Van Eyck 2233b0563631STom Van Eyck status = psa_restrict_key_policy(source_slot->attr.type, 2234b0563631STom Van Eyck &actual_attributes.policy, 2235b0563631STom Van Eyck &source_slot->attr.policy); 2236b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2237b0563631STom Van Eyck goto exit; 2238b0563631STom Van Eyck } 2239b0563631STom Van Eyck 2240b0563631STom Van Eyck status = psa_start_key_creation(PSA_KEY_CREATION_COPY, &actual_attributes, 2241b0563631STom Van Eyck &target_slot, &driver); 2242b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2243b0563631STom Van Eyck goto exit; 2244b0563631STom Van Eyck } 2245b0563631STom Van Eyck if (PSA_KEY_LIFETIME_GET_LOCATION(target_slot->attr.lifetime) != 2246b0563631STom Van Eyck PSA_KEY_LIFETIME_GET_LOCATION(source_slot->attr.lifetime)) { 2247b0563631STom Van Eyck /* 2248b0563631STom Van Eyck * If the source and target keys are stored in different locations, 2249b0563631STom Van Eyck * the source key would need to be exported as plaintext and re-imported 2250b0563631STom Van Eyck * in the other location. This has security implications which have not 2251b0563631STom Van Eyck * been fully mapped. For now, this can be achieved through 2252b0563631STom Van Eyck * appropriate API invocations from the application, if needed. 2253b0563631STom Van Eyck * */ 2254b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 2255b0563631STom Van Eyck goto exit; 2256b0563631STom Van Eyck } 2257b0563631STom Van Eyck /* 2258b0563631STom Van Eyck * When the source and target keys are within the same location, 2259b0563631STom Van Eyck * - For transparent keys it is a blind copy without any driver invocation, 2260b0563631STom Van Eyck * - For opaque keys this translates to an invocation of the drivers' 2261b0563631STom Van Eyck * copy_key entry point through the dispatch layer. 2262b0563631STom Van Eyck * */ 2263b0563631STom Van Eyck if (psa_key_lifetime_is_external(actual_attributes.lifetime)) { 2264b0563631STom Van Eyck status = psa_driver_wrapper_get_key_buffer_size(&actual_attributes, 2265b0563631STom Van Eyck &storage_size); 2266b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2267b0563631STom Van Eyck goto exit; 2268b0563631STom Van Eyck } 2269b0563631STom Van Eyck 2270b0563631STom Van Eyck status = psa_allocate_buffer_to_slot(target_slot, storage_size); 2271b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2272b0563631STom Van Eyck goto exit; 2273b0563631STom Van Eyck } 2274b0563631STom Van Eyck 2275b0563631STom Van Eyck status = psa_driver_wrapper_copy_key(&actual_attributes, 2276b0563631STom Van Eyck source_slot->key.data, 2277b0563631STom Van Eyck source_slot->key.bytes, 2278b0563631STom Van Eyck target_slot->key.data, 2279b0563631STom Van Eyck target_slot->key.bytes, 2280b0563631STom Van Eyck &target_slot->key.bytes); 2281b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2282b0563631STom Van Eyck goto exit; 2283b0563631STom Van Eyck } 2284b0563631STom Van Eyck } else { 2285b0563631STom Van Eyck status = psa_copy_key_material_into_slot(target_slot, 2286b0563631STom Van Eyck source_slot->key.data, 2287b0563631STom Van Eyck source_slot->key.bytes); 2288b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2289b0563631STom Van Eyck goto exit; 2290b0563631STom Van Eyck } 2291b0563631STom Van Eyck } 2292b0563631STom Van Eyck status = psa_finish_key_creation(target_slot, driver, target_key); 2293b0563631STom Van Eyck exit: 2294b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2295b0563631STom Van Eyck psa_fail_key_creation(target_slot, driver); 2296b0563631STom Van Eyck } 2297b0563631STom Van Eyck 2298b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(source_slot); 2299b0563631STom Van Eyck 2300b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 2301b0563631STom Van Eyck } 2302b0563631STom Van Eyck 2303b0563631STom Van Eyck 2304b0563631STom Van Eyck 2305b0563631STom Van Eyck /****************************************************************/ 2306b0563631STom Van Eyck /* Message digests */ 2307b0563631STom Van Eyck /****************************************************************/ 2308b0563631STom Van Eyck 2309b0563631STom Van Eyck psa_status_t psa_hash_abort(psa_hash_operation_t *operation) 2310b0563631STom Van Eyck { 2311b0563631STom Van Eyck /* Aborting a non-active operation is allowed */ 2312b0563631STom Van Eyck if (operation->id == 0) { 2313b0563631STom Van Eyck return PSA_SUCCESS; 2314b0563631STom Van Eyck } 2315b0563631STom Van Eyck 2316b0563631STom Van Eyck psa_status_t status = psa_driver_wrapper_hash_abort(operation); 2317b0563631STom Van Eyck operation->id = 0; 2318b0563631STom Van Eyck 2319b0563631STom Van Eyck return status; 2320b0563631STom Van Eyck } 2321b0563631STom Van Eyck 2322b0563631STom Van Eyck psa_status_t psa_hash_setup(psa_hash_operation_t *operation, 2323b0563631STom Van Eyck psa_algorithm_t alg) 2324b0563631STom Van Eyck { 2325b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2326b0563631STom Van Eyck 2327b0563631STom Van Eyck /* A context must be freshly initialized before it can be set up. */ 2328b0563631STom Van Eyck if (operation->id != 0) { 2329b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 2330b0563631STom Van Eyck goto exit; 2331b0563631STom Van Eyck } 2332b0563631STom Van Eyck 2333b0563631STom Van Eyck if (!PSA_ALG_IS_HASH(alg)) { 2334b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 2335b0563631STom Van Eyck goto exit; 2336b0563631STom Van Eyck } 2337b0563631STom Van Eyck 2338b0563631STom Van Eyck /* Ensure all of the context is zeroized, since PSA_HASH_OPERATION_INIT only 2339b0563631STom Van Eyck * directly zeroes the int-sized dummy member of the context union. */ 2340b0563631STom Van Eyck memset(&operation->ctx, 0, sizeof(operation->ctx)); 2341b0563631STom Van Eyck 2342b0563631STom Van Eyck status = psa_driver_wrapper_hash_setup(operation, alg); 2343b0563631STom Van Eyck 2344b0563631STom Van Eyck exit: 2345b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2346b0563631STom Van Eyck psa_hash_abort(operation); 2347b0563631STom Van Eyck } 2348b0563631STom Van Eyck 2349b0563631STom Van Eyck return status; 2350b0563631STom Van Eyck } 2351b0563631STom Van Eyck 2352b0563631STom Van Eyck psa_status_t psa_hash_update(psa_hash_operation_t *operation, 2353b0563631STom Van Eyck const uint8_t *input_external, 2354b0563631STom Van Eyck size_t input_length) 2355b0563631STom Van Eyck { 2356b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2357b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 2358b0563631STom Van Eyck 2359b0563631STom Van Eyck if (operation->id == 0) { 2360b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 2361b0563631STom Van Eyck goto exit; 2362b0563631STom Van Eyck } 2363b0563631STom Van Eyck 2364b0563631STom Van Eyck /* Don't require hash implementations to behave correctly on a 2365b0563631STom Van Eyck * zero-length input, which may have an invalid pointer. */ 2366b0563631STom Van Eyck if (input_length == 0) { 2367b0563631STom Van Eyck return PSA_SUCCESS; 2368b0563631STom Van Eyck } 2369b0563631STom Van Eyck 2370b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 2371b0563631STom Van Eyck status = psa_driver_wrapper_hash_update(operation, input, input_length); 2372b0563631STom Van Eyck 2373b0563631STom Van Eyck exit: 2374b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2375b0563631STom Van Eyck psa_hash_abort(operation); 2376b0563631STom Van Eyck } 2377b0563631STom Van Eyck 2378b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 2379b0563631STom Van Eyck return status; 2380b0563631STom Van Eyck } 2381b0563631STom Van Eyck 2382b0563631STom Van Eyck static psa_status_t psa_hash_finish_internal(psa_hash_operation_t *operation, 2383b0563631STom Van Eyck uint8_t *hash, 2384b0563631STom Van Eyck size_t hash_size, 2385b0563631STom Van Eyck size_t *hash_length) 2386b0563631STom Van Eyck { 2387b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2388b0563631STom Van Eyck 2389b0563631STom Van Eyck *hash_length = 0; 2390b0563631STom Van Eyck if (operation->id == 0) { 2391b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 2392b0563631STom Van Eyck } 2393b0563631STom Van Eyck 2394b0563631STom Van Eyck status = psa_driver_wrapper_hash_finish( 2395b0563631STom Van Eyck operation, hash, hash_size, hash_length); 2396b0563631STom Van Eyck psa_hash_abort(operation); 2397b0563631STom Van Eyck 2398b0563631STom Van Eyck return status; 2399b0563631STom Van Eyck } 2400b0563631STom Van Eyck 2401b0563631STom Van Eyck psa_status_t psa_hash_finish(psa_hash_operation_t *operation, 2402b0563631STom Van Eyck uint8_t *hash_external, 2403b0563631STom Van Eyck size_t hash_size, 2404b0563631STom Van Eyck size_t *hash_length) 2405b0563631STom Van Eyck { 2406b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2407b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(hash_external, hash); 2408b0563631STom Van Eyck 2409b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash); 2410b0563631STom Van Eyck status = psa_hash_finish_internal(operation, hash, hash_size, hash_length); 2411b0563631STom Van Eyck 2412b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 2413b0563631STom Van Eyck exit: 2414b0563631STom Van Eyck #endif 2415b0563631STom Van Eyck LOCAL_OUTPUT_FREE(hash_external, hash); 2416b0563631STom Van Eyck return status; 2417b0563631STom Van Eyck } 2418b0563631STom Van Eyck 2419b0563631STom Van Eyck psa_status_t psa_hash_verify(psa_hash_operation_t *operation, 2420b0563631STom Van Eyck const uint8_t *hash_external, 2421b0563631STom Van Eyck size_t hash_length) 2422b0563631STom Van Eyck { 2423b0563631STom Van Eyck uint8_t actual_hash[PSA_HASH_MAX_SIZE]; 2424b0563631STom Van Eyck size_t actual_hash_length; 2425b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2426b0563631STom Van Eyck LOCAL_INPUT_DECLARE(hash_external, hash); 2427b0563631STom Van Eyck 2428b0563631STom Van Eyck status = psa_hash_finish_internal( 2429b0563631STom Van Eyck operation, 2430b0563631STom Van Eyck actual_hash, sizeof(actual_hash), 2431b0563631STom Van Eyck &actual_hash_length); 2432b0563631STom Van Eyck 2433b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2434b0563631STom Van Eyck goto exit; 2435b0563631STom Van Eyck } 2436b0563631STom Van Eyck 2437b0563631STom Van Eyck if (actual_hash_length != hash_length) { 2438b0563631STom Van Eyck status = PSA_ERROR_INVALID_SIGNATURE; 2439b0563631STom Van Eyck goto exit; 2440b0563631STom Van Eyck } 2441b0563631STom Van Eyck 2442b0563631STom Van Eyck LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); 2443b0563631STom Van Eyck if (mbedtls_ct_memcmp(hash, actual_hash, actual_hash_length) != 0) { 2444b0563631STom Van Eyck status = PSA_ERROR_INVALID_SIGNATURE; 2445b0563631STom Van Eyck } 2446b0563631STom Van Eyck 2447b0563631STom Van Eyck exit: 2448b0563631STom Van Eyck mbedtls_platform_zeroize(actual_hash, sizeof(actual_hash)); 2449b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2450b0563631STom Van Eyck psa_hash_abort(operation); 2451b0563631STom Van Eyck } 2452b0563631STom Van Eyck LOCAL_INPUT_FREE(hash_external, hash); 2453b0563631STom Van Eyck return status; 2454b0563631STom Van Eyck } 2455b0563631STom Van Eyck 2456b0563631STom Van Eyck psa_status_t psa_hash_compute(psa_algorithm_t alg, 2457b0563631STom Van Eyck const uint8_t *input_external, size_t input_length, 2458b0563631STom Van Eyck uint8_t *hash_external, size_t hash_size, 2459b0563631STom Van Eyck size_t *hash_length) 2460b0563631STom Van Eyck { 2461b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2462b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 2463b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(hash_external, hash); 2464b0563631STom Van Eyck 2465b0563631STom Van Eyck *hash_length = 0; 2466b0563631STom Van Eyck if (!PSA_ALG_IS_HASH(alg)) { 2467b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 2468b0563631STom Van Eyck } 2469b0563631STom Van Eyck 2470b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 2471b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash); 2472b0563631STom Van Eyck status = psa_driver_wrapper_hash_compute(alg, input, input_length, 2473b0563631STom Van Eyck hash, hash_size, hash_length); 2474b0563631STom Van Eyck 2475b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 2476b0563631STom Van Eyck exit: 2477b0563631STom Van Eyck #endif 2478b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 2479b0563631STom Van Eyck LOCAL_OUTPUT_FREE(hash_external, hash); 2480b0563631STom Van Eyck return status; 2481b0563631STom Van Eyck } 2482b0563631STom Van Eyck 2483b0563631STom Van Eyck psa_status_t psa_hash_compare(psa_algorithm_t alg, 2484b0563631STom Van Eyck const uint8_t *input_external, size_t input_length, 2485b0563631STom Van Eyck const uint8_t *hash_external, size_t hash_length) 2486b0563631STom Van Eyck { 2487b0563631STom Van Eyck uint8_t actual_hash[PSA_HASH_MAX_SIZE]; 2488b0563631STom Van Eyck size_t actual_hash_length; 2489b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2490b0563631STom Van Eyck 2491b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 2492b0563631STom Van Eyck LOCAL_INPUT_DECLARE(hash_external, hash); 2493b0563631STom Van Eyck 2494b0563631STom Van Eyck if (!PSA_ALG_IS_HASH(alg)) { 2495b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 2496b0563631STom Van Eyck return status; 2497b0563631STom Van Eyck } 2498b0563631STom Van Eyck 2499b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 2500b0563631STom Van Eyck status = psa_driver_wrapper_hash_compute( 2501b0563631STom Van Eyck alg, input, input_length, 2502b0563631STom Van Eyck actual_hash, sizeof(actual_hash), 2503b0563631STom Van Eyck &actual_hash_length); 2504b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2505b0563631STom Van Eyck goto exit; 2506b0563631STom Van Eyck } 2507b0563631STom Van Eyck if (actual_hash_length != hash_length) { 2508b0563631STom Van Eyck status = PSA_ERROR_INVALID_SIGNATURE; 2509b0563631STom Van Eyck goto exit; 2510b0563631STom Van Eyck } 2511b0563631STom Van Eyck 2512b0563631STom Van Eyck LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); 2513b0563631STom Van Eyck if (mbedtls_ct_memcmp(hash, actual_hash, actual_hash_length) != 0) { 2514b0563631STom Van Eyck status = PSA_ERROR_INVALID_SIGNATURE; 2515b0563631STom Van Eyck } 2516b0563631STom Van Eyck 2517b0563631STom Van Eyck exit: 2518b0563631STom Van Eyck mbedtls_platform_zeroize(actual_hash, sizeof(actual_hash)); 2519b0563631STom Van Eyck 2520b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 2521b0563631STom Van Eyck LOCAL_INPUT_FREE(hash_external, hash); 2522b0563631STom Van Eyck 2523b0563631STom Van Eyck return status; 2524b0563631STom Van Eyck } 2525b0563631STom Van Eyck 2526b0563631STom Van Eyck psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, 2527b0563631STom Van Eyck psa_hash_operation_t *target_operation) 2528b0563631STom Van Eyck { 2529b0563631STom Van Eyck if (source_operation->id == 0 || 2530b0563631STom Van Eyck target_operation->id != 0) { 2531b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 2532b0563631STom Van Eyck } 2533b0563631STom Van Eyck 2534b0563631STom Van Eyck psa_status_t status = psa_driver_wrapper_hash_clone(source_operation, 2535b0563631STom Van Eyck target_operation); 2536b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2537b0563631STom Van Eyck psa_hash_abort(target_operation); 2538b0563631STom Van Eyck } 2539b0563631STom Van Eyck 2540b0563631STom Van Eyck return status; 2541b0563631STom Van Eyck } 2542b0563631STom Van Eyck 2543b0563631STom Van Eyck 2544b0563631STom Van Eyck /****************************************************************/ 2545b0563631STom Van Eyck /* MAC */ 2546b0563631STom Van Eyck /****************************************************************/ 2547b0563631STom Van Eyck 2548b0563631STom Van Eyck psa_status_t psa_mac_abort(psa_mac_operation_t *operation) 2549b0563631STom Van Eyck { 2550b0563631STom Van Eyck /* Aborting a non-active operation is allowed */ 2551b0563631STom Van Eyck if (operation->id == 0) { 2552b0563631STom Van Eyck return PSA_SUCCESS; 2553b0563631STom Van Eyck } 2554b0563631STom Van Eyck 2555b0563631STom Van Eyck psa_status_t status = psa_driver_wrapper_mac_abort(operation); 2556b0563631STom Van Eyck operation->mac_size = 0; 2557b0563631STom Van Eyck operation->is_sign = 0; 2558b0563631STom Van Eyck operation->id = 0; 2559b0563631STom Van Eyck 2560b0563631STom Van Eyck return status; 2561b0563631STom Van Eyck } 2562b0563631STom Van Eyck 2563b0563631STom Van Eyck static psa_status_t psa_mac_finalize_alg_and_key_validation( 2564b0563631STom Van Eyck psa_algorithm_t alg, 2565b0563631STom Van Eyck const psa_key_attributes_t *attributes, 2566b0563631STom Van Eyck uint8_t *mac_size) 2567b0563631STom Van Eyck { 2568b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2569b0563631STom Van Eyck psa_key_type_t key_type = psa_get_key_type(attributes); 2570b0563631STom Van Eyck size_t key_bits = psa_get_key_bits(attributes); 2571b0563631STom Van Eyck 2572b0563631STom Van Eyck if (!PSA_ALG_IS_MAC(alg)) { 2573b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 2574b0563631STom Van Eyck } 2575b0563631STom Van Eyck 2576b0563631STom Van Eyck /* Validate the combination of key type and algorithm */ 2577b0563631STom Van Eyck status = psa_mac_key_can_do(alg, key_type); 2578b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2579b0563631STom Van Eyck return status; 2580b0563631STom Van Eyck } 2581b0563631STom Van Eyck 2582b0563631STom Van Eyck /* Get the output length for the algorithm and key combination */ 2583b0563631STom Van Eyck *mac_size = PSA_MAC_LENGTH(key_type, key_bits, alg); 2584b0563631STom Van Eyck 2585b0563631STom Van Eyck if (*mac_size < 4) { 2586b0563631STom Van Eyck /* A very short MAC is too short for security since it can be 2587b0563631STom Van Eyck * brute-forced. Ancient protocols with 32-bit MACs do exist, 2588b0563631STom Van Eyck * so we make this our minimum, even though 32 bits is still 2589b0563631STom Van Eyck * too small for security. */ 2590b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 2591b0563631STom Van Eyck } 2592b0563631STom Van Eyck 2593b0563631STom Van Eyck if (*mac_size > PSA_MAC_LENGTH(key_type, key_bits, 2594b0563631STom Van Eyck PSA_ALG_FULL_LENGTH_MAC(alg))) { 2595b0563631STom Van Eyck /* It's impossible to "truncate" to a larger length than the full length 2596b0563631STom Van Eyck * of the algorithm. */ 2597b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 2598b0563631STom Van Eyck } 2599b0563631STom Van Eyck 2600b0563631STom Van Eyck if (*mac_size > PSA_MAC_MAX_SIZE) { 2601b0563631STom Van Eyck /* PSA_MAC_LENGTH returns the correct length even for a MAC algorithm 2602b0563631STom Van Eyck * that is disabled in the compile-time configuration. The result can 2603b0563631STom Van Eyck * therefore be larger than PSA_MAC_MAX_SIZE, which does take the 2604b0563631STom Van Eyck * configuration into account. In this case, force a return of 2605b0563631STom Van Eyck * PSA_ERROR_NOT_SUPPORTED here. Otherwise psa_mac_verify(), or 2606b0563631STom Van Eyck * psa_mac_compute(mac_size=PSA_MAC_MAX_SIZE), would return 2607b0563631STom Van Eyck * PSA_ERROR_BUFFER_TOO_SMALL for an unsupported algorithm whose MAC size 2608b0563631STom Van Eyck * is larger than PSA_MAC_MAX_SIZE, which is misleading and which breaks 2609b0563631STom Van Eyck * systematically generated tests. */ 2610b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 2611b0563631STom Van Eyck } 2612b0563631STom Van Eyck 2613b0563631STom Van Eyck return PSA_SUCCESS; 2614b0563631STom Van Eyck } 2615b0563631STom Van Eyck 2616b0563631STom Van Eyck static psa_status_t psa_mac_setup(psa_mac_operation_t *operation, 2617b0563631STom Van Eyck mbedtls_svc_key_id_t key, 2618b0563631STom Van Eyck psa_algorithm_t alg, 2619b0563631STom Van Eyck int is_sign) 2620b0563631STom Van Eyck { 2621b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2622b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 2623b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 2624b0563631STom Van Eyck 2625b0563631STom Van Eyck /* A context must be freshly initialized before it can be set up. */ 2626b0563631STom Van Eyck if (operation->id != 0) { 2627b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 2628b0563631STom Van Eyck goto exit; 2629b0563631STom Van Eyck } 2630b0563631STom Van Eyck 2631b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy( 2632b0563631STom Van Eyck key, 2633b0563631STom Van Eyck &slot, 2634b0563631STom Van Eyck is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE, 2635b0563631STom Van Eyck alg); 2636b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2637b0563631STom Van Eyck goto exit; 2638b0563631STom Van Eyck } 2639b0563631STom Van Eyck 2640b0563631STom Van Eyck status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr, 2641b0563631STom Van Eyck &operation->mac_size); 2642b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2643b0563631STom Van Eyck goto exit; 2644b0563631STom Van Eyck } 2645b0563631STom Van Eyck 2646b0563631STom Van Eyck operation->is_sign = is_sign; 2647b0563631STom Van Eyck /* Dispatch the MAC setup call with validated input */ 2648b0563631STom Van Eyck if (is_sign) { 2649b0563631STom Van Eyck status = psa_driver_wrapper_mac_sign_setup(operation, 2650b0563631STom Van Eyck &slot->attr, 2651b0563631STom Van Eyck slot->key.data, 2652b0563631STom Van Eyck slot->key.bytes, 2653b0563631STom Van Eyck alg); 2654b0563631STom Van Eyck } else { 2655b0563631STom Van Eyck status = psa_driver_wrapper_mac_verify_setup(operation, 2656b0563631STom Van Eyck &slot->attr, 2657b0563631STom Van Eyck slot->key.data, 2658b0563631STom Van Eyck slot->key.bytes, 2659b0563631STom Van Eyck alg); 2660b0563631STom Van Eyck } 2661b0563631STom Van Eyck 2662b0563631STom Van Eyck exit: 2663b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2664b0563631STom Van Eyck psa_mac_abort(operation); 2665b0563631STom Van Eyck } 2666b0563631STom Van Eyck 2667b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 2668b0563631STom Van Eyck 2669b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 2670b0563631STom Van Eyck } 2671b0563631STom Van Eyck 2672b0563631STom Van Eyck psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, 2673b0563631STom Van Eyck mbedtls_svc_key_id_t key, 2674b0563631STom Van Eyck psa_algorithm_t alg) 2675b0563631STom Van Eyck { 2676b0563631STom Van Eyck return psa_mac_setup(operation, key, alg, 1); 2677b0563631STom Van Eyck } 2678b0563631STom Van Eyck 2679b0563631STom Van Eyck psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, 2680b0563631STom Van Eyck mbedtls_svc_key_id_t key, 2681b0563631STom Van Eyck psa_algorithm_t alg) 2682b0563631STom Van Eyck { 2683b0563631STom Van Eyck return psa_mac_setup(operation, key, alg, 0); 2684b0563631STom Van Eyck } 2685b0563631STom Van Eyck 2686b0563631STom Van Eyck psa_status_t psa_mac_update(psa_mac_operation_t *operation, 2687b0563631STom Van Eyck const uint8_t *input_external, 2688b0563631STom Van Eyck size_t input_length) 2689b0563631STom Van Eyck { 2690b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2691b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 2692b0563631STom Van Eyck 2693b0563631STom Van Eyck if (operation->id == 0) { 2694b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 2695b0563631STom Van Eyck return status; 2696b0563631STom Van Eyck } 2697b0563631STom Van Eyck 2698b0563631STom Van Eyck /* Don't require hash implementations to behave correctly on a 2699b0563631STom Van Eyck * zero-length input, which may have an invalid pointer. */ 2700b0563631STom Van Eyck if (input_length == 0) { 2701b0563631STom Van Eyck status = PSA_SUCCESS; 2702b0563631STom Van Eyck return status; 2703b0563631STom Van Eyck } 2704b0563631STom Van Eyck 2705b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 2706b0563631STom Van Eyck status = psa_driver_wrapper_mac_update(operation, input, input_length); 2707b0563631STom Van Eyck 2708b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2709b0563631STom Van Eyck psa_mac_abort(operation); 2710b0563631STom Van Eyck } 2711b0563631STom Van Eyck 2712b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 2713b0563631STom Van Eyck exit: 2714b0563631STom Van Eyck #endif 2715b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 2716b0563631STom Van Eyck 2717b0563631STom Van Eyck return status; 2718b0563631STom Van Eyck } 2719b0563631STom Van Eyck 2720b0563631STom Van Eyck psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, 2721b0563631STom Van Eyck uint8_t *mac_external, 2722b0563631STom Van Eyck size_t mac_size, 2723b0563631STom Van Eyck size_t *mac_length) 2724b0563631STom Van Eyck { 2725b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2726b0563631STom Van Eyck psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; 2727b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(mac_external, mac); 2728b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac); 2729b0563631STom Van Eyck 2730b0563631STom Van Eyck if (operation->id == 0) { 2731b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 2732b0563631STom Van Eyck goto exit; 2733b0563631STom Van Eyck } 2734b0563631STom Van Eyck 2735b0563631STom Van Eyck if (!operation->is_sign) { 2736b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 2737b0563631STom Van Eyck goto exit; 2738b0563631STom Van Eyck } 2739b0563631STom Van Eyck 2740b0563631STom Van Eyck /* Sanity check. This will guarantee that mac_size != 0 (and so mac != NULL) 2741b0563631STom Van Eyck * once all the error checks are done. */ 2742b0563631STom Van Eyck if (operation->mac_size == 0) { 2743b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 2744b0563631STom Van Eyck goto exit; 2745b0563631STom Van Eyck } 2746b0563631STom Van Eyck 2747b0563631STom Van Eyck if (mac_size < operation->mac_size) { 2748b0563631STom Van Eyck status = PSA_ERROR_BUFFER_TOO_SMALL; 2749b0563631STom Van Eyck goto exit; 2750b0563631STom Van Eyck } 2751b0563631STom Van Eyck 2752b0563631STom Van Eyck 2753b0563631STom Van Eyck status = psa_driver_wrapper_mac_sign_finish(operation, 2754b0563631STom Van Eyck mac, operation->mac_size, 2755b0563631STom Van Eyck mac_length); 2756b0563631STom Van Eyck 2757b0563631STom Van Eyck exit: 2758b0563631STom Van Eyck /* In case of success, set the potential excess room in the output buffer 2759b0563631STom Van Eyck * to an invalid value, to avoid potentially leaking a longer MAC. 2760b0563631STom Van Eyck * In case of error, set the output length and content to a safe default, 2761b0563631STom Van Eyck * such that in case the caller misses an error check, the output would be 2762b0563631STom Van Eyck * an unachievable MAC. 2763b0563631STom Van Eyck */ 2764b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2765b0563631STom Van Eyck *mac_length = mac_size; 2766b0563631STom Van Eyck operation->mac_size = 0; 2767b0563631STom Van Eyck } 2768b0563631STom Van Eyck 2769b0563631STom Van Eyck if (mac != NULL) { 2770b0563631STom Van Eyck psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length); 2771b0563631STom Van Eyck } 2772b0563631STom Van Eyck 2773b0563631STom Van Eyck abort_status = psa_mac_abort(operation); 2774b0563631STom Van Eyck LOCAL_OUTPUT_FREE(mac_external, mac); 2775b0563631STom Van Eyck 2776b0563631STom Van Eyck return status == PSA_SUCCESS ? abort_status : status; 2777b0563631STom Van Eyck } 2778b0563631STom Van Eyck 2779b0563631STom Van Eyck psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, 2780b0563631STom Van Eyck const uint8_t *mac_external, 2781b0563631STom Van Eyck size_t mac_length) 2782b0563631STom Van Eyck { 2783b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2784b0563631STom Van Eyck psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; 2785b0563631STom Van Eyck LOCAL_INPUT_DECLARE(mac_external, mac); 2786b0563631STom Van Eyck 2787b0563631STom Van Eyck if (operation->id == 0) { 2788b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 2789b0563631STom Van Eyck goto exit; 2790b0563631STom Van Eyck } 2791b0563631STom Van Eyck 2792b0563631STom Van Eyck if (operation->is_sign) { 2793b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 2794b0563631STom Van Eyck goto exit; 2795b0563631STom Van Eyck } 2796b0563631STom Van Eyck 2797b0563631STom Van Eyck if (operation->mac_size != mac_length) { 2798b0563631STom Van Eyck status = PSA_ERROR_INVALID_SIGNATURE; 2799b0563631STom Van Eyck goto exit; 2800b0563631STom Van Eyck } 2801b0563631STom Van Eyck 2802b0563631STom Van Eyck LOCAL_INPUT_ALLOC(mac_external, mac_length, mac); 2803b0563631STom Van Eyck status = psa_driver_wrapper_mac_verify_finish(operation, 2804b0563631STom Van Eyck mac, mac_length); 2805b0563631STom Van Eyck 2806b0563631STom Van Eyck exit: 2807b0563631STom Van Eyck abort_status = psa_mac_abort(operation); 2808b0563631STom Van Eyck LOCAL_INPUT_FREE(mac_external, mac); 2809b0563631STom Van Eyck 2810b0563631STom Van Eyck return status == PSA_SUCCESS ? abort_status : status; 2811b0563631STom Van Eyck } 2812b0563631STom Van Eyck 2813b0563631STom Van Eyck static psa_status_t psa_mac_compute_internal(mbedtls_svc_key_id_t key, 2814b0563631STom Van Eyck psa_algorithm_t alg, 2815b0563631STom Van Eyck const uint8_t *input, 2816b0563631STom Van Eyck size_t input_length, 2817b0563631STom Van Eyck uint8_t *mac, 2818b0563631STom Van Eyck size_t mac_size, 2819b0563631STom Van Eyck size_t *mac_length, 2820b0563631STom Van Eyck int is_sign) 2821b0563631STom Van Eyck { 2822b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2823b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 2824b0563631STom Van Eyck psa_key_slot_t *slot; 2825b0563631STom Van Eyck uint8_t operation_mac_size = 0; 2826b0563631STom Van Eyck 2827b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy( 2828b0563631STom Van Eyck key, 2829b0563631STom Van Eyck &slot, 2830b0563631STom Van Eyck is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE, 2831b0563631STom Van Eyck alg); 2832b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2833b0563631STom Van Eyck goto exit; 2834b0563631STom Van Eyck } 2835b0563631STom Van Eyck 2836b0563631STom Van Eyck status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr, 2837b0563631STom Van Eyck &operation_mac_size); 2838b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2839b0563631STom Van Eyck goto exit; 2840b0563631STom Van Eyck } 2841b0563631STom Van Eyck 2842b0563631STom Van Eyck if (mac_size < operation_mac_size) { 2843b0563631STom Van Eyck status = PSA_ERROR_BUFFER_TOO_SMALL; 2844b0563631STom Van Eyck goto exit; 2845b0563631STom Van Eyck } 2846b0563631STom Van Eyck 2847b0563631STom Van Eyck status = psa_driver_wrapper_mac_compute( 2848b0563631STom Van Eyck &slot->attr, 2849b0563631STom Van Eyck slot->key.data, slot->key.bytes, 2850b0563631STom Van Eyck alg, 2851b0563631STom Van Eyck input, input_length, 2852b0563631STom Van Eyck mac, operation_mac_size, mac_length); 2853b0563631STom Van Eyck 2854b0563631STom Van Eyck exit: 2855b0563631STom Van Eyck /* In case of success, set the potential excess room in the output buffer 2856b0563631STom Van Eyck * to an invalid value, to avoid potentially leaking a longer MAC. 2857b0563631STom Van Eyck * In case of error, set the output length and content to a safe default, 2858b0563631STom Van Eyck * such that in case the caller misses an error check, the output would be 2859b0563631STom Van Eyck * an unachievable MAC. 2860b0563631STom Van Eyck */ 2861b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2862b0563631STom Van Eyck *mac_length = mac_size; 2863b0563631STom Van Eyck operation_mac_size = 0; 2864b0563631STom Van Eyck } 2865b0563631STom Van Eyck 2866b0563631STom Van Eyck psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length); 2867b0563631STom Van Eyck 2868b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 2869b0563631STom Van Eyck 2870b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 2871b0563631STom Van Eyck } 2872b0563631STom Van Eyck 2873b0563631STom Van Eyck psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, 2874b0563631STom Van Eyck psa_algorithm_t alg, 2875b0563631STom Van Eyck const uint8_t *input_external, 2876b0563631STom Van Eyck size_t input_length, 2877b0563631STom Van Eyck uint8_t *mac_external, 2878b0563631STom Van Eyck size_t mac_size, 2879b0563631STom Van Eyck size_t *mac_length) 2880b0563631STom Van Eyck { 2881b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2882b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 2883b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(mac_external, mac); 2884b0563631STom Van Eyck 2885b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 2886b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac); 2887b0563631STom Van Eyck status = psa_mac_compute_internal(key, alg, 2888b0563631STom Van Eyck input, input_length, 2889b0563631STom Van Eyck mac, mac_size, mac_length, 1); 2890b0563631STom Van Eyck 2891b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 2892b0563631STom Van Eyck exit: 2893b0563631STom Van Eyck #endif 2894b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 2895b0563631STom Van Eyck LOCAL_OUTPUT_FREE(mac_external, mac); 2896b0563631STom Van Eyck 2897b0563631STom Van Eyck return status; 2898b0563631STom Van Eyck } 2899b0563631STom Van Eyck 2900b0563631STom Van Eyck psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key, 2901b0563631STom Van Eyck psa_algorithm_t alg, 2902b0563631STom Van Eyck const uint8_t *input_external, 2903b0563631STom Van Eyck size_t input_length, 2904b0563631STom Van Eyck const uint8_t *mac_external, 2905b0563631STom Van Eyck size_t mac_length) 2906b0563631STom Van Eyck { 2907b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2908b0563631STom Van Eyck uint8_t actual_mac[PSA_MAC_MAX_SIZE]; 2909b0563631STom Van Eyck size_t actual_mac_length; 2910b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 2911b0563631STom Van Eyck LOCAL_INPUT_DECLARE(mac_external, mac); 2912b0563631STom Van Eyck 2913b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 2914b0563631STom Van Eyck status = psa_mac_compute_internal(key, alg, 2915b0563631STom Van Eyck input, input_length, 2916b0563631STom Van Eyck actual_mac, sizeof(actual_mac), 2917b0563631STom Van Eyck &actual_mac_length, 0); 2918b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2919b0563631STom Van Eyck goto exit; 2920b0563631STom Van Eyck } 2921b0563631STom Van Eyck 2922b0563631STom Van Eyck if (mac_length != actual_mac_length) { 2923b0563631STom Van Eyck status = PSA_ERROR_INVALID_SIGNATURE; 2924b0563631STom Van Eyck goto exit; 2925b0563631STom Van Eyck } 2926b0563631STom Van Eyck 2927b0563631STom Van Eyck LOCAL_INPUT_ALLOC(mac_external, mac_length, mac); 2928b0563631STom Van Eyck if (mbedtls_ct_memcmp(mac, actual_mac, actual_mac_length) != 0) { 2929b0563631STom Van Eyck status = PSA_ERROR_INVALID_SIGNATURE; 2930b0563631STom Van Eyck goto exit; 2931b0563631STom Van Eyck } 2932b0563631STom Van Eyck 2933b0563631STom Van Eyck exit: 2934b0563631STom Van Eyck mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac)); 2935b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 2936b0563631STom Van Eyck LOCAL_INPUT_FREE(mac_external, mac); 2937b0563631STom Van Eyck 2938b0563631STom Van Eyck return status; 2939b0563631STom Van Eyck } 2940b0563631STom Van Eyck 2941b0563631STom Van Eyck /****************************************************************/ 2942b0563631STom Van Eyck /* Asymmetric cryptography */ 2943b0563631STom Van Eyck /****************************************************************/ 2944b0563631STom Van Eyck 2945b0563631STom Van Eyck static psa_status_t psa_sign_verify_check_alg(int input_is_message, 2946b0563631STom Van Eyck psa_algorithm_t alg) 2947b0563631STom Van Eyck { 2948b0563631STom Van Eyck if (input_is_message) { 2949b0563631STom Van Eyck if (!PSA_ALG_IS_SIGN_MESSAGE(alg)) { 2950b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 2951b0563631STom Van Eyck } 2952b0563631STom Van Eyck 2953b0563631STom Van Eyck if (PSA_ALG_IS_SIGN_HASH(alg)) { 2954b0563631STom Van Eyck if (!PSA_ALG_IS_HASH(PSA_ALG_SIGN_GET_HASH(alg))) { 2955b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 2956b0563631STom Van Eyck } 2957b0563631STom Van Eyck } 2958b0563631STom Van Eyck } else { 2959b0563631STom Van Eyck if (!PSA_ALG_IS_SIGN_HASH(alg)) { 2960b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 2961b0563631STom Van Eyck } 2962b0563631STom Van Eyck } 2963b0563631STom Van Eyck 2964b0563631STom Van Eyck return PSA_SUCCESS; 2965b0563631STom Van Eyck } 2966b0563631STom Van Eyck 2967b0563631STom Van Eyck static psa_status_t psa_sign_internal(mbedtls_svc_key_id_t key, 2968b0563631STom Van Eyck int input_is_message, 2969b0563631STom Van Eyck psa_algorithm_t alg, 2970b0563631STom Van Eyck const uint8_t *input, 2971b0563631STom Van Eyck size_t input_length, 2972b0563631STom Van Eyck uint8_t *signature, 2973b0563631STom Van Eyck size_t signature_size, 2974b0563631STom Van Eyck size_t *signature_length) 2975b0563631STom Van Eyck { 2976b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2977b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 2978b0563631STom Van Eyck psa_key_slot_t *slot; 2979b0563631STom Van Eyck 2980b0563631STom Van Eyck *signature_length = 0; 2981b0563631STom Van Eyck 2982b0563631STom Van Eyck status = psa_sign_verify_check_alg(input_is_message, alg); 2983b0563631STom Van Eyck if (status != PSA_SUCCESS) { 2984b0563631STom Van Eyck return status; 2985b0563631STom Van Eyck } 2986b0563631STom Van Eyck 2987b0563631STom Van Eyck /* Immediately reject a zero-length signature buffer. This guarantees 2988b0563631STom Van Eyck * that signature must be a valid pointer. (On the other hand, the input 2989b0563631STom Van Eyck * buffer can in principle be empty since it doesn't actually have 2990b0563631STom Van Eyck * to be a hash.) */ 2991b0563631STom Van Eyck if (signature_size == 0) { 2992b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 2993b0563631STom Van Eyck } 2994b0563631STom Van Eyck 2995b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy( 2996b0563631STom Van Eyck key, &slot, 2997b0563631STom Van Eyck input_is_message ? PSA_KEY_USAGE_SIGN_MESSAGE : 2998b0563631STom Van Eyck PSA_KEY_USAGE_SIGN_HASH, 2999b0563631STom Van Eyck alg); 3000b0563631STom Van Eyck 3001b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3002b0563631STom Van Eyck goto exit; 3003b0563631STom Van Eyck } 3004b0563631STom Van Eyck 3005b0563631STom Van Eyck if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) { 3006b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 3007b0563631STom Van Eyck goto exit; 3008b0563631STom Van Eyck } 3009b0563631STom Van Eyck 3010b0563631STom Van Eyck if (input_is_message) { 3011b0563631STom Van Eyck status = psa_driver_wrapper_sign_message( 3012b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 3013b0563631STom Van Eyck alg, input, input_length, 3014b0563631STom Van Eyck signature, signature_size, signature_length); 3015b0563631STom Van Eyck } else { 3016b0563631STom Van Eyck 3017b0563631STom Van Eyck status = psa_driver_wrapper_sign_hash( 3018b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 3019b0563631STom Van Eyck alg, input, input_length, 3020b0563631STom Van Eyck signature, signature_size, signature_length); 3021b0563631STom Van Eyck } 3022b0563631STom Van Eyck 3023b0563631STom Van Eyck 3024b0563631STom Van Eyck exit: 3025b0563631STom Van Eyck psa_wipe_tag_output_buffer(signature, status, signature_size, 3026b0563631STom Van Eyck *signature_length); 3027b0563631STom Van Eyck 3028b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 3029b0563631STom Van Eyck 3030b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 3031b0563631STom Van Eyck } 3032b0563631STom Van Eyck 3033b0563631STom Van Eyck static psa_status_t psa_verify_internal(mbedtls_svc_key_id_t key, 3034b0563631STom Van Eyck int input_is_message, 3035b0563631STom Van Eyck psa_algorithm_t alg, 3036b0563631STom Van Eyck const uint8_t *input, 3037b0563631STom Van Eyck size_t input_length, 3038b0563631STom Van Eyck const uint8_t *signature, 3039b0563631STom Van Eyck size_t signature_length) 3040b0563631STom Van Eyck { 3041b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3042b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 3043b0563631STom Van Eyck psa_key_slot_t *slot; 3044b0563631STom Van Eyck 3045b0563631STom Van Eyck status = psa_sign_verify_check_alg(input_is_message, alg); 3046b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3047b0563631STom Van Eyck return status; 3048b0563631STom Van Eyck } 3049b0563631STom Van Eyck 3050b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy( 3051b0563631STom Van Eyck key, &slot, 3052b0563631STom Van Eyck input_is_message ? PSA_KEY_USAGE_VERIFY_MESSAGE : 3053b0563631STom Van Eyck PSA_KEY_USAGE_VERIFY_HASH, 3054b0563631STom Van Eyck alg); 3055b0563631STom Van Eyck 3056b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3057b0563631STom Van Eyck return status; 3058b0563631STom Van Eyck } 3059b0563631STom Van Eyck 3060b0563631STom Van Eyck if (input_is_message) { 3061b0563631STom Van Eyck status = psa_driver_wrapper_verify_message( 3062b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 3063b0563631STom Van Eyck alg, input, input_length, 3064b0563631STom Van Eyck signature, signature_length); 3065b0563631STom Van Eyck } else { 3066b0563631STom Van Eyck status = psa_driver_wrapper_verify_hash( 3067b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 3068b0563631STom Van Eyck alg, input, input_length, 3069b0563631STom Van Eyck signature, signature_length); 3070b0563631STom Van Eyck } 3071b0563631STom Van Eyck 3072b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 3073b0563631STom Van Eyck 3074b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 3075b0563631STom Van Eyck 3076b0563631STom Van Eyck } 3077b0563631STom Van Eyck 3078b0563631STom Van Eyck psa_status_t psa_sign_message_builtin( 3079b0563631STom Van Eyck const psa_key_attributes_t *attributes, 3080b0563631STom Van Eyck const uint8_t *key_buffer, 3081b0563631STom Van Eyck size_t key_buffer_size, 3082b0563631STom Van Eyck psa_algorithm_t alg, 3083b0563631STom Van Eyck const uint8_t *input, 3084b0563631STom Van Eyck size_t input_length, 3085b0563631STom Van Eyck uint8_t *signature, 3086b0563631STom Van Eyck size_t signature_size, 3087b0563631STom Van Eyck size_t *signature_length) 3088b0563631STom Van Eyck { 3089b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3090b0563631STom Van Eyck 3091b0563631STom Van Eyck if (PSA_ALG_IS_SIGN_HASH(alg)) { 3092b0563631STom Van Eyck size_t hash_length; 3093b0563631STom Van Eyck uint8_t hash[PSA_HASH_MAX_SIZE]; 3094b0563631STom Van Eyck 3095b0563631STom Van Eyck status = psa_driver_wrapper_hash_compute( 3096b0563631STom Van Eyck PSA_ALG_SIGN_GET_HASH(alg), 3097b0563631STom Van Eyck input, input_length, 3098b0563631STom Van Eyck hash, sizeof(hash), &hash_length); 3099b0563631STom Van Eyck 3100b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3101b0563631STom Van Eyck return status; 3102b0563631STom Van Eyck } 3103b0563631STom Van Eyck 3104b0563631STom Van Eyck return psa_driver_wrapper_sign_hash( 3105b0563631STom Van Eyck attributes, key_buffer, key_buffer_size, 3106b0563631STom Van Eyck alg, hash, hash_length, 3107b0563631STom Van Eyck signature, signature_size, signature_length); 3108b0563631STom Van Eyck } 3109b0563631STom Van Eyck 3110b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 3111b0563631STom Van Eyck } 3112b0563631STom Van Eyck 3113b0563631STom Van Eyck psa_status_t psa_sign_message(mbedtls_svc_key_id_t key, 3114b0563631STom Van Eyck psa_algorithm_t alg, 3115b0563631STom Van Eyck const uint8_t *input_external, 3116b0563631STom Van Eyck size_t input_length, 3117b0563631STom Van Eyck uint8_t *signature_external, 3118b0563631STom Van Eyck size_t signature_size, 3119b0563631STom Van Eyck size_t *signature_length) 3120b0563631STom Van Eyck { 3121b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3122b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 3123b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(signature_external, signature); 3124b0563631STom Van Eyck 3125b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 3126b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature); 3127b0563631STom Van Eyck status = psa_sign_internal(key, 1, alg, input, input_length, signature, 3128b0563631STom Van Eyck signature_size, signature_length); 3129b0563631STom Van Eyck 3130b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 3131b0563631STom Van Eyck exit: 3132b0563631STom Van Eyck #endif 3133b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 3134b0563631STom Van Eyck LOCAL_OUTPUT_FREE(signature_external, signature); 3135b0563631STom Van Eyck return status; 3136b0563631STom Van Eyck } 3137b0563631STom Van Eyck 3138b0563631STom Van Eyck psa_status_t psa_verify_message_builtin( 3139b0563631STom Van Eyck const psa_key_attributes_t *attributes, 3140b0563631STom Van Eyck const uint8_t *key_buffer, 3141b0563631STom Van Eyck size_t key_buffer_size, 3142b0563631STom Van Eyck psa_algorithm_t alg, 3143b0563631STom Van Eyck const uint8_t *input, 3144b0563631STom Van Eyck size_t input_length, 3145b0563631STom Van Eyck const uint8_t *signature, 3146b0563631STom Van Eyck size_t signature_length) 3147b0563631STom Van Eyck { 3148b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3149b0563631STom Van Eyck 3150b0563631STom Van Eyck if (PSA_ALG_IS_SIGN_HASH(alg)) { 3151b0563631STom Van Eyck size_t hash_length; 3152b0563631STom Van Eyck uint8_t hash[PSA_HASH_MAX_SIZE]; 3153b0563631STom Van Eyck 3154b0563631STom Van Eyck status = psa_driver_wrapper_hash_compute( 3155b0563631STom Van Eyck PSA_ALG_SIGN_GET_HASH(alg), 3156b0563631STom Van Eyck input, input_length, 3157b0563631STom Van Eyck hash, sizeof(hash), &hash_length); 3158b0563631STom Van Eyck 3159b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3160b0563631STom Van Eyck return status; 3161b0563631STom Van Eyck } 3162b0563631STom Van Eyck 3163b0563631STom Van Eyck return psa_driver_wrapper_verify_hash( 3164b0563631STom Van Eyck attributes, key_buffer, key_buffer_size, 3165b0563631STom Van Eyck alg, hash, hash_length, 3166b0563631STom Van Eyck signature, signature_length); 3167b0563631STom Van Eyck } 3168b0563631STom Van Eyck 3169b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 3170b0563631STom Van Eyck } 3171b0563631STom Van Eyck 3172b0563631STom Van Eyck psa_status_t psa_verify_message(mbedtls_svc_key_id_t key, 3173b0563631STom Van Eyck psa_algorithm_t alg, 3174b0563631STom Van Eyck const uint8_t *input_external, 3175b0563631STom Van Eyck size_t input_length, 3176b0563631STom Van Eyck const uint8_t *signature_external, 3177b0563631STom Van Eyck size_t signature_length) 3178b0563631STom Van Eyck { 3179b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3180b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 3181b0563631STom Van Eyck LOCAL_INPUT_DECLARE(signature_external, signature); 3182b0563631STom Van Eyck 3183b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 3184b0563631STom Van Eyck LOCAL_INPUT_ALLOC(signature_external, signature_length, signature); 3185b0563631STom Van Eyck status = psa_verify_internal(key, 1, alg, input, input_length, signature, 3186b0563631STom Van Eyck signature_length); 3187b0563631STom Van Eyck 3188b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 3189b0563631STom Van Eyck exit: 3190b0563631STom Van Eyck #endif 3191b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 3192b0563631STom Van Eyck LOCAL_INPUT_FREE(signature_external, signature); 3193b0563631STom Van Eyck 3194b0563631STom Van Eyck return status; 3195b0563631STom Van Eyck } 3196b0563631STom Van Eyck 3197b0563631STom Van Eyck psa_status_t psa_sign_hash_builtin( 3198b0563631STom Van Eyck const psa_key_attributes_t *attributes, 3199b0563631STom Van Eyck const uint8_t *key_buffer, size_t key_buffer_size, 3200b0563631STom Van Eyck psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, 3201b0563631STom Van Eyck uint8_t *signature, size_t signature_size, size_t *signature_length) 3202b0563631STom Van Eyck { 3203b0563631STom Van Eyck if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 3204b0563631STom Van Eyck if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || 3205b0563631STom Van Eyck PSA_ALG_IS_RSA_PSS(alg)) { 3206b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ 3207b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) 3208b0563631STom Van Eyck return mbedtls_psa_rsa_sign_hash( 3209b0563631STom Van Eyck attributes, 3210b0563631STom Van Eyck key_buffer, key_buffer_size, 3211b0563631STom Van Eyck alg, hash, hash_length, 3212b0563631STom Van Eyck signature, signature_size, signature_length); 3213b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || 3214b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */ 3215b0563631STom Van Eyck } else { 3216b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 3217b0563631STom Van Eyck } 3218b0563631STom Van Eyck } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) { 3219b0563631STom Van Eyck if (PSA_ALG_IS_ECDSA(alg)) { 3220b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 3221b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) 3222b0563631STom Van Eyck return mbedtls_psa_ecdsa_sign_hash( 3223b0563631STom Van Eyck attributes, 3224b0563631STom Van Eyck key_buffer, key_buffer_size, 3225b0563631STom Van Eyck alg, hash, hash_length, 3226b0563631STom Van Eyck signature, signature_size, signature_length); 3227b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 3228b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ 3229b0563631STom Van Eyck } else { 3230b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 3231b0563631STom Van Eyck } 3232b0563631STom Van Eyck } 3233b0563631STom Van Eyck 3234b0563631STom Van Eyck (void) key_buffer; 3235b0563631STom Van Eyck (void) key_buffer_size; 3236b0563631STom Van Eyck (void) hash; 3237b0563631STom Van Eyck (void) hash_length; 3238b0563631STom Van Eyck (void) signature; 3239b0563631STom Van Eyck (void) signature_size; 3240b0563631STom Van Eyck (void) signature_length; 3241b0563631STom Van Eyck 3242b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 3243b0563631STom Van Eyck } 3244b0563631STom Van Eyck 3245b0563631STom Van Eyck psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, 3246b0563631STom Van Eyck psa_algorithm_t alg, 3247b0563631STom Van Eyck const uint8_t *hash_external, 3248b0563631STom Van Eyck size_t hash_length, 3249b0563631STom Van Eyck uint8_t *signature_external, 3250b0563631STom Van Eyck size_t signature_size, 3251b0563631STom Van Eyck size_t *signature_length) 3252b0563631STom Van Eyck { 3253b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3254b0563631STom Van Eyck LOCAL_INPUT_DECLARE(hash_external, hash); 3255b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(signature_external, signature); 3256b0563631STom Van Eyck 3257b0563631STom Van Eyck LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); 3258b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature); 3259b0563631STom Van Eyck status = psa_sign_internal(key, 0, alg, hash, hash_length, signature, 3260b0563631STom Van Eyck signature_size, signature_length); 3261b0563631STom Van Eyck 3262b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 3263b0563631STom Van Eyck exit: 3264b0563631STom Van Eyck #endif 3265b0563631STom Van Eyck LOCAL_INPUT_FREE(hash_external, hash); 3266b0563631STom Van Eyck LOCAL_OUTPUT_FREE(signature_external, signature); 3267b0563631STom Van Eyck 3268b0563631STom Van Eyck return status; 3269b0563631STom Van Eyck } 3270b0563631STom Van Eyck 3271b0563631STom Van Eyck psa_status_t psa_verify_hash_builtin( 3272b0563631STom Van Eyck const psa_key_attributes_t *attributes, 3273b0563631STom Van Eyck const uint8_t *key_buffer, size_t key_buffer_size, 3274b0563631STom Van Eyck psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, 3275b0563631STom Van Eyck const uint8_t *signature, size_t signature_length) 3276b0563631STom Van Eyck { 3277b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_RSA(attributes->type)) { 3278b0563631STom Van Eyck if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || 3279b0563631STom Van Eyck PSA_ALG_IS_RSA_PSS(alg)) { 3280b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ 3281b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) 3282b0563631STom Van Eyck return mbedtls_psa_rsa_verify_hash( 3283b0563631STom Van Eyck attributes, 3284b0563631STom Van Eyck key_buffer, key_buffer_size, 3285b0563631STom Van Eyck alg, hash, hash_length, 3286b0563631STom Van Eyck signature, signature_length); 3287b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || 3288b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */ 3289b0563631STom Van Eyck } else { 3290b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 3291b0563631STom Van Eyck } 3292b0563631STom Van Eyck } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) { 3293b0563631STom Van Eyck if (PSA_ALG_IS_ECDSA(alg)) { 3294b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 3295b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) 3296b0563631STom Van Eyck return mbedtls_psa_ecdsa_verify_hash( 3297b0563631STom Van Eyck attributes, 3298b0563631STom Van Eyck key_buffer, key_buffer_size, 3299b0563631STom Van Eyck alg, hash, hash_length, 3300b0563631STom Van Eyck signature, signature_length); 3301b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 3302b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ 3303b0563631STom Van Eyck } else { 3304b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 3305b0563631STom Van Eyck } 3306b0563631STom Van Eyck } 3307b0563631STom Van Eyck 3308b0563631STom Van Eyck (void) key_buffer; 3309b0563631STom Van Eyck (void) key_buffer_size; 3310b0563631STom Van Eyck (void) hash; 3311b0563631STom Van Eyck (void) hash_length; 3312b0563631STom Van Eyck (void) signature; 3313b0563631STom Van Eyck (void) signature_length; 3314b0563631STom Van Eyck 3315b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 3316b0563631STom Van Eyck } 3317b0563631STom Van Eyck 3318b0563631STom Van Eyck psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, 3319b0563631STom Van Eyck psa_algorithm_t alg, 3320b0563631STom Van Eyck const uint8_t *hash_external, 3321b0563631STom Van Eyck size_t hash_length, 3322b0563631STom Van Eyck const uint8_t *signature_external, 3323b0563631STom Van Eyck size_t signature_length) 3324b0563631STom Van Eyck { 3325b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3326b0563631STom Van Eyck LOCAL_INPUT_DECLARE(hash_external, hash); 3327b0563631STom Van Eyck LOCAL_INPUT_DECLARE(signature_external, signature); 3328b0563631STom Van Eyck 3329b0563631STom Van Eyck LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); 3330b0563631STom Van Eyck LOCAL_INPUT_ALLOC(signature_external, signature_length, signature); 3331b0563631STom Van Eyck status = psa_verify_internal(key, 0, alg, hash, hash_length, signature, 3332b0563631STom Van Eyck signature_length); 3333b0563631STom Van Eyck 3334b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 3335b0563631STom Van Eyck exit: 3336b0563631STom Van Eyck #endif 3337b0563631STom Van Eyck LOCAL_INPUT_FREE(hash_external, hash); 3338b0563631STom Van Eyck LOCAL_INPUT_FREE(signature_external, signature); 3339b0563631STom Van Eyck 3340b0563631STom Van Eyck return status; 3341b0563631STom Van Eyck } 3342b0563631STom Van Eyck 3343b0563631STom Van Eyck psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, 3344b0563631STom Van Eyck psa_algorithm_t alg, 3345b0563631STom Van Eyck const uint8_t *input_external, 3346b0563631STom Van Eyck size_t input_length, 3347b0563631STom Van Eyck const uint8_t *salt_external, 3348b0563631STom Van Eyck size_t salt_length, 3349b0563631STom Van Eyck uint8_t *output_external, 3350b0563631STom Van Eyck size_t output_size, 3351b0563631STom Van Eyck size_t *output_length) 3352b0563631STom Van Eyck { 3353b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3354b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 3355b0563631STom Van Eyck psa_key_slot_t *slot; 3356b0563631STom Van Eyck 3357b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 3358b0563631STom Van Eyck LOCAL_INPUT_DECLARE(salt_external, salt); 3359b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 3360b0563631STom Van Eyck 3361b0563631STom Van Eyck (void) input; 3362b0563631STom Van Eyck (void) input_length; 3363b0563631STom Van Eyck (void) salt; 3364b0563631STom Van Eyck (void) output; 3365b0563631STom Van Eyck (void) output_size; 3366b0563631STom Van Eyck 3367b0563631STom Van Eyck *output_length = 0; 3368b0563631STom Van Eyck 3369b0563631STom Van Eyck if (!PSA_ALG_IS_RSA_OAEP(alg) && salt_length != 0) { 3370b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 3371b0563631STom Van Eyck } 3372b0563631STom Van Eyck 3373b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy( 3374b0563631STom Van Eyck key, &slot, PSA_KEY_USAGE_ENCRYPT, alg); 3375b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3376b0563631STom Van Eyck return status; 3377b0563631STom Van Eyck } 3378b0563631STom Van Eyck if (!(PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type) || 3379b0563631STom Van Eyck PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type))) { 3380b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 3381b0563631STom Van Eyck goto exit; 3382b0563631STom Van Eyck } 3383b0563631STom Van Eyck 3384b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 3385b0563631STom Van Eyck LOCAL_INPUT_ALLOC(salt_external, salt_length, salt); 3386b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_size, output); 3387b0563631STom Van Eyck 3388b0563631STom Van Eyck status = psa_driver_wrapper_asymmetric_encrypt( 3389b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 3390b0563631STom Van Eyck alg, input, input_length, salt, salt_length, 3391b0563631STom Van Eyck output, output_size, output_length); 3392b0563631STom Van Eyck exit: 3393b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 3394b0563631STom Van Eyck 3395b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 3396b0563631STom Van Eyck LOCAL_INPUT_FREE(salt_external, salt); 3397b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 3398b0563631STom Van Eyck 3399b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 3400b0563631STom Van Eyck } 3401b0563631STom Van Eyck 3402b0563631STom Van Eyck psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, 3403b0563631STom Van Eyck psa_algorithm_t alg, 3404b0563631STom Van Eyck const uint8_t *input_external, 3405b0563631STom Van Eyck size_t input_length, 3406b0563631STom Van Eyck const uint8_t *salt_external, 3407b0563631STom Van Eyck size_t salt_length, 3408b0563631STom Van Eyck uint8_t *output_external, 3409b0563631STom Van Eyck size_t output_size, 3410b0563631STom Van Eyck size_t *output_length) 3411b0563631STom Van Eyck { 3412b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3413b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 3414b0563631STom Van Eyck psa_key_slot_t *slot; 3415b0563631STom Van Eyck 3416b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 3417b0563631STom Van Eyck LOCAL_INPUT_DECLARE(salt_external, salt); 3418b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 3419b0563631STom Van Eyck 3420b0563631STom Van Eyck (void) input; 3421b0563631STom Van Eyck (void) input_length; 3422b0563631STom Van Eyck (void) salt; 3423b0563631STom Van Eyck (void) output; 3424b0563631STom Van Eyck (void) output_size; 3425b0563631STom Van Eyck 3426b0563631STom Van Eyck *output_length = 0; 3427b0563631STom Van Eyck 3428b0563631STom Van Eyck if (!PSA_ALG_IS_RSA_OAEP(alg) && salt_length != 0) { 3429b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 3430b0563631STom Van Eyck } 3431b0563631STom Van Eyck 3432b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy( 3433b0563631STom Van Eyck key, &slot, PSA_KEY_USAGE_DECRYPT, alg); 3434b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3435b0563631STom Van Eyck return status; 3436b0563631STom Van Eyck } 3437b0563631STom Van Eyck if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) { 3438b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 3439b0563631STom Van Eyck goto exit; 3440b0563631STom Van Eyck } 3441b0563631STom Van Eyck 3442b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 3443b0563631STom Van Eyck LOCAL_INPUT_ALLOC(salt_external, salt_length, salt); 3444b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_size, output); 3445b0563631STom Van Eyck 3446b0563631STom Van Eyck status = psa_driver_wrapper_asymmetric_decrypt( 3447b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 3448b0563631STom Van Eyck alg, input, input_length, salt, salt_length, 3449b0563631STom Van Eyck output, output_size, output_length); 3450b0563631STom Van Eyck 3451b0563631STom Van Eyck exit: 3452b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 3453b0563631STom Van Eyck 3454b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 3455b0563631STom Van Eyck LOCAL_INPUT_FREE(salt_external, salt); 3456b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 3457b0563631STom Van Eyck 3458b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 3459b0563631STom Van Eyck } 3460b0563631STom Van Eyck 3461b0563631STom Van Eyck /****************************************************************/ 3462b0563631STom Van Eyck /* Asymmetric interruptible cryptography */ 3463b0563631STom Van Eyck /****************************************************************/ 3464b0563631STom Van Eyck 3465b0563631STom Van Eyck static uint32_t psa_interruptible_max_ops = PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED; 3466b0563631STom Van Eyck 3467b0563631STom Van Eyck void psa_interruptible_set_max_ops(uint32_t max_ops) 3468b0563631STom Van Eyck { 3469b0563631STom Van Eyck psa_interruptible_max_ops = max_ops; 3470b0563631STom Van Eyck } 3471b0563631STom Van Eyck 3472b0563631STom Van Eyck uint32_t psa_interruptible_get_max_ops(void) 3473b0563631STom Van Eyck { 3474b0563631STom Van Eyck return psa_interruptible_max_ops; 3475b0563631STom Van Eyck } 3476b0563631STom Van Eyck 3477b0563631STom Van Eyck uint32_t psa_sign_hash_get_num_ops( 3478b0563631STom Van Eyck const psa_sign_hash_interruptible_operation_t *operation) 3479b0563631STom Van Eyck { 3480b0563631STom Van Eyck return operation->num_ops; 3481b0563631STom Van Eyck } 3482b0563631STom Van Eyck 3483b0563631STom Van Eyck uint32_t psa_verify_hash_get_num_ops( 3484b0563631STom Van Eyck const psa_verify_hash_interruptible_operation_t *operation) 3485b0563631STom Van Eyck { 3486b0563631STom Van Eyck return operation->num_ops; 3487b0563631STom Van Eyck } 3488b0563631STom Van Eyck 3489b0563631STom Van Eyck static psa_status_t psa_sign_hash_abort_internal( 3490b0563631STom Van Eyck psa_sign_hash_interruptible_operation_t *operation) 3491b0563631STom Van Eyck { 3492b0563631STom Van Eyck if (operation->id == 0) { 3493b0563631STom Van Eyck /* The object has (apparently) been initialized but it is not (yet) 3494b0563631STom Van Eyck * in use. It's ok to call abort on such an object, and there's 3495b0563631STom Van Eyck * nothing to do. */ 3496b0563631STom Van Eyck return PSA_SUCCESS; 3497b0563631STom Van Eyck } 3498b0563631STom Van Eyck 3499b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3500b0563631STom Van Eyck 3501b0563631STom Van Eyck status = psa_driver_wrapper_sign_hash_abort(operation); 3502b0563631STom Van Eyck 3503b0563631STom Van Eyck operation->id = 0; 3504b0563631STom Van Eyck 3505b0563631STom Van Eyck /* Do not clear either the error_occurred or num_ops elements here as they 3506b0563631STom Van Eyck * only want to be cleared by the application calling abort, not by abort 3507b0563631STom Van Eyck * being called at completion of an operation. */ 3508b0563631STom Van Eyck 3509b0563631STom Van Eyck return status; 3510b0563631STom Van Eyck } 3511b0563631STom Van Eyck 3512b0563631STom Van Eyck psa_status_t psa_sign_hash_start( 3513b0563631STom Van Eyck psa_sign_hash_interruptible_operation_t *operation, 3514b0563631STom Van Eyck mbedtls_svc_key_id_t key, psa_algorithm_t alg, 3515b0563631STom Van Eyck const uint8_t *hash_external, size_t hash_length) 3516b0563631STom Van Eyck { 3517b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3518b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 3519b0563631STom Van Eyck psa_key_slot_t *slot; 3520b0563631STom Van Eyck 3521b0563631STom Van Eyck LOCAL_INPUT_DECLARE(hash_external, hash); 3522b0563631STom Van Eyck 3523b0563631STom Van Eyck /* Check that start has not been previously called, or operation has not 3524b0563631STom Van Eyck * previously errored. */ 3525b0563631STom Van Eyck if (operation->id != 0 || operation->error_occurred) { 3526b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 3527b0563631STom Van Eyck } 3528b0563631STom Van Eyck 3529b0563631STom Van Eyck status = psa_sign_verify_check_alg(0, alg); 3530b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3531b0563631STom Van Eyck operation->error_occurred = 1; 3532b0563631STom Van Eyck return status; 3533b0563631STom Van Eyck } 3534b0563631STom Van Eyck 3535b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy(key, &slot, 3536b0563631STom Van Eyck PSA_KEY_USAGE_SIGN_HASH, 3537b0563631STom Van Eyck alg); 3538b0563631STom Van Eyck 3539b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3540b0563631STom Van Eyck goto exit; 3541b0563631STom Van Eyck } 3542b0563631STom Van Eyck 3543b0563631STom Van Eyck if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) { 3544b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 3545b0563631STom Van Eyck goto exit; 3546b0563631STom Van Eyck } 3547b0563631STom Van Eyck 3548b0563631STom Van Eyck LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); 3549b0563631STom Van Eyck 3550b0563631STom Van Eyck /* Ensure ops count gets reset, in case of operation re-use. */ 3551b0563631STom Van Eyck operation->num_ops = 0; 3552b0563631STom Van Eyck 3553b0563631STom Van Eyck status = psa_driver_wrapper_sign_hash_start(operation, &slot->attr, 3554b0563631STom Van Eyck slot->key.data, 3555b0563631STom Van Eyck slot->key.bytes, alg, 3556b0563631STom Van Eyck hash, hash_length); 3557b0563631STom Van Eyck exit: 3558b0563631STom Van Eyck 3559b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3560b0563631STom Van Eyck operation->error_occurred = 1; 3561b0563631STom Van Eyck psa_sign_hash_abort_internal(operation); 3562b0563631STom Van Eyck } 3563b0563631STom Van Eyck 3564b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 3565b0563631STom Van Eyck 3566b0563631STom Van Eyck if (unlock_status != PSA_SUCCESS) { 3567b0563631STom Van Eyck operation->error_occurred = 1; 3568b0563631STom Van Eyck } 3569b0563631STom Van Eyck 3570b0563631STom Van Eyck LOCAL_INPUT_FREE(hash_external, hash); 3571b0563631STom Van Eyck 3572b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 3573b0563631STom Van Eyck } 3574b0563631STom Van Eyck 3575b0563631STom Van Eyck 3576b0563631STom Van Eyck psa_status_t psa_sign_hash_complete( 3577b0563631STom Van Eyck psa_sign_hash_interruptible_operation_t *operation, 3578b0563631STom Van Eyck uint8_t *signature_external, size_t signature_size, 3579b0563631STom Van Eyck size_t *signature_length) 3580b0563631STom Van Eyck { 3581b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3582b0563631STom Van Eyck 3583b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(signature_external, signature); 3584b0563631STom Van Eyck 3585b0563631STom Van Eyck *signature_length = 0; 3586b0563631STom Van Eyck 3587b0563631STom Van Eyck /* Check that start has been called first, and that operation has not 3588b0563631STom Van Eyck * previously errored. */ 3589b0563631STom Van Eyck if (operation->id == 0 || operation->error_occurred) { 3590b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 3591b0563631STom Van Eyck goto exit; 3592b0563631STom Van Eyck } 3593b0563631STom Van Eyck 3594b0563631STom Van Eyck /* Immediately reject a zero-length signature buffer. This guarantees that 3595b0563631STom Van Eyck * signature must be a valid pointer. */ 3596b0563631STom Van Eyck if (signature_size == 0) { 3597b0563631STom Van Eyck status = PSA_ERROR_BUFFER_TOO_SMALL; 3598b0563631STom Van Eyck goto exit; 3599b0563631STom Van Eyck } 3600b0563631STom Van Eyck 3601b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature); 3602b0563631STom Van Eyck 3603b0563631STom Van Eyck status = psa_driver_wrapper_sign_hash_complete(operation, signature, 3604b0563631STom Van Eyck signature_size, 3605b0563631STom Van Eyck signature_length); 3606b0563631STom Van Eyck 3607b0563631STom Van Eyck /* Update ops count with work done. */ 3608b0563631STom Van Eyck operation->num_ops = psa_driver_wrapper_sign_hash_get_num_ops(operation); 3609b0563631STom Van Eyck 3610b0563631STom Van Eyck exit: 3611b0563631STom Van Eyck 3612b0563631STom Van Eyck if (signature != NULL) { 3613b0563631STom Van Eyck psa_wipe_tag_output_buffer(signature, status, signature_size, 3614b0563631STom Van Eyck *signature_length); 3615b0563631STom Van Eyck } 3616b0563631STom Van Eyck 3617b0563631STom Van Eyck if (status != PSA_OPERATION_INCOMPLETE) { 3618b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3619b0563631STom Van Eyck operation->error_occurred = 1; 3620b0563631STom Van Eyck } 3621b0563631STom Van Eyck 3622b0563631STom Van Eyck psa_sign_hash_abort_internal(operation); 3623b0563631STom Van Eyck } 3624b0563631STom Van Eyck 3625b0563631STom Van Eyck LOCAL_OUTPUT_FREE(signature_external, signature); 3626b0563631STom Van Eyck 3627b0563631STom Van Eyck return status; 3628b0563631STom Van Eyck } 3629b0563631STom Van Eyck 3630b0563631STom Van Eyck psa_status_t psa_sign_hash_abort( 3631b0563631STom Van Eyck psa_sign_hash_interruptible_operation_t *operation) 3632b0563631STom Van Eyck { 3633b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3634b0563631STom Van Eyck 3635b0563631STom Van Eyck status = psa_sign_hash_abort_internal(operation); 3636b0563631STom Van Eyck 3637b0563631STom Van Eyck /* We clear the number of ops done here, so that it is not cleared when 3638b0563631STom Van Eyck * the operation fails or succeeds, only on manual abort. */ 3639b0563631STom Van Eyck operation->num_ops = 0; 3640b0563631STom Van Eyck 3641b0563631STom Van Eyck /* Likewise, failure state. */ 3642b0563631STom Van Eyck operation->error_occurred = 0; 3643b0563631STom Van Eyck 3644b0563631STom Van Eyck return status; 3645b0563631STom Van Eyck } 3646b0563631STom Van Eyck 3647b0563631STom Van Eyck static psa_status_t psa_verify_hash_abort_internal( 3648b0563631STom Van Eyck psa_verify_hash_interruptible_operation_t *operation) 3649b0563631STom Van Eyck { 3650b0563631STom Van Eyck if (operation->id == 0) { 3651b0563631STom Van Eyck /* The object has (apparently) been initialized but it is not (yet) 3652b0563631STom Van Eyck * in use. It's ok to call abort on such an object, and there's 3653b0563631STom Van Eyck * nothing to do. */ 3654b0563631STom Van Eyck return PSA_SUCCESS; 3655b0563631STom Van Eyck } 3656b0563631STom Van Eyck 3657b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3658b0563631STom Van Eyck 3659b0563631STom Van Eyck status = psa_driver_wrapper_verify_hash_abort(operation); 3660b0563631STom Van Eyck 3661b0563631STom Van Eyck operation->id = 0; 3662b0563631STom Van Eyck 3663b0563631STom Van Eyck /* Do not clear either the error_occurred or num_ops elements here as they 3664b0563631STom Van Eyck * only want to be cleared by the application calling abort, not by abort 3665b0563631STom Van Eyck * being called at completion of an operation. */ 3666b0563631STom Van Eyck 3667b0563631STom Van Eyck return status; 3668b0563631STom Van Eyck } 3669b0563631STom Van Eyck 3670b0563631STom Van Eyck psa_status_t psa_verify_hash_start( 3671b0563631STom Van Eyck psa_verify_hash_interruptible_operation_t *operation, 3672b0563631STom Van Eyck mbedtls_svc_key_id_t key, psa_algorithm_t alg, 3673b0563631STom Van Eyck const uint8_t *hash_external, size_t hash_length, 3674b0563631STom Van Eyck const uint8_t *signature_external, size_t signature_length) 3675b0563631STom Van Eyck { 3676b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3677b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 3678b0563631STom Van Eyck psa_key_slot_t *slot; 3679b0563631STom Van Eyck 3680b0563631STom Van Eyck LOCAL_INPUT_DECLARE(hash_external, hash); 3681b0563631STom Van Eyck LOCAL_INPUT_DECLARE(signature_external, signature); 3682b0563631STom Van Eyck 3683b0563631STom Van Eyck /* Check that start has not been previously called, or operation has not 3684b0563631STom Van Eyck * previously errored. */ 3685b0563631STom Van Eyck if (operation->id != 0 || operation->error_occurred) { 3686b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 3687b0563631STom Van Eyck } 3688b0563631STom Van Eyck 3689b0563631STom Van Eyck status = psa_sign_verify_check_alg(0, alg); 3690b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3691b0563631STom Van Eyck operation->error_occurred = 1; 3692b0563631STom Van Eyck return status; 3693b0563631STom Van Eyck } 3694b0563631STom Van Eyck 3695b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy(key, &slot, 3696b0563631STom Van Eyck PSA_KEY_USAGE_VERIFY_HASH, 3697b0563631STom Van Eyck alg); 3698b0563631STom Van Eyck 3699b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3700b0563631STom Van Eyck operation->error_occurred = 1; 3701b0563631STom Van Eyck return status; 3702b0563631STom Van Eyck } 3703b0563631STom Van Eyck 3704b0563631STom Van Eyck LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); 3705b0563631STom Van Eyck LOCAL_INPUT_ALLOC(signature_external, signature_length, signature); 3706b0563631STom Van Eyck 3707b0563631STom Van Eyck /* Ensure ops count gets reset, in case of operation re-use. */ 3708b0563631STom Van Eyck operation->num_ops = 0; 3709b0563631STom Van Eyck 3710b0563631STom Van Eyck status = psa_driver_wrapper_verify_hash_start(operation, &slot->attr, 3711b0563631STom Van Eyck slot->key.data, 3712b0563631STom Van Eyck slot->key.bytes, 3713b0563631STom Van Eyck alg, hash, hash_length, 3714b0563631STom Van Eyck signature, signature_length); 3715b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 3716b0563631STom Van Eyck exit: 3717b0563631STom Van Eyck #endif 3718b0563631STom Van Eyck 3719b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3720b0563631STom Van Eyck operation->error_occurred = 1; 3721b0563631STom Van Eyck psa_verify_hash_abort_internal(operation); 3722b0563631STom Van Eyck } 3723b0563631STom Van Eyck 3724b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 3725b0563631STom Van Eyck 3726b0563631STom Van Eyck if (unlock_status != PSA_SUCCESS) { 3727b0563631STom Van Eyck operation->error_occurred = 1; 3728b0563631STom Van Eyck } 3729b0563631STom Van Eyck 3730b0563631STom Van Eyck LOCAL_INPUT_FREE(hash_external, hash); 3731b0563631STom Van Eyck LOCAL_INPUT_FREE(signature_external, signature); 3732b0563631STom Van Eyck 3733b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 3734b0563631STom Van Eyck } 3735b0563631STom Van Eyck 3736b0563631STom Van Eyck psa_status_t psa_verify_hash_complete( 3737b0563631STom Van Eyck psa_verify_hash_interruptible_operation_t *operation) 3738b0563631STom Van Eyck { 3739b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3740b0563631STom Van Eyck 3741b0563631STom Van Eyck /* Check that start has been called first, and that operation has not 3742b0563631STom Van Eyck * previously errored. */ 3743b0563631STom Van Eyck if (operation->id == 0 || operation->error_occurred) { 3744b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 3745b0563631STom Van Eyck goto exit; 3746b0563631STom Van Eyck } 3747b0563631STom Van Eyck 3748b0563631STom Van Eyck status = psa_driver_wrapper_verify_hash_complete(operation); 3749b0563631STom Van Eyck 3750b0563631STom Van Eyck /* Update ops count with work done. */ 3751b0563631STom Van Eyck operation->num_ops = psa_driver_wrapper_verify_hash_get_num_ops( 3752b0563631STom Van Eyck operation); 3753b0563631STom Van Eyck 3754b0563631STom Van Eyck exit: 3755b0563631STom Van Eyck 3756b0563631STom Van Eyck if (status != PSA_OPERATION_INCOMPLETE) { 3757b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3758b0563631STom Van Eyck operation->error_occurred = 1; 3759b0563631STom Van Eyck } 3760b0563631STom Van Eyck 3761b0563631STom Van Eyck psa_verify_hash_abort_internal(operation); 3762b0563631STom Van Eyck } 3763b0563631STom Van Eyck 3764b0563631STom Van Eyck return status; 3765b0563631STom Van Eyck } 3766b0563631STom Van Eyck 3767b0563631STom Van Eyck psa_status_t psa_verify_hash_abort( 3768b0563631STom Van Eyck psa_verify_hash_interruptible_operation_t *operation) 3769b0563631STom Van Eyck { 3770b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3771b0563631STom Van Eyck 3772b0563631STom Van Eyck status = psa_verify_hash_abort_internal(operation); 3773b0563631STom Van Eyck 3774b0563631STom Van Eyck /* We clear the number of ops done here, so that it is not cleared when 3775b0563631STom Van Eyck * the operation fails or succeeds, only on manual abort. */ 3776b0563631STom Van Eyck operation->num_ops = 0; 3777b0563631STom Van Eyck 3778b0563631STom Van Eyck /* Likewise, failure state. */ 3779b0563631STom Van Eyck operation->error_occurred = 0; 3780b0563631STom Van Eyck 3781b0563631STom Van Eyck return status; 3782b0563631STom Van Eyck } 3783b0563631STom Van Eyck 3784b0563631STom Van Eyck /****************************************************************/ 3785b0563631STom Van Eyck /* Asymmetric interruptible cryptography internal */ 3786b0563631STom Van Eyck /* implementations */ 3787b0563631STom Van Eyck /****************************************************************/ 3788b0563631STom Van Eyck 3789b0563631STom Van Eyck void mbedtls_psa_interruptible_set_max_ops(uint32_t max_ops) 3790b0563631STom Van Eyck { 3791b0563631STom Van Eyck 3792b0563631STom Van Eyck #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 3793b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ 3794b0563631STom Van Eyck defined(MBEDTLS_ECP_RESTARTABLE) 3795b0563631STom Van Eyck 3796b0563631STom Van Eyck /* Internal implementation uses zero to indicate infinite number max ops, 3797b0563631STom Van Eyck * therefore avoid this value, and set to minimum possible. */ 3798b0563631STom Van Eyck if (max_ops == 0) { 3799b0563631STom Van Eyck max_ops = 1; 3800b0563631STom Van Eyck } 3801b0563631STom Van Eyck 3802b0563631STom Van Eyck mbedtls_ecp_set_max_ops(max_ops); 3803b0563631STom Van Eyck #else 3804b0563631STom Van Eyck (void) max_ops; 3805b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 3806b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && 3807b0563631STom Van Eyck * defined( MBEDTLS_ECP_RESTARTABLE ) */ 3808b0563631STom Van Eyck } 3809b0563631STom Van Eyck 3810b0563631STom Van Eyck uint32_t mbedtls_psa_sign_hash_get_num_ops( 3811b0563631STom Van Eyck const mbedtls_psa_sign_hash_interruptible_operation_t *operation) 3812b0563631STom Van Eyck { 3813b0563631STom Van Eyck #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 3814b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ 3815b0563631STom Van Eyck defined(MBEDTLS_ECP_RESTARTABLE) 3816b0563631STom Van Eyck 3817b0563631STom Van Eyck return operation->num_ops; 3818b0563631STom Van Eyck #else 3819b0563631STom Van Eyck (void) operation; 3820b0563631STom Van Eyck return 0; 3821b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 3822b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && 3823b0563631STom Van Eyck * defined( MBEDTLS_ECP_RESTARTABLE ) */ 3824b0563631STom Van Eyck } 3825b0563631STom Van Eyck 3826b0563631STom Van Eyck uint32_t mbedtls_psa_verify_hash_get_num_ops( 3827b0563631STom Van Eyck const mbedtls_psa_verify_hash_interruptible_operation_t *operation) 3828b0563631STom Van Eyck { 3829b0563631STom Van Eyck #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 3830b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ 3831b0563631STom Van Eyck defined(MBEDTLS_ECP_RESTARTABLE) 3832b0563631STom Van Eyck 3833b0563631STom Van Eyck return operation->num_ops; 3834b0563631STom Van Eyck #else 3835b0563631STom Van Eyck (void) operation; 3836b0563631STom Van Eyck return 0; 3837b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 3838b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && 3839b0563631STom Van Eyck * defined( MBEDTLS_ECP_RESTARTABLE ) */ 3840b0563631STom Van Eyck } 3841b0563631STom Van Eyck 3842b0563631STom Van Eyck psa_status_t mbedtls_psa_sign_hash_start( 3843b0563631STom Van Eyck mbedtls_psa_sign_hash_interruptible_operation_t *operation, 3844b0563631STom Van Eyck const psa_key_attributes_t *attributes, const uint8_t *key_buffer, 3845b0563631STom Van Eyck size_t key_buffer_size, psa_algorithm_t alg, 3846b0563631STom Van Eyck const uint8_t *hash, size_t hash_length) 3847b0563631STom Van Eyck { 3848b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3849b0563631STom Van Eyck size_t required_hash_length; 3850b0563631STom Van Eyck 3851b0563631STom Van Eyck if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) { 3852b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 3853b0563631STom Van Eyck } 3854b0563631STom Van Eyck 3855b0563631STom Van Eyck if (!PSA_ALG_IS_ECDSA(alg)) { 3856b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 3857b0563631STom Van Eyck } 3858b0563631STom Van Eyck 3859b0563631STom Van Eyck #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 3860b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ 3861b0563631STom Van Eyck defined(MBEDTLS_ECP_RESTARTABLE) 3862b0563631STom Van Eyck 3863b0563631STom Van Eyck mbedtls_ecdsa_restart_init(&operation->restart_ctx); 3864b0563631STom Van Eyck 3865b0563631STom Van Eyck /* Ensure num_ops is zero'ed in case of context re-use. */ 3866b0563631STom Van Eyck operation->num_ops = 0; 3867b0563631STom Van Eyck 3868b0563631STom Van Eyck status = mbedtls_psa_ecp_load_representation(attributes->type, 3869b0563631STom Van Eyck attributes->bits, 3870b0563631STom Van Eyck key_buffer, 3871b0563631STom Van Eyck key_buffer_size, 3872b0563631STom Van Eyck &operation->ctx); 3873b0563631STom Van Eyck 3874b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3875b0563631STom Van Eyck return status; 3876b0563631STom Van Eyck } 3877b0563631STom Van Eyck 3878b0563631STom Van Eyck operation->coordinate_bytes = PSA_BITS_TO_BYTES( 3879b0563631STom Van Eyck operation->ctx->grp.nbits); 3880b0563631STom Van Eyck 3881b0563631STom Van Eyck psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg); 3882b0563631STom Van Eyck operation->md_alg = mbedtls_md_type_from_psa_alg(hash_alg); 3883b0563631STom Van Eyck operation->alg = alg; 3884b0563631STom Van Eyck 3885b0563631STom Van Eyck /* We only need to store the same length of hash as the private key size 3886b0563631STom Van Eyck * here, it would be truncated by the internal implementation anyway. */ 3887b0563631STom Van Eyck required_hash_length = (hash_length < operation->coordinate_bytes ? 3888b0563631STom Van Eyck hash_length : operation->coordinate_bytes); 3889b0563631STom Van Eyck 3890b0563631STom Van Eyck if (required_hash_length > sizeof(operation->hash)) { 3891b0563631STom Van Eyck /* Shouldn't happen, but better safe than sorry. */ 3892b0563631STom Van Eyck return PSA_ERROR_CORRUPTION_DETECTED; 3893b0563631STom Van Eyck } 3894b0563631STom Van Eyck 3895b0563631STom Van Eyck memcpy(operation->hash, hash, required_hash_length); 3896b0563631STom Van Eyck operation->hash_length = required_hash_length; 3897b0563631STom Van Eyck 3898b0563631STom Van Eyck return PSA_SUCCESS; 3899b0563631STom Van Eyck 3900b0563631STom Van Eyck #else 3901b0563631STom Van Eyck (void) operation; 3902b0563631STom Van Eyck (void) key_buffer; 3903b0563631STom Van Eyck (void) key_buffer_size; 3904b0563631STom Van Eyck (void) alg; 3905b0563631STom Van Eyck (void) hash; 3906b0563631STom Van Eyck (void) hash_length; 3907b0563631STom Van Eyck (void) status; 3908b0563631STom Van Eyck (void) required_hash_length; 3909b0563631STom Van Eyck 3910b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 3911b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 3912b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && 3913b0563631STom Van Eyck * defined( MBEDTLS_ECP_RESTARTABLE ) */ 3914b0563631STom Van Eyck } 3915b0563631STom Van Eyck 3916b0563631STom Van Eyck psa_status_t mbedtls_psa_sign_hash_complete( 3917b0563631STom Van Eyck mbedtls_psa_sign_hash_interruptible_operation_t *operation, 3918b0563631STom Van Eyck uint8_t *signature, size_t signature_size, 3919b0563631STom Van Eyck size_t *signature_length) 3920b0563631STom Van Eyck { 3921b0563631STom Van Eyck #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 3922b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ 3923b0563631STom Van Eyck defined(MBEDTLS_ECP_RESTARTABLE) 3924b0563631STom Van Eyck 3925b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3926b0563631STom Van Eyck mbedtls_mpi r; 3927b0563631STom Van Eyck mbedtls_mpi s; 3928b0563631STom Van Eyck 3929b0563631STom Van Eyck mbedtls_mpi_init(&r); 3930b0563631STom Van Eyck mbedtls_mpi_init(&s); 3931b0563631STom Van Eyck 3932b0563631STom Van Eyck /* Ensure max_ops is set to the current value (or default). */ 3933b0563631STom Van Eyck mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops()); 3934b0563631STom Van Eyck 3935b0563631STom Van Eyck if (signature_size < 2 * operation->coordinate_bytes) { 3936b0563631STom Van Eyck status = PSA_ERROR_BUFFER_TOO_SMALL; 3937b0563631STom Van Eyck goto exit; 3938b0563631STom Van Eyck } 3939b0563631STom Van Eyck 3940b0563631STom Van Eyck if (PSA_ALG_ECDSA_IS_DETERMINISTIC(operation->alg)) { 3941b0563631STom Van Eyck 3942b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) 3943b0563631STom Van Eyck status = mbedtls_to_psa_error( 3944b0563631STom Van Eyck mbedtls_ecdsa_sign_det_restartable(&operation->ctx->grp, 3945b0563631STom Van Eyck &r, 3946b0563631STom Van Eyck &s, 3947b0563631STom Van Eyck &operation->ctx->d, 3948b0563631STom Van Eyck operation->hash, 3949b0563631STom Van Eyck operation->hash_length, 3950b0563631STom Van Eyck operation->md_alg, 3951b0563631STom Van Eyck mbedtls_psa_get_random, 3952b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE, 3953b0563631STom Van Eyck &operation->restart_ctx)); 3954b0563631STom Van Eyck #else /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ 3955b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 3956b0563631STom Van Eyck goto exit; 3957b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ 3958b0563631STom Van Eyck } else { 3959b0563631STom Van Eyck status = mbedtls_to_psa_error( 3960b0563631STom Van Eyck mbedtls_ecdsa_sign_restartable(&operation->ctx->grp, 3961b0563631STom Van Eyck &r, 3962b0563631STom Van Eyck &s, 3963b0563631STom Van Eyck &operation->ctx->d, 3964b0563631STom Van Eyck operation->hash, 3965b0563631STom Van Eyck operation->hash_length, 3966b0563631STom Van Eyck mbedtls_psa_get_random, 3967b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE, 3968b0563631STom Van Eyck mbedtls_psa_get_random, 3969b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE, 3970b0563631STom Van Eyck &operation->restart_ctx)); 3971b0563631STom Van Eyck } 3972b0563631STom Van Eyck 3973b0563631STom Van Eyck /* Hide the fact that the restart context only holds a delta of number of 3974b0563631STom Van Eyck * ops done during the last operation, not an absolute value. */ 3975b0563631STom Van Eyck operation->num_ops += operation->restart_ctx.ecp.ops_done; 3976b0563631STom Van Eyck 3977b0563631STom Van Eyck if (status == PSA_SUCCESS) { 3978b0563631STom Van Eyck status = mbedtls_to_psa_error( 3979b0563631STom Van Eyck mbedtls_mpi_write_binary(&r, 3980b0563631STom Van Eyck signature, 3981b0563631STom Van Eyck operation->coordinate_bytes) 3982b0563631STom Van Eyck ); 3983b0563631STom Van Eyck 3984b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3985b0563631STom Van Eyck goto exit; 3986b0563631STom Van Eyck } 3987b0563631STom Van Eyck 3988b0563631STom Van Eyck status = mbedtls_to_psa_error( 3989b0563631STom Van Eyck mbedtls_mpi_write_binary(&s, 3990b0563631STom Van Eyck signature + 3991b0563631STom Van Eyck operation->coordinate_bytes, 3992b0563631STom Van Eyck operation->coordinate_bytes) 3993b0563631STom Van Eyck ); 3994b0563631STom Van Eyck 3995b0563631STom Van Eyck if (status != PSA_SUCCESS) { 3996b0563631STom Van Eyck goto exit; 3997b0563631STom Van Eyck } 3998b0563631STom Van Eyck 3999b0563631STom Van Eyck *signature_length = operation->coordinate_bytes * 2; 4000b0563631STom Van Eyck 4001b0563631STom Van Eyck status = PSA_SUCCESS; 4002b0563631STom Van Eyck } 4003b0563631STom Van Eyck 4004b0563631STom Van Eyck exit: 4005b0563631STom Van Eyck 4006b0563631STom Van Eyck mbedtls_mpi_free(&r); 4007b0563631STom Van Eyck mbedtls_mpi_free(&s); 4008b0563631STom Van Eyck return status; 4009b0563631STom Van Eyck 4010b0563631STom Van Eyck #else 4011b0563631STom Van Eyck 4012b0563631STom Van Eyck (void) operation; 4013b0563631STom Van Eyck (void) signature; 4014b0563631STom Van Eyck (void) signature_size; 4015b0563631STom Van Eyck (void) signature_length; 4016b0563631STom Van Eyck 4017b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 4018b0563631STom Van Eyck 4019b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 4020b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && 4021b0563631STom Van Eyck * defined( MBEDTLS_ECP_RESTARTABLE ) */ 4022b0563631STom Van Eyck } 4023b0563631STom Van Eyck 4024b0563631STom Van Eyck psa_status_t mbedtls_psa_sign_hash_abort( 4025b0563631STom Van Eyck mbedtls_psa_sign_hash_interruptible_operation_t *operation) 4026b0563631STom Van Eyck { 4027b0563631STom Van Eyck 4028b0563631STom Van Eyck #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 4029b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ 4030b0563631STom Van Eyck defined(MBEDTLS_ECP_RESTARTABLE) 4031b0563631STom Van Eyck 4032b0563631STom Van Eyck if (operation->ctx) { 4033b0563631STom Van Eyck mbedtls_ecdsa_free(operation->ctx); 4034b0563631STom Van Eyck mbedtls_free(operation->ctx); 4035b0563631STom Van Eyck operation->ctx = NULL; 4036b0563631STom Van Eyck } 4037b0563631STom Van Eyck 4038b0563631STom Van Eyck mbedtls_ecdsa_restart_free(&operation->restart_ctx); 4039b0563631STom Van Eyck 4040b0563631STom Van Eyck operation->num_ops = 0; 4041b0563631STom Van Eyck 4042b0563631STom Van Eyck return PSA_SUCCESS; 4043b0563631STom Van Eyck 4044b0563631STom Van Eyck #else 4045b0563631STom Van Eyck 4046b0563631STom Van Eyck (void) operation; 4047b0563631STom Van Eyck 4048b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 4049b0563631STom Van Eyck 4050b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 4051b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && 4052b0563631STom Van Eyck * defined( MBEDTLS_ECP_RESTARTABLE ) */ 4053b0563631STom Van Eyck } 4054b0563631STom Van Eyck 4055b0563631STom Van Eyck psa_status_t mbedtls_psa_verify_hash_start( 4056b0563631STom Van Eyck mbedtls_psa_verify_hash_interruptible_operation_t *operation, 4057b0563631STom Van Eyck const psa_key_attributes_t *attributes, 4058b0563631STom Van Eyck const uint8_t *key_buffer, size_t key_buffer_size, 4059b0563631STom Van Eyck psa_algorithm_t alg, 4060b0563631STom Van Eyck const uint8_t *hash, size_t hash_length, 4061b0563631STom Van Eyck const uint8_t *signature, size_t signature_length) 4062b0563631STom Van Eyck { 4063b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4064b0563631STom Van Eyck size_t coordinate_bytes = 0; 4065b0563631STom Van Eyck size_t required_hash_length = 0; 4066b0563631STom Van Eyck 4067b0563631STom Van Eyck if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) { 4068b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 4069b0563631STom Van Eyck } 4070b0563631STom Van Eyck 4071b0563631STom Van Eyck if (!PSA_ALG_IS_ECDSA(alg)) { 4072b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 4073b0563631STom Van Eyck } 4074b0563631STom Van Eyck 4075b0563631STom Van Eyck #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 4076b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ 4077b0563631STom Van Eyck defined(MBEDTLS_ECP_RESTARTABLE) 4078b0563631STom Van Eyck 4079b0563631STom Van Eyck mbedtls_ecdsa_restart_init(&operation->restart_ctx); 4080b0563631STom Van Eyck mbedtls_mpi_init(&operation->r); 4081b0563631STom Van Eyck mbedtls_mpi_init(&operation->s); 4082b0563631STom Van Eyck 4083b0563631STom Van Eyck /* Ensure num_ops is zero'ed in case of context re-use. */ 4084b0563631STom Van Eyck operation->num_ops = 0; 4085b0563631STom Van Eyck 4086b0563631STom Van Eyck status = mbedtls_psa_ecp_load_representation(attributes->type, 4087b0563631STom Van Eyck attributes->bits, 4088b0563631STom Van Eyck key_buffer, 4089b0563631STom Van Eyck key_buffer_size, 4090b0563631STom Van Eyck &operation->ctx); 4091b0563631STom Van Eyck 4092b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4093b0563631STom Van Eyck return status; 4094b0563631STom Van Eyck } 4095b0563631STom Van Eyck 4096b0563631STom Van Eyck coordinate_bytes = PSA_BITS_TO_BYTES(operation->ctx->grp.nbits); 4097b0563631STom Van Eyck 4098b0563631STom Van Eyck if (signature_length != 2 * coordinate_bytes) { 4099b0563631STom Van Eyck return PSA_ERROR_INVALID_SIGNATURE; 4100b0563631STom Van Eyck } 4101b0563631STom Van Eyck 4102b0563631STom Van Eyck status = mbedtls_to_psa_error( 4103b0563631STom Van Eyck mbedtls_mpi_read_binary(&operation->r, 4104b0563631STom Van Eyck signature, 4105b0563631STom Van Eyck coordinate_bytes)); 4106b0563631STom Van Eyck 4107b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4108b0563631STom Van Eyck return status; 4109b0563631STom Van Eyck } 4110b0563631STom Van Eyck 4111b0563631STom Van Eyck status = mbedtls_to_psa_error( 4112b0563631STom Van Eyck mbedtls_mpi_read_binary(&operation->s, 4113b0563631STom Van Eyck signature + 4114b0563631STom Van Eyck coordinate_bytes, 4115b0563631STom Van Eyck coordinate_bytes)); 4116b0563631STom Van Eyck 4117b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4118b0563631STom Van Eyck return status; 4119b0563631STom Van Eyck } 4120b0563631STom Van Eyck 4121b0563631STom Van Eyck status = mbedtls_psa_ecp_load_public_part(operation->ctx); 4122b0563631STom Van Eyck 4123b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4124b0563631STom Van Eyck return status; 4125b0563631STom Van Eyck } 4126b0563631STom Van Eyck 4127b0563631STom Van Eyck /* We only need to store the same length of hash as the private key size 4128b0563631STom Van Eyck * here, it would be truncated by the internal implementation anyway. */ 4129b0563631STom Van Eyck required_hash_length = (hash_length < coordinate_bytes ? hash_length : 4130b0563631STom Van Eyck coordinate_bytes); 4131b0563631STom Van Eyck 4132b0563631STom Van Eyck if (required_hash_length > sizeof(operation->hash)) { 4133b0563631STom Van Eyck /* Shouldn't happen, but better safe than sorry. */ 4134b0563631STom Van Eyck return PSA_ERROR_CORRUPTION_DETECTED; 4135b0563631STom Van Eyck } 4136b0563631STom Van Eyck 4137b0563631STom Van Eyck memcpy(operation->hash, hash, required_hash_length); 4138b0563631STom Van Eyck operation->hash_length = required_hash_length; 4139b0563631STom Van Eyck 4140b0563631STom Van Eyck return PSA_SUCCESS; 4141b0563631STom Van Eyck #else 4142b0563631STom Van Eyck (void) operation; 4143b0563631STom Van Eyck (void) key_buffer; 4144b0563631STom Van Eyck (void) key_buffer_size; 4145b0563631STom Van Eyck (void) alg; 4146b0563631STom Van Eyck (void) hash; 4147b0563631STom Van Eyck (void) hash_length; 4148b0563631STom Van Eyck (void) signature; 4149b0563631STom Van Eyck (void) signature_length; 4150b0563631STom Van Eyck (void) status; 4151b0563631STom Van Eyck (void) coordinate_bytes; 4152b0563631STom Van Eyck (void) required_hash_length; 4153b0563631STom Van Eyck 4154b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 4155b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 4156b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && 4157b0563631STom Van Eyck * defined( MBEDTLS_ECP_RESTARTABLE ) */ 4158b0563631STom Van Eyck } 4159b0563631STom Van Eyck 4160b0563631STom Van Eyck psa_status_t mbedtls_psa_verify_hash_complete( 4161b0563631STom Van Eyck mbedtls_psa_verify_hash_interruptible_operation_t *operation) 4162b0563631STom Van Eyck { 4163b0563631STom Van Eyck 4164b0563631STom Van Eyck #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 4165b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ 4166b0563631STom Van Eyck defined(MBEDTLS_ECP_RESTARTABLE) 4167b0563631STom Van Eyck 4168b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4169b0563631STom Van Eyck 4170b0563631STom Van Eyck /* Ensure max_ops is set to the current value (or default). */ 4171b0563631STom Van Eyck mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops()); 4172b0563631STom Van Eyck 4173b0563631STom Van Eyck status = mbedtls_to_psa_error( 4174b0563631STom Van Eyck mbedtls_ecdsa_verify_restartable(&operation->ctx->grp, 4175b0563631STom Van Eyck operation->hash, 4176b0563631STom Van Eyck operation->hash_length, 4177b0563631STom Van Eyck &operation->ctx->Q, 4178b0563631STom Van Eyck &operation->r, 4179b0563631STom Van Eyck &operation->s, 4180b0563631STom Van Eyck &operation->restart_ctx)); 4181b0563631STom Van Eyck 4182b0563631STom Van Eyck /* Hide the fact that the restart context only holds a delta of number of 4183b0563631STom Van Eyck * ops done during the last operation, not an absolute value. */ 4184b0563631STom Van Eyck operation->num_ops += operation->restart_ctx.ecp.ops_done; 4185b0563631STom Van Eyck 4186b0563631STom Van Eyck return status; 4187b0563631STom Van Eyck #else 4188b0563631STom Van Eyck (void) operation; 4189b0563631STom Van Eyck 4190b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 4191b0563631STom Van Eyck 4192b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 4193b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && 4194b0563631STom Van Eyck * defined( MBEDTLS_ECP_RESTARTABLE ) */ 4195b0563631STom Van Eyck } 4196b0563631STom Van Eyck 4197b0563631STom Van Eyck psa_status_t mbedtls_psa_verify_hash_abort( 4198b0563631STom Van Eyck mbedtls_psa_verify_hash_interruptible_operation_t *operation) 4199b0563631STom Van Eyck { 4200b0563631STom Van Eyck 4201b0563631STom Van Eyck #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 4202b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ 4203b0563631STom Van Eyck defined(MBEDTLS_ECP_RESTARTABLE) 4204b0563631STom Van Eyck 4205b0563631STom Van Eyck if (operation->ctx) { 4206b0563631STom Van Eyck mbedtls_ecdsa_free(operation->ctx); 4207b0563631STom Van Eyck mbedtls_free(operation->ctx); 4208b0563631STom Van Eyck operation->ctx = NULL; 4209b0563631STom Van Eyck } 4210b0563631STom Van Eyck 4211b0563631STom Van Eyck mbedtls_ecdsa_restart_free(&operation->restart_ctx); 4212b0563631STom Van Eyck 4213b0563631STom Van Eyck operation->num_ops = 0; 4214b0563631STom Van Eyck 4215b0563631STom Van Eyck mbedtls_mpi_free(&operation->r); 4216b0563631STom Van Eyck mbedtls_mpi_free(&operation->s); 4217b0563631STom Van Eyck 4218b0563631STom Van Eyck return PSA_SUCCESS; 4219b0563631STom Van Eyck 4220b0563631STom Van Eyck #else 4221b0563631STom Van Eyck (void) operation; 4222b0563631STom Van Eyck 4223b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 4224b0563631STom Van Eyck 4225b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 4226b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && 4227b0563631STom Van Eyck * defined( MBEDTLS_ECP_RESTARTABLE ) */ 4228b0563631STom Van Eyck } 4229b0563631STom Van Eyck 4230b0563631STom Van Eyck static psa_status_t psa_generate_random_internal(uint8_t *output, 4231b0563631STom Van Eyck size_t output_size) 4232b0563631STom Van Eyck { 4233b0563631STom Van Eyck GUARD_MODULE_INITIALIZED; 4234b0563631STom Van Eyck 4235b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) 4236b0563631STom Van Eyck 4237b0563631STom Van Eyck psa_status_t status; 4238b0563631STom Van Eyck size_t output_length = 0; 4239b0563631STom Van Eyck status = mbedtls_psa_external_get_random(&global_data.rng, 4240b0563631STom Van Eyck output, output_size, 4241b0563631STom Van Eyck &output_length); 4242b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4243b0563631STom Van Eyck return status; 4244b0563631STom Van Eyck } 4245b0563631STom Van Eyck /* Breaking up a request into smaller chunks is currently not supported 4246b0563631STom Van Eyck * for the external RNG interface. */ 4247b0563631STom Van Eyck if (output_length != output_size) { 4248b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_ENTROPY; 4249b0563631STom Van Eyck } 4250b0563631STom Van Eyck return PSA_SUCCESS; 4251b0563631STom Van Eyck 4252b0563631STom Van Eyck #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 4253b0563631STom Van Eyck 4254b0563631STom Van Eyck while (output_size > 0) { 4255b0563631STom Van Eyck int ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; 4256b0563631STom Van Eyck size_t request_size = 4257b0563631STom Van Eyck (output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ? 4258b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_MAX_REQUEST : 4259b0563631STom Van Eyck output_size); 4260b0563631STom Van Eyck #if defined(MBEDTLS_CTR_DRBG_C) 4261b0563631STom Van Eyck ret = mbedtls_ctr_drbg_random(&global_data.rng.drbg, output, request_size); 4262b0563631STom Van Eyck #elif defined(MBEDTLS_HMAC_DRBG_C) 4263b0563631STom Van Eyck ret = mbedtls_hmac_drbg_random(&global_data.rng.drbg, output, request_size); 4264b0563631STom Van Eyck #endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */ 4265b0563631STom Van Eyck if (ret != 0) { 4266b0563631STom Van Eyck return mbedtls_to_psa_error(ret); 4267b0563631STom Van Eyck } 4268b0563631STom Van Eyck output_size -= request_size; 4269b0563631STom Van Eyck output += request_size; 4270b0563631STom Van Eyck } 4271b0563631STom Van Eyck return PSA_SUCCESS; 4272b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 4273b0563631STom Van Eyck } 4274b0563631STom Van Eyck 4275b0563631STom Van Eyck 4276b0563631STom Van Eyck /****************************************************************/ 4277b0563631STom Van Eyck /* Symmetric cryptography */ 4278b0563631STom Van Eyck /****************************************************************/ 4279b0563631STom Van Eyck 4280b0563631STom Van Eyck static psa_status_t psa_cipher_setup(psa_cipher_operation_t *operation, 4281b0563631STom Van Eyck mbedtls_svc_key_id_t key, 4282b0563631STom Van Eyck psa_algorithm_t alg, 4283b0563631STom Van Eyck mbedtls_operation_t cipher_operation) 4284b0563631STom Van Eyck { 4285b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4286b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 4287b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 4288b0563631STom Van Eyck psa_key_usage_t usage = (cipher_operation == MBEDTLS_ENCRYPT ? 4289b0563631STom Van Eyck PSA_KEY_USAGE_ENCRYPT : 4290b0563631STom Van Eyck PSA_KEY_USAGE_DECRYPT); 4291b0563631STom Van Eyck 4292b0563631STom Van Eyck /* A context must be freshly initialized before it can be set up. */ 4293b0563631STom Van Eyck if (operation->id != 0) { 4294b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4295b0563631STom Van Eyck goto exit; 4296b0563631STom Van Eyck } 4297b0563631STom Van Eyck 4298b0563631STom Van Eyck if (!PSA_ALG_IS_CIPHER(alg)) { 4299b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 4300b0563631STom Van Eyck goto exit; 4301b0563631STom Van Eyck } 4302b0563631STom Van Eyck 4303b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy(key, &slot, usage, alg); 4304b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4305b0563631STom Van Eyck goto exit; 4306b0563631STom Van Eyck } 4307b0563631STom Van Eyck 4308b0563631STom Van Eyck /* Initialize the operation struct members, except for id. The id member 4309b0563631STom Van Eyck * is used to indicate to psa_cipher_abort that there are resources to free, 4310b0563631STom Van Eyck * so we only set it (in the driver wrapper) after resources have been 4311b0563631STom Van Eyck * allocated/initialized. */ 4312b0563631STom Van Eyck operation->iv_set = 0; 4313b0563631STom Van Eyck if (alg == PSA_ALG_ECB_NO_PADDING) { 4314b0563631STom Van Eyck operation->iv_required = 0; 4315b0563631STom Van Eyck } else { 4316b0563631STom Van Eyck operation->iv_required = 1; 4317b0563631STom Van Eyck } 4318b0563631STom Van Eyck operation->default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg); 4319b0563631STom Van Eyck 4320b0563631STom Van Eyck /* Try doing the operation through a driver before using software fallback. */ 4321b0563631STom Van Eyck if (cipher_operation == MBEDTLS_ENCRYPT) { 4322b0563631STom Van Eyck status = psa_driver_wrapper_cipher_encrypt_setup(operation, 4323b0563631STom Van Eyck &slot->attr, 4324b0563631STom Van Eyck slot->key.data, 4325b0563631STom Van Eyck slot->key.bytes, 4326b0563631STom Van Eyck alg); 4327b0563631STom Van Eyck } else { 4328b0563631STom Van Eyck status = psa_driver_wrapper_cipher_decrypt_setup(operation, 4329b0563631STom Van Eyck &slot->attr, 4330b0563631STom Van Eyck slot->key.data, 4331b0563631STom Van Eyck slot->key.bytes, 4332b0563631STom Van Eyck alg); 4333b0563631STom Van Eyck } 4334b0563631STom Van Eyck 4335b0563631STom Van Eyck exit: 4336b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4337b0563631STom Van Eyck psa_cipher_abort(operation); 4338b0563631STom Van Eyck } 4339b0563631STom Van Eyck 4340b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 4341b0563631STom Van Eyck 4342b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 4343b0563631STom Van Eyck } 4344b0563631STom Van Eyck 4345b0563631STom Van Eyck psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, 4346b0563631STom Van Eyck mbedtls_svc_key_id_t key, 4347b0563631STom Van Eyck psa_algorithm_t alg) 4348b0563631STom Van Eyck { 4349b0563631STom Van Eyck return psa_cipher_setup(operation, key, alg, MBEDTLS_ENCRYPT); 4350b0563631STom Van Eyck } 4351b0563631STom Van Eyck 4352b0563631STom Van Eyck psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, 4353b0563631STom Van Eyck mbedtls_svc_key_id_t key, 4354b0563631STom Van Eyck psa_algorithm_t alg) 4355b0563631STom Van Eyck { 4356b0563631STom Van Eyck return psa_cipher_setup(operation, key, alg, MBEDTLS_DECRYPT); 4357b0563631STom Van Eyck } 4358b0563631STom Van Eyck 4359b0563631STom Van Eyck psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, 4360b0563631STom Van Eyck uint8_t *iv_external, 4361b0563631STom Van Eyck size_t iv_size, 4362b0563631STom Van Eyck size_t *iv_length) 4363b0563631STom Van Eyck { 4364b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4365b0563631STom Van Eyck size_t default_iv_length = 0; 4366b0563631STom Van Eyck 4367b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(iv_external, iv); 4368b0563631STom Van Eyck 4369b0563631STom Van Eyck if (operation->id == 0) { 4370b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4371b0563631STom Van Eyck goto exit; 4372b0563631STom Van Eyck } 4373b0563631STom Van Eyck 4374b0563631STom Van Eyck if (operation->iv_set || !operation->iv_required) { 4375b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4376b0563631STom Van Eyck goto exit; 4377b0563631STom Van Eyck } 4378b0563631STom Van Eyck 4379b0563631STom Van Eyck default_iv_length = operation->default_iv_length; 4380b0563631STom Van Eyck if (iv_size < default_iv_length) { 4381b0563631STom Van Eyck status = PSA_ERROR_BUFFER_TOO_SMALL; 4382b0563631STom Van Eyck goto exit; 4383b0563631STom Van Eyck } 4384b0563631STom Van Eyck 4385b0563631STom Van Eyck if (default_iv_length > PSA_CIPHER_IV_MAX_SIZE) { 4386b0563631STom Van Eyck status = PSA_ERROR_GENERIC_ERROR; 4387b0563631STom Van Eyck goto exit; 4388b0563631STom Van Eyck } 4389b0563631STom Van Eyck 4390b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(iv_external, default_iv_length, iv); 4391b0563631STom Van Eyck 4392b0563631STom Van Eyck status = psa_generate_random_internal(iv, default_iv_length); 4393b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4394b0563631STom Van Eyck goto exit; 4395b0563631STom Van Eyck } 4396b0563631STom Van Eyck 4397b0563631STom Van Eyck status = psa_driver_wrapper_cipher_set_iv(operation, 4398b0563631STom Van Eyck iv, default_iv_length); 4399b0563631STom Van Eyck 4400b0563631STom Van Eyck exit: 4401b0563631STom Van Eyck if (status == PSA_SUCCESS) { 4402b0563631STom Van Eyck *iv_length = default_iv_length; 4403b0563631STom Van Eyck operation->iv_set = 1; 4404b0563631STom Van Eyck } else { 4405b0563631STom Van Eyck *iv_length = 0; 4406b0563631STom Van Eyck psa_cipher_abort(operation); 4407b0563631STom Van Eyck if (iv != NULL) { 4408b0563631STom Van Eyck mbedtls_platform_zeroize(iv, default_iv_length); 4409b0563631STom Van Eyck } 4410b0563631STom Van Eyck } 4411b0563631STom Van Eyck 4412b0563631STom Van Eyck LOCAL_OUTPUT_FREE(iv_external, iv); 4413b0563631STom Van Eyck return status; 4414b0563631STom Van Eyck } 4415b0563631STom Van Eyck 4416b0563631STom Van Eyck psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, 4417b0563631STom Van Eyck const uint8_t *iv_external, 4418b0563631STom Van Eyck size_t iv_length) 4419b0563631STom Van Eyck { 4420b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4421b0563631STom Van Eyck 4422b0563631STom Van Eyck LOCAL_INPUT_DECLARE(iv_external, iv); 4423b0563631STom Van Eyck 4424b0563631STom Van Eyck if (operation->id == 0) { 4425b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4426b0563631STom Van Eyck goto exit; 4427b0563631STom Van Eyck } 4428b0563631STom Van Eyck 4429b0563631STom Van Eyck if (operation->iv_set || !operation->iv_required) { 4430b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4431b0563631STom Van Eyck goto exit; 4432b0563631STom Van Eyck } 4433b0563631STom Van Eyck 4434b0563631STom Van Eyck if (iv_length > PSA_CIPHER_IV_MAX_SIZE) { 4435b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 4436b0563631STom Van Eyck goto exit; 4437b0563631STom Van Eyck } 4438b0563631STom Van Eyck 4439b0563631STom Van Eyck LOCAL_INPUT_ALLOC(iv_external, iv_length, iv); 4440b0563631STom Van Eyck 4441b0563631STom Van Eyck status = psa_driver_wrapper_cipher_set_iv(operation, 4442b0563631STom Van Eyck iv, 4443b0563631STom Van Eyck iv_length); 4444b0563631STom Van Eyck 4445b0563631STom Van Eyck exit: 4446b0563631STom Van Eyck if (status == PSA_SUCCESS) { 4447b0563631STom Van Eyck operation->iv_set = 1; 4448b0563631STom Van Eyck } else { 4449b0563631STom Van Eyck psa_cipher_abort(operation); 4450b0563631STom Van Eyck } 4451b0563631STom Van Eyck 4452b0563631STom Van Eyck LOCAL_INPUT_FREE(iv_external, iv); 4453b0563631STom Van Eyck 4454b0563631STom Van Eyck return status; 4455b0563631STom Van Eyck } 4456b0563631STom Van Eyck 4457b0563631STom Van Eyck psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, 4458b0563631STom Van Eyck const uint8_t *input_external, 4459b0563631STom Van Eyck size_t input_length, 4460b0563631STom Van Eyck uint8_t *output_external, 4461b0563631STom Van Eyck size_t output_size, 4462b0563631STom Van Eyck size_t *output_length) 4463b0563631STom Van Eyck { 4464b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4465b0563631STom Van Eyck 4466b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 4467b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 4468b0563631STom Van Eyck 4469b0563631STom Van Eyck if (operation->id == 0) { 4470b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4471b0563631STom Van Eyck goto exit; 4472b0563631STom Van Eyck } 4473b0563631STom Van Eyck 4474b0563631STom Van Eyck if (operation->iv_required && !operation->iv_set) { 4475b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4476b0563631STom Van Eyck goto exit; 4477b0563631STom Van Eyck } 4478b0563631STom Van Eyck 4479b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 4480b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_size, output); 4481b0563631STom Van Eyck 4482b0563631STom Van Eyck status = psa_driver_wrapper_cipher_update(operation, 4483b0563631STom Van Eyck input, 4484b0563631STom Van Eyck input_length, 4485b0563631STom Van Eyck output, 4486b0563631STom Van Eyck output_size, 4487b0563631STom Van Eyck output_length); 4488b0563631STom Van Eyck 4489b0563631STom Van Eyck exit: 4490b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4491b0563631STom Van Eyck psa_cipher_abort(operation); 4492b0563631STom Van Eyck } 4493b0563631STom Van Eyck 4494b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 4495b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 4496b0563631STom Van Eyck 4497b0563631STom Van Eyck return status; 4498b0563631STom Van Eyck } 4499b0563631STom Van Eyck 4500b0563631STom Van Eyck psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, 4501b0563631STom Van Eyck uint8_t *output_external, 4502b0563631STom Van Eyck size_t output_size, 4503b0563631STom Van Eyck size_t *output_length) 4504b0563631STom Van Eyck { 4505b0563631STom Van Eyck psa_status_t status = PSA_ERROR_GENERIC_ERROR; 4506b0563631STom Van Eyck 4507b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 4508b0563631STom Van Eyck 4509b0563631STom Van Eyck if (operation->id == 0) { 4510b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4511b0563631STom Van Eyck goto exit; 4512b0563631STom Van Eyck } 4513b0563631STom Van Eyck 4514b0563631STom Van Eyck if (operation->iv_required && !operation->iv_set) { 4515b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4516b0563631STom Van Eyck goto exit; 4517b0563631STom Van Eyck } 4518b0563631STom Van Eyck 4519b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_size, output); 4520b0563631STom Van Eyck 4521b0563631STom Van Eyck status = psa_driver_wrapper_cipher_finish(operation, 4522b0563631STom Van Eyck output, 4523b0563631STom Van Eyck output_size, 4524b0563631STom Van Eyck output_length); 4525b0563631STom Van Eyck 4526b0563631STom Van Eyck exit: 4527b0563631STom Van Eyck if (status == PSA_SUCCESS) { 4528b0563631STom Van Eyck status = psa_cipher_abort(operation); 4529b0563631STom Van Eyck } else { 4530b0563631STom Van Eyck *output_length = 0; 4531b0563631STom Van Eyck (void) psa_cipher_abort(operation); 4532b0563631STom Van Eyck } 4533b0563631STom Van Eyck 4534b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 4535b0563631STom Van Eyck 4536b0563631STom Van Eyck return status; 4537b0563631STom Van Eyck } 4538b0563631STom Van Eyck 4539b0563631STom Van Eyck psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation) 4540b0563631STom Van Eyck { 4541b0563631STom Van Eyck if (operation->id == 0) { 4542b0563631STom Van Eyck /* The object has (apparently) been initialized but it is not (yet) 4543b0563631STom Van Eyck * in use. It's ok to call abort on such an object, and there's 4544b0563631STom Van Eyck * nothing to do. */ 4545b0563631STom Van Eyck return PSA_SUCCESS; 4546b0563631STom Van Eyck } 4547b0563631STom Van Eyck 4548b0563631STom Van Eyck psa_driver_wrapper_cipher_abort(operation); 4549b0563631STom Van Eyck 4550b0563631STom Van Eyck operation->id = 0; 4551b0563631STom Van Eyck operation->iv_set = 0; 4552b0563631STom Van Eyck operation->iv_required = 0; 4553b0563631STom Van Eyck 4554b0563631STom Van Eyck return PSA_SUCCESS; 4555b0563631STom Van Eyck } 4556b0563631STom Van Eyck 4557b0563631STom Van Eyck psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, 4558b0563631STom Van Eyck psa_algorithm_t alg, 4559b0563631STom Van Eyck const uint8_t *input_external, 4560b0563631STom Van Eyck size_t input_length, 4561b0563631STom Van Eyck uint8_t *output_external, 4562b0563631STom Van Eyck size_t output_size, 4563b0563631STom Van Eyck size_t *output_length) 4564b0563631STom Van Eyck { 4565b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4566b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 4567b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 4568b0563631STom Van Eyck uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE]; 4569b0563631STom Van Eyck size_t default_iv_length = 0; 4570b0563631STom Van Eyck 4571b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 4572b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 4573b0563631STom Van Eyck 4574b0563631STom Van Eyck if (!PSA_ALG_IS_CIPHER(alg)) { 4575b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 4576b0563631STom Van Eyck goto exit; 4577b0563631STom Van Eyck } 4578b0563631STom Van Eyck 4579b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy(key, &slot, 4580b0563631STom Van Eyck PSA_KEY_USAGE_ENCRYPT, 4581b0563631STom Van Eyck alg); 4582b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4583b0563631STom Van Eyck goto exit; 4584b0563631STom Van Eyck } 4585b0563631STom Van Eyck 4586b0563631STom Van Eyck default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg); 4587b0563631STom Van Eyck if (default_iv_length > PSA_CIPHER_IV_MAX_SIZE) { 4588b0563631STom Van Eyck status = PSA_ERROR_GENERIC_ERROR; 4589b0563631STom Van Eyck goto exit; 4590b0563631STom Van Eyck } 4591b0563631STom Van Eyck 4592b0563631STom Van Eyck if (default_iv_length > 0) { 4593b0563631STom Van Eyck if (output_size < default_iv_length) { 4594b0563631STom Van Eyck status = PSA_ERROR_BUFFER_TOO_SMALL; 4595b0563631STom Van Eyck goto exit; 4596b0563631STom Van Eyck } 4597b0563631STom Van Eyck 4598b0563631STom Van Eyck status = psa_generate_random_internal(local_iv, default_iv_length); 4599b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4600b0563631STom Van Eyck goto exit; 4601b0563631STom Van Eyck } 4602b0563631STom Van Eyck } 4603b0563631STom Van Eyck 4604b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 4605b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_size, output); 4606b0563631STom Van Eyck 4607b0563631STom Van Eyck status = psa_driver_wrapper_cipher_encrypt( 4608b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 4609b0563631STom Van Eyck alg, local_iv, default_iv_length, input, input_length, 4610b0563631STom Van Eyck psa_crypto_buffer_offset(output, default_iv_length), 4611b0563631STom Van Eyck output_size - default_iv_length, output_length); 4612b0563631STom Van Eyck 4613b0563631STom Van Eyck exit: 4614b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 4615b0563631STom Van Eyck if (status == PSA_SUCCESS) { 4616b0563631STom Van Eyck status = unlock_status; 4617b0563631STom Van Eyck } 4618b0563631STom Van Eyck 4619b0563631STom Van Eyck if (status == PSA_SUCCESS) { 4620b0563631STom Van Eyck if (default_iv_length > 0) { 4621b0563631STom Van Eyck memcpy(output, local_iv, default_iv_length); 4622b0563631STom Van Eyck } 4623b0563631STom Van Eyck *output_length += default_iv_length; 4624b0563631STom Van Eyck } else { 4625b0563631STom Van Eyck *output_length = 0; 4626b0563631STom Van Eyck } 4627b0563631STom Van Eyck 4628b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 4629b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 4630b0563631STom Van Eyck 4631b0563631STom Van Eyck return status; 4632b0563631STom Van Eyck } 4633b0563631STom Van Eyck 4634b0563631STom Van Eyck psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, 4635b0563631STom Van Eyck psa_algorithm_t alg, 4636b0563631STom Van Eyck const uint8_t *input_external, 4637b0563631STom Van Eyck size_t input_length, 4638b0563631STom Van Eyck uint8_t *output_external, 4639b0563631STom Van Eyck size_t output_size, 4640b0563631STom Van Eyck size_t *output_length) 4641b0563631STom Van Eyck { 4642b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4643b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 4644b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 4645b0563631STom Van Eyck 4646b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 4647b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 4648b0563631STom Van Eyck 4649b0563631STom Van Eyck if (!PSA_ALG_IS_CIPHER(alg)) { 4650b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 4651b0563631STom Van Eyck goto exit; 4652b0563631STom Van Eyck } 4653b0563631STom Van Eyck 4654b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy(key, &slot, 4655b0563631STom Van Eyck PSA_KEY_USAGE_DECRYPT, 4656b0563631STom Van Eyck alg); 4657b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4658b0563631STom Van Eyck goto exit; 4659b0563631STom Van Eyck } 4660b0563631STom Van Eyck 4661*cb034002SJerome Forissier if (input_length < PSA_CIPHER_IV_LENGTH(slot->attr.type, alg)) { 4662b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 4663b0563631STom Van Eyck goto exit; 4664b0563631STom Van Eyck } 4665b0563631STom Van Eyck 4666b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 4667b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_size, output); 4668b0563631STom Van Eyck 4669b0563631STom Van Eyck status = psa_driver_wrapper_cipher_decrypt( 4670b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 4671b0563631STom Van Eyck alg, input, input_length, 4672b0563631STom Van Eyck output, output_size, output_length); 4673b0563631STom Van Eyck 4674b0563631STom Van Eyck exit: 4675b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 4676b0563631STom Van Eyck if (status == PSA_SUCCESS) { 4677b0563631STom Van Eyck status = unlock_status; 4678b0563631STom Van Eyck } 4679b0563631STom Van Eyck 4680b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4681b0563631STom Van Eyck *output_length = 0; 4682b0563631STom Van Eyck } 4683b0563631STom Van Eyck 4684b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 4685b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 4686b0563631STom Van Eyck 4687b0563631STom Van Eyck return status; 4688b0563631STom Van Eyck } 4689b0563631STom Van Eyck 4690b0563631STom Van Eyck 4691b0563631STom Van Eyck /****************************************************************/ 4692b0563631STom Van Eyck /* AEAD */ 4693b0563631STom Van Eyck /****************************************************************/ 4694b0563631STom Van Eyck 4695b0563631STom Van Eyck /* Helper function to get the base algorithm from its variants. */ 4696b0563631STom Van Eyck static psa_algorithm_t psa_aead_get_base_algorithm(psa_algorithm_t alg) 4697b0563631STom Van Eyck { 4698b0563631STom Van Eyck return PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg); 4699b0563631STom Van Eyck } 4700b0563631STom Van Eyck 4701b0563631STom Van Eyck /* Helper function to perform common nonce length checks. */ 4702b0563631STom Van Eyck static psa_status_t psa_aead_check_nonce_length(psa_algorithm_t alg, 4703b0563631STom Van Eyck size_t nonce_length) 4704b0563631STom Van Eyck { 4705b0563631STom Van Eyck psa_algorithm_t base_alg = psa_aead_get_base_algorithm(alg); 4706b0563631STom Van Eyck 4707b0563631STom Van Eyck switch (base_alg) { 4708b0563631STom Van Eyck #if defined(PSA_WANT_ALG_GCM) 4709b0563631STom Van Eyck case PSA_ALG_GCM: 4710b0563631STom Van Eyck /* Not checking max nonce size here as GCM spec allows almost 4711b0563631STom Van Eyck * arbitrarily large nonces. Please note that we do not generally 4712b0563631STom Van Eyck * recommend the usage of nonces of greater length than 4713b0563631STom Van Eyck * PSA_AEAD_NONCE_MAX_SIZE, as large nonces are hashed to a shorter 4714b0563631STom Van Eyck * size, which can then lead to collisions if you encrypt a very 4715b0563631STom Van Eyck * large number of messages.*/ 4716b0563631STom Van Eyck if (nonce_length != 0) { 4717b0563631STom Van Eyck return PSA_SUCCESS; 4718b0563631STom Van Eyck } 4719b0563631STom Van Eyck break; 4720b0563631STom Van Eyck #endif /* PSA_WANT_ALG_GCM */ 4721b0563631STom Van Eyck #if defined(PSA_WANT_ALG_CCM) 4722b0563631STom Van Eyck case PSA_ALG_CCM: 4723b0563631STom Van Eyck if (nonce_length >= 7 && nonce_length <= 13) { 4724b0563631STom Van Eyck return PSA_SUCCESS; 4725b0563631STom Van Eyck } 4726b0563631STom Van Eyck break; 4727b0563631STom Van Eyck #endif /* PSA_WANT_ALG_CCM */ 4728b0563631STom Van Eyck #if defined(PSA_WANT_ALG_CHACHA20_POLY1305) 4729b0563631STom Van Eyck case PSA_ALG_CHACHA20_POLY1305: 4730b0563631STom Van Eyck if (nonce_length == 12) { 4731b0563631STom Van Eyck return PSA_SUCCESS; 4732b0563631STom Van Eyck } else if (nonce_length == 8) { 4733b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 4734b0563631STom Van Eyck } 4735b0563631STom Van Eyck break; 4736b0563631STom Van Eyck #endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */ 4737b0563631STom Van Eyck default: 4738b0563631STom Van Eyck (void) nonce_length; 4739b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 4740b0563631STom Van Eyck } 4741b0563631STom Van Eyck 4742b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 4743b0563631STom Van Eyck } 4744b0563631STom Van Eyck 4745b0563631STom Van Eyck static psa_status_t psa_aead_check_algorithm(psa_algorithm_t alg) 4746b0563631STom Van Eyck { 4747b0563631STom Van Eyck if (!PSA_ALG_IS_AEAD(alg) || PSA_ALG_IS_WILDCARD(alg)) { 4748b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 4749b0563631STom Van Eyck } 4750b0563631STom Van Eyck 4751b0563631STom Van Eyck return PSA_SUCCESS; 4752b0563631STom Van Eyck } 4753b0563631STom Van Eyck 4754b0563631STom Van Eyck psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, 4755b0563631STom Van Eyck psa_algorithm_t alg, 4756b0563631STom Van Eyck const uint8_t *nonce_external, 4757b0563631STom Van Eyck size_t nonce_length, 4758b0563631STom Van Eyck const uint8_t *additional_data_external, 4759b0563631STom Van Eyck size_t additional_data_length, 4760b0563631STom Van Eyck const uint8_t *plaintext_external, 4761b0563631STom Van Eyck size_t plaintext_length, 4762b0563631STom Van Eyck uint8_t *ciphertext_external, 4763b0563631STom Van Eyck size_t ciphertext_size, 4764b0563631STom Van Eyck size_t *ciphertext_length) 4765b0563631STom Van Eyck { 4766b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4767b0563631STom Van Eyck psa_key_slot_t *slot; 4768b0563631STom Van Eyck 4769b0563631STom Van Eyck LOCAL_INPUT_DECLARE(nonce_external, nonce); 4770b0563631STom Van Eyck LOCAL_INPUT_DECLARE(additional_data_external, additional_data); 4771b0563631STom Van Eyck LOCAL_INPUT_DECLARE(plaintext_external, plaintext); 4772b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(ciphertext_external, ciphertext); 4773b0563631STom Van Eyck 4774b0563631STom Van Eyck *ciphertext_length = 0; 4775b0563631STom Van Eyck 4776b0563631STom Van Eyck status = psa_aead_check_algorithm(alg); 4777b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4778b0563631STom Van Eyck return status; 4779b0563631STom Van Eyck } 4780b0563631STom Van Eyck 4781b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy( 4782b0563631STom Van Eyck key, &slot, PSA_KEY_USAGE_ENCRYPT, alg); 4783b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4784b0563631STom Van Eyck return status; 4785b0563631STom Van Eyck } 4786b0563631STom Van Eyck 4787b0563631STom Van Eyck LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce); 4788b0563631STom Van Eyck LOCAL_INPUT_ALLOC(additional_data_external, additional_data_length, additional_data); 4789b0563631STom Van Eyck LOCAL_INPUT_ALLOC(plaintext_external, plaintext_length, plaintext); 4790b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(ciphertext_external, ciphertext_size, ciphertext); 4791b0563631STom Van Eyck 4792b0563631STom Van Eyck status = psa_aead_check_nonce_length(alg, nonce_length); 4793b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4794b0563631STom Van Eyck goto exit; 4795b0563631STom Van Eyck } 4796b0563631STom Van Eyck 4797b0563631STom Van Eyck status = psa_driver_wrapper_aead_encrypt( 4798b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 4799b0563631STom Van Eyck alg, 4800b0563631STom Van Eyck nonce, nonce_length, 4801b0563631STom Van Eyck additional_data, additional_data_length, 4802b0563631STom Van Eyck plaintext, plaintext_length, 4803b0563631STom Van Eyck ciphertext, ciphertext_size, ciphertext_length); 4804b0563631STom Van Eyck 4805b0563631STom Van Eyck if (status != PSA_SUCCESS && ciphertext_size != 0) { 4806b0563631STom Van Eyck memset(ciphertext, 0, ciphertext_size); 4807b0563631STom Van Eyck } 4808b0563631STom Van Eyck 4809b0563631STom Van Eyck exit: 4810b0563631STom Van Eyck LOCAL_INPUT_FREE(nonce_external, nonce); 4811b0563631STom Van Eyck LOCAL_INPUT_FREE(additional_data_external, additional_data); 4812b0563631STom Van Eyck LOCAL_INPUT_FREE(plaintext_external, plaintext); 4813b0563631STom Van Eyck LOCAL_OUTPUT_FREE(ciphertext_external, ciphertext); 4814b0563631STom Van Eyck 4815b0563631STom Van Eyck psa_unregister_read_under_mutex(slot); 4816b0563631STom Van Eyck 4817b0563631STom Van Eyck return status; 4818b0563631STom Van Eyck } 4819b0563631STom Van Eyck 4820b0563631STom Van Eyck psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, 4821b0563631STom Van Eyck psa_algorithm_t alg, 4822b0563631STom Van Eyck const uint8_t *nonce_external, 4823b0563631STom Van Eyck size_t nonce_length, 4824b0563631STom Van Eyck const uint8_t *additional_data_external, 4825b0563631STom Van Eyck size_t additional_data_length, 4826b0563631STom Van Eyck const uint8_t *ciphertext_external, 4827b0563631STom Van Eyck size_t ciphertext_length, 4828b0563631STom Van Eyck uint8_t *plaintext_external, 4829b0563631STom Van Eyck size_t plaintext_size, 4830b0563631STom Van Eyck size_t *plaintext_length) 4831b0563631STom Van Eyck { 4832b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4833b0563631STom Van Eyck psa_key_slot_t *slot; 4834b0563631STom Van Eyck 4835b0563631STom Van Eyck LOCAL_INPUT_DECLARE(nonce_external, nonce); 4836b0563631STom Van Eyck LOCAL_INPUT_DECLARE(additional_data_external, additional_data); 4837b0563631STom Van Eyck LOCAL_INPUT_DECLARE(ciphertext_external, ciphertext); 4838b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(plaintext_external, plaintext); 4839b0563631STom Van Eyck 4840b0563631STom Van Eyck *plaintext_length = 0; 4841b0563631STom Van Eyck 4842b0563631STom Van Eyck status = psa_aead_check_algorithm(alg); 4843b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4844b0563631STom Van Eyck return status; 4845b0563631STom Van Eyck } 4846b0563631STom Van Eyck 4847b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy( 4848b0563631STom Van Eyck key, &slot, PSA_KEY_USAGE_DECRYPT, alg); 4849b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4850b0563631STom Van Eyck return status; 4851b0563631STom Van Eyck } 4852b0563631STom Van Eyck 4853b0563631STom Van Eyck LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce); 4854b0563631STom Van Eyck LOCAL_INPUT_ALLOC(additional_data_external, additional_data_length, 4855b0563631STom Van Eyck additional_data); 4856b0563631STom Van Eyck LOCAL_INPUT_ALLOC(ciphertext_external, ciphertext_length, ciphertext); 4857b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(plaintext_external, plaintext_size, plaintext); 4858b0563631STom Van Eyck 4859b0563631STom Van Eyck status = psa_aead_check_nonce_length(alg, nonce_length); 4860b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4861b0563631STom Van Eyck goto exit; 4862b0563631STom Van Eyck } 4863b0563631STom Van Eyck 4864b0563631STom Van Eyck status = psa_driver_wrapper_aead_decrypt( 4865b0563631STom Van Eyck &slot->attr, slot->key.data, slot->key.bytes, 4866b0563631STom Van Eyck alg, 4867b0563631STom Van Eyck nonce, nonce_length, 4868b0563631STom Van Eyck additional_data, additional_data_length, 4869b0563631STom Van Eyck ciphertext, ciphertext_length, 4870b0563631STom Van Eyck plaintext, plaintext_size, plaintext_length); 4871b0563631STom Van Eyck 4872b0563631STom Van Eyck if (status != PSA_SUCCESS && plaintext_size != 0) { 4873b0563631STom Van Eyck memset(plaintext, 0, plaintext_size); 4874b0563631STom Van Eyck } 4875b0563631STom Van Eyck 4876b0563631STom Van Eyck exit: 4877b0563631STom Van Eyck LOCAL_INPUT_FREE(nonce_external, nonce); 4878b0563631STom Van Eyck LOCAL_INPUT_FREE(additional_data_external, additional_data); 4879b0563631STom Van Eyck LOCAL_INPUT_FREE(ciphertext_external, ciphertext); 4880b0563631STom Van Eyck LOCAL_OUTPUT_FREE(plaintext_external, plaintext); 4881b0563631STom Van Eyck 4882b0563631STom Van Eyck psa_unregister_read_under_mutex(slot); 4883b0563631STom Van Eyck 4884b0563631STom Van Eyck return status; 4885b0563631STom Van Eyck } 4886b0563631STom Van Eyck 4887b0563631STom Van Eyck static psa_status_t psa_validate_tag_length(psa_algorithm_t alg) 4888b0563631STom Van Eyck { 4889b0563631STom Van Eyck const uint8_t tag_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg); 4890b0563631STom Van Eyck 4891b0563631STom Van Eyck switch (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0)) { 4892b0563631STom Van Eyck #if defined(PSA_WANT_ALG_CCM) 4893b0563631STom Van Eyck case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0): 4894b0563631STom Van Eyck /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.*/ 4895b0563631STom Van Eyck if (tag_len < 4 || tag_len > 16 || tag_len % 2) { 4896b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 4897b0563631STom Van Eyck } 4898b0563631STom Van Eyck break; 4899b0563631STom Van Eyck #endif /* PSA_WANT_ALG_CCM */ 4900b0563631STom Van Eyck 4901b0563631STom Van Eyck #if defined(PSA_WANT_ALG_GCM) 4902b0563631STom Van Eyck case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0): 4903b0563631STom Van Eyck /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. */ 4904b0563631STom Van Eyck if (tag_len != 4 && tag_len != 8 && (tag_len < 12 || tag_len > 16)) { 4905b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 4906b0563631STom Van Eyck } 4907b0563631STom Van Eyck break; 4908b0563631STom Van Eyck #endif /* PSA_WANT_ALG_GCM */ 4909b0563631STom Van Eyck 4910b0563631STom Van Eyck #if defined(PSA_WANT_ALG_CHACHA20_POLY1305) 4911b0563631STom Van Eyck case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0): 4912b0563631STom Van Eyck /* We only support the default tag length. */ 4913b0563631STom Van Eyck if (tag_len != 16) { 4914b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 4915b0563631STom Van Eyck } 4916b0563631STom Van Eyck break; 4917b0563631STom Van Eyck #endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */ 4918b0563631STom Van Eyck 4919b0563631STom Van Eyck default: 4920b0563631STom Van Eyck (void) tag_len; 4921b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 4922b0563631STom Van Eyck } 4923b0563631STom Van Eyck return PSA_SUCCESS; 4924b0563631STom Van Eyck } 4925b0563631STom Van Eyck 4926b0563631STom Van Eyck /* Set the key for a multipart authenticated operation. */ 4927b0563631STom Van Eyck static psa_status_t psa_aead_setup(psa_aead_operation_t *operation, 4928b0563631STom Van Eyck int is_encrypt, 4929b0563631STom Van Eyck mbedtls_svc_key_id_t key, 4930b0563631STom Van Eyck psa_algorithm_t alg) 4931b0563631STom Van Eyck { 4932b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 4933b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 4934b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 4935b0563631STom Van Eyck psa_key_usage_t key_usage = 0; 4936b0563631STom Van Eyck 4937b0563631STom Van Eyck status = psa_aead_check_algorithm(alg); 4938b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4939b0563631STom Van Eyck goto exit; 4940b0563631STom Van Eyck } 4941b0563631STom Van Eyck 4942b0563631STom Van Eyck if (operation->id != 0) { 4943b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4944b0563631STom Van Eyck goto exit; 4945b0563631STom Van Eyck } 4946b0563631STom Van Eyck 4947b0563631STom Van Eyck if (operation->nonce_set || operation->lengths_set || 4948b0563631STom Van Eyck operation->ad_started || operation->body_started) { 4949b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 4950b0563631STom Van Eyck goto exit; 4951b0563631STom Van Eyck } 4952b0563631STom Van Eyck 4953b0563631STom Van Eyck if (is_encrypt) { 4954b0563631STom Van Eyck key_usage = PSA_KEY_USAGE_ENCRYPT; 4955b0563631STom Van Eyck } else { 4956b0563631STom Van Eyck key_usage = PSA_KEY_USAGE_DECRYPT; 4957b0563631STom Van Eyck } 4958b0563631STom Van Eyck 4959b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy(key, &slot, key_usage, 4960b0563631STom Van Eyck alg); 4961b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4962b0563631STom Van Eyck goto exit; 4963b0563631STom Van Eyck } 4964b0563631STom Van Eyck 4965b0563631STom Van Eyck if ((status = psa_validate_tag_length(alg)) != PSA_SUCCESS) { 4966b0563631STom Van Eyck goto exit; 4967b0563631STom Van Eyck } 4968b0563631STom Van Eyck 4969b0563631STom Van Eyck if (is_encrypt) { 4970b0563631STom Van Eyck status = psa_driver_wrapper_aead_encrypt_setup(operation, 4971b0563631STom Van Eyck &slot->attr, 4972b0563631STom Van Eyck slot->key.data, 4973b0563631STom Van Eyck slot->key.bytes, 4974b0563631STom Van Eyck alg); 4975b0563631STom Van Eyck } else { 4976b0563631STom Van Eyck status = psa_driver_wrapper_aead_decrypt_setup(operation, 4977b0563631STom Van Eyck &slot->attr, 4978b0563631STom Van Eyck slot->key.data, 4979b0563631STom Van Eyck slot->key.bytes, 4980b0563631STom Van Eyck alg); 4981b0563631STom Van Eyck } 4982b0563631STom Van Eyck if (status != PSA_SUCCESS) { 4983b0563631STom Van Eyck goto exit; 4984b0563631STom Van Eyck } 4985b0563631STom Van Eyck 4986b0563631STom Van Eyck operation->key_type = psa_get_key_type(&slot->attr); 4987b0563631STom Van Eyck 4988b0563631STom Van Eyck exit: 4989b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 4990b0563631STom Van Eyck 4991b0563631STom Van Eyck if (status == PSA_SUCCESS) { 4992b0563631STom Van Eyck status = unlock_status; 4993b0563631STom Van Eyck operation->alg = psa_aead_get_base_algorithm(alg); 4994b0563631STom Van Eyck operation->is_encrypt = is_encrypt; 4995b0563631STom Van Eyck } else { 4996b0563631STom Van Eyck psa_aead_abort(operation); 4997b0563631STom Van Eyck } 4998b0563631STom Van Eyck 4999b0563631STom Van Eyck return status; 5000b0563631STom Van Eyck } 5001b0563631STom Van Eyck 5002b0563631STom Van Eyck /* Set the key for a multipart authenticated encryption operation. */ 5003b0563631STom Van Eyck psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, 5004b0563631STom Van Eyck mbedtls_svc_key_id_t key, 5005b0563631STom Van Eyck psa_algorithm_t alg) 5006b0563631STom Van Eyck { 5007b0563631STom Van Eyck return psa_aead_setup(operation, 1, key, alg); 5008b0563631STom Van Eyck } 5009b0563631STom Van Eyck 5010b0563631STom Van Eyck /* Set the key for a multipart authenticated decryption operation. */ 5011b0563631STom Van Eyck psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, 5012b0563631STom Van Eyck mbedtls_svc_key_id_t key, 5013b0563631STom Van Eyck psa_algorithm_t alg) 5014b0563631STom Van Eyck { 5015b0563631STom Van Eyck return psa_aead_setup(operation, 0, key, alg); 5016b0563631STom Van Eyck } 5017b0563631STom Van Eyck 5018b0563631STom Van Eyck static psa_status_t psa_aead_set_nonce_internal(psa_aead_operation_t *operation, 5019b0563631STom Van Eyck const uint8_t *nonce, 5020b0563631STom Van Eyck size_t nonce_length) 5021b0563631STom Van Eyck { 5022b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 5023b0563631STom Van Eyck 5024b0563631STom Van Eyck if (operation->id == 0) { 5025b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5026b0563631STom Van Eyck goto exit; 5027b0563631STom Van Eyck } 5028b0563631STom Van Eyck 5029b0563631STom Van Eyck if (operation->nonce_set) { 5030b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5031b0563631STom Van Eyck goto exit; 5032b0563631STom Van Eyck } 5033b0563631STom Van Eyck 5034b0563631STom Van Eyck status = psa_aead_check_nonce_length(operation->alg, nonce_length); 5035b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5036b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 5037b0563631STom Van Eyck goto exit; 5038b0563631STom Van Eyck } 5039b0563631STom Van Eyck 5040b0563631STom Van Eyck status = psa_driver_wrapper_aead_set_nonce(operation, nonce, 5041b0563631STom Van Eyck nonce_length); 5042b0563631STom Van Eyck 5043b0563631STom Van Eyck exit: 5044b0563631STom Van Eyck if (status == PSA_SUCCESS) { 5045b0563631STom Van Eyck operation->nonce_set = 1; 5046b0563631STom Van Eyck } else { 5047b0563631STom Van Eyck psa_aead_abort(operation); 5048b0563631STom Van Eyck } 5049b0563631STom Van Eyck 5050b0563631STom Van Eyck return status; 5051b0563631STom Van Eyck } 5052b0563631STom Van Eyck 5053b0563631STom Van Eyck /* Generate a random nonce / IV for multipart AEAD operation */ 5054b0563631STom Van Eyck psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation, 5055b0563631STom Van Eyck uint8_t *nonce_external, 5056b0563631STom Van Eyck size_t nonce_size, 5057b0563631STom Van Eyck size_t *nonce_length) 5058b0563631STom Van Eyck { 5059b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 5060b0563631STom Van Eyck uint8_t local_nonce[PSA_AEAD_NONCE_MAX_SIZE]; 5061b0563631STom Van Eyck size_t required_nonce_size = 0; 5062b0563631STom Van Eyck 5063b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(nonce_external, nonce); 5064b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(nonce_external, nonce_size, nonce); 5065b0563631STom Van Eyck 5066b0563631STom Van Eyck *nonce_length = 0; 5067b0563631STom Van Eyck 5068b0563631STom Van Eyck if (operation->id == 0) { 5069b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5070b0563631STom Van Eyck goto exit; 5071b0563631STom Van Eyck } 5072b0563631STom Van Eyck 5073b0563631STom Van Eyck if (operation->nonce_set || !operation->is_encrypt) { 5074b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5075b0563631STom Van Eyck goto exit; 5076b0563631STom Van Eyck } 5077b0563631STom Van Eyck 5078b0563631STom Van Eyck /* For CCM, this size may not be correct according to the PSA 5079b0563631STom Van Eyck * specification. The PSA Crypto 1.0.1 specification states: 5080b0563631STom Van Eyck * 5081b0563631STom Van Eyck * CCM encodes the plaintext length pLen in L octets, with L the smallest 5082b0563631STom Van Eyck * integer >= 2 where pLen < 2^(8L). The nonce length is then 15 - L bytes. 5083b0563631STom Van Eyck * 5084b0563631STom Van Eyck * However this restriction that L has to be the smallest integer is not 5085b0563631STom Van Eyck * applied in practice, and it is not implementable here since the 5086b0563631STom Van Eyck * plaintext length may or may not be known at this time. */ 5087b0563631STom Van Eyck required_nonce_size = PSA_AEAD_NONCE_LENGTH(operation->key_type, 5088b0563631STom Van Eyck operation->alg); 5089b0563631STom Van Eyck if (nonce_size < required_nonce_size) { 5090b0563631STom Van Eyck status = PSA_ERROR_BUFFER_TOO_SMALL; 5091b0563631STom Van Eyck goto exit; 5092b0563631STom Van Eyck } 5093b0563631STom Van Eyck 5094b0563631STom Van Eyck status = psa_generate_random_internal(local_nonce, required_nonce_size); 5095b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5096b0563631STom Van Eyck goto exit; 5097b0563631STom Van Eyck } 5098b0563631STom Van Eyck 5099b0563631STom Van Eyck status = psa_aead_set_nonce_internal(operation, local_nonce, 5100b0563631STom Van Eyck required_nonce_size); 5101b0563631STom Van Eyck 5102b0563631STom Van Eyck exit: 5103b0563631STom Van Eyck if (status == PSA_SUCCESS) { 5104b0563631STom Van Eyck memcpy(nonce, local_nonce, required_nonce_size); 5105b0563631STom Van Eyck *nonce_length = required_nonce_size; 5106b0563631STom Van Eyck } else { 5107b0563631STom Van Eyck psa_aead_abort(operation); 5108b0563631STom Van Eyck } 5109b0563631STom Van Eyck 5110b0563631STom Van Eyck LOCAL_OUTPUT_FREE(nonce_external, nonce); 5111b0563631STom Van Eyck 5112b0563631STom Van Eyck return status; 5113b0563631STom Van Eyck } 5114b0563631STom Van Eyck 5115b0563631STom Van Eyck /* Set the nonce for a multipart authenticated encryption or decryption 5116b0563631STom Van Eyck operation.*/ 5117b0563631STom Van Eyck psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation, 5118b0563631STom Van Eyck const uint8_t *nonce_external, 5119b0563631STom Van Eyck size_t nonce_length) 5120b0563631STom Van Eyck { 5121b0563631STom Van Eyck psa_status_t status; 5122b0563631STom Van Eyck 5123b0563631STom Van Eyck LOCAL_INPUT_DECLARE(nonce_external, nonce); 5124b0563631STom Van Eyck LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce); 5125b0563631STom Van Eyck 5126b0563631STom Van Eyck status = psa_aead_set_nonce_internal(operation, nonce, nonce_length); 5127b0563631STom Van Eyck 5128b0563631STom Van Eyck /* Exit label is only needed for buffer copying, prevent unused warnings. */ 5129b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 5130b0563631STom Van Eyck exit: 5131b0563631STom Van Eyck #endif 5132b0563631STom Van Eyck 5133b0563631STom Van Eyck LOCAL_INPUT_FREE(nonce_external, nonce); 5134b0563631STom Van Eyck 5135b0563631STom Van Eyck return status; 5136b0563631STom Van Eyck } 5137b0563631STom Van Eyck 5138b0563631STom Van Eyck /* Declare the lengths of the message and additional data for multipart AEAD. */ 5139b0563631STom Van Eyck psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation, 5140b0563631STom Van Eyck size_t ad_length, 5141b0563631STom Van Eyck size_t plaintext_length) 5142b0563631STom Van Eyck { 5143b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 5144b0563631STom Van Eyck 5145b0563631STom Van Eyck if (operation->id == 0) { 5146b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5147b0563631STom Van Eyck goto exit; 5148b0563631STom Van Eyck } 5149b0563631STom Van Eyck 5150b0563631STom Van Eyck if (operation->lengths_set || operation->ad_started || 5151b0563631STom Van Eyck operation->body_started) { 5152b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5153b0563631STom Van Eyck goto exit; 5154b0563631STom Van Eyck } 5155b0563631STom Van Eyck 5156b0563631STom Van Eyck switch (operation->alg) { 5157b0563631STom Van Eyck #if defined(PSA_WANT_ALG_GCM) 5158b0563631STom Van Eyck case PSA_ALG_GCM: 5159b0563631STom Van Eyck /* Lengths can only be too large for GCM if size_t is bigger than 32 5160b0563631STom Van Eyck * bits. Without the guard this code will generate warnings on 32bit 5161b0563631STom Van Eyck * builds. */ 5162b0563631STom Van Eyck #if SIZE_MAX > UINT32_MAX 5163b0563631STom Van Eyck if (((uint64_t) ad_length) >> 61 != 0 || 5164b0563631STom Van Eyck ((uint64_t) plaintext_length) > 0xFFFFFFFE0ull) { 5165b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 5166b0563631STom Van Eyck goto exit; 5167b0563631STom Van Eyck } 5168b0563631STom Van Eyck #endif 5169b0563631STom Van Eyck break; 5170b0563631STom Van Eyck #endif /* PSA_WANT_ALG_GCM */ 5171b0563631STom Van Eyck #if defined(PSA_WANT_ALG_CCM) 5172b0563631STom Van Eyck case PSA_ALG_CCM: 5173b0563631STom Van Eyck if (ad_length > 0xFF00) { 5174b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 5175b0563631STom Van Eyck goto exit; 5176b0563631STom Van Eyck } 5177b0563631STom Van Eyck break; 5178b0563631STom Van Eyck #endif /* PSA_WANT_ALG_CCM */ 5179b0563631STom Van Eyck #if defined(PSA_WANT_ALG_CHACHA20_POLY1305) 5180b0563631STom Van Eyck case PSA_ALG_CHACHA20_POLY1305: 5181b0563631STom Van Eyck /* No length restrictions for ChaChaPoly. */ 5182b0563631STom Van Eyck break; 5183b0563631STom Van Eyck #endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */ 5184b0563631STom Van Eyck default: 5185b0563631STom Van Eyck break; 5186b0563631STom Van Eyck } 5187b0563631STom Van Eyck 5188b0563631STom Van Eyck status = psa_driver_wrapper_aead_set_lengths(operation, ad_length, 5189b0563631STom Van Eyck plaintext_length); 5190b0563631STom Van Eyck 5191b0563631STom Van Eyck exit: 5192b0563631STom Van Eyck if (status == PSA_SUCCESS) { 5193b0563631STom Van Eyck operation->ad_remaining = ad_length; 5194b0563631STom Van Eyck operation->body_remaining = plaintext_length; 5195b0563631STom Van Eyck operation->lengths_set = 1; 5196b0563631STom Van Eyck } else { 5197b0563631STom Van Eyck psa_aead_abort(operation); 5198b0563631STom Van Eyck } 5199b0563631STom Van Eyck 5200b0563631STom Van Eyck return status; 5201b0563631STom Van Eyck } 5202b0563631STom Van Eyck 5203b0563631STom Van Eyck /* Pass additional data to an active multipart AEAD operation. */ 5204b0563631STom Van Eyck psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, 5205b0563631STom Van Eyck const uint8_t *input_external, 5206b0563631STom Van Eyck size_t input_length) 5207b0563631STom Van Eyck { 5208b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 5209b0563631STom Van Eyck 5210b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 5211b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 5212b0563631STom Van Eyck 5213b0563631STom Van Eyck if (operation->id == 0) { 5214b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5215b0563631STom Van Eyck goto exit; 5216b0563631STom Van Eyck } 5217b0563631STom Van Eyck 5218b0563631STom Van Eyck if (!operation->nonce_set || operation->body_started) { 5219b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5220b0563631STom Van Eyck goto exit; 5221b0563631STom Van Eyck } 5222b0563631STom Van Eyck 5223*cb034002SJerome Forissier /* No input to add (zero length), nothing to do. */ 5224*cb034002SJerome Forissier if (input_length == 0) { 5225*cb034002SJerome Forissier status = PSA_SUCCESS; 5226*cb034002SJerome Forissier goto exit; 5227*cb034002SJerome Forissier } 5228*cb034002SJerome Forissier 5229b0563631STom Van Eyck if (operation->lengths_set) { 5230b0563631STom Van Eyck if (operation->ad_remaining < input_length) { 5231b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 5232b0563631STom Van Eyck goto exit; 5233b0563631STom Van Eyck } 5234b0563631STom Van Eyck 5235b0563631STom Van Eyck operation->ad_remaining -= input_length; 5236b0563631STom Van Eyck } 5237b0563631STom Van Eyck #if defined(PSA_WANT_ALG_CCM) 5238b0563631STom Van Eyck else if (operation->alg == PSA_ALG_CCM) { 5239b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5240b0563631STom Van Eyck goto exit; 5241b0563631STom Van Eyck } 5242b0563631STom Van Eyck #endif /* PSA_WANT_ALG_CCM */ 5243b0563631STom Van Eyck 5244b0563631STom Van Eyck status = psa_driver_wrapper_aead_update_ad(operation, input, 5245b0563631STom Van Eyck input_length); 5246b0563631STom Van Eyck 5247b0563631STom Van Eyck exit: 5248b0563631STom Van Eyck if (status == PSA_SUCCESS) { 5249b0563631STom Van Eyck operation->ad_started = 1; 5250b0563631STom Van Eyck } else { 5251b0563631STom Van Eyck psa_aead_abort(operation); 5252b0563631STom Van Eyck } 5253b0563631STom Van Eyck 5254b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 5255b0563631STom Van Eyck 5256b0563631STom Van Eyck return status; 5257b0563631STom Van Eyck } 5258b0563631STom Van Eyck 5259b0563631STom Van Eyck /* Encrypt or decrypt a message fragment in an active multipart AEAD 5260b0563631STom Van Eyck operation.*/ 5261b0563631STom Van Eyck psa_status_t psa_aead_update(psa_aead_operation_t *operation, 5262b0563631STom Van Eyck const uint8_t *input_external, 5263b0563631STom Van Eyck size_t input_length, 5264b0563631STom Van Eyck uint8_t *output_external, 5265b0563631STom Van Eyck size_t output_size, 5266b0563631STom Van Eyck size_t *output_length) 5267b0563631STom Van Eyck { 5268b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 5269b0563631STom Van Eyck 5270b0563631STom Van Eyck 5271b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 5272b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 5273b0563631STom Van Eyck 5274b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 5275b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_size, output); 5276b0563631STom Van Eyck 5277b0563631STom Van Eyck *output_length = 0; 5278b0563631STom Van Eyck 5279b0563631STom Van Eyck if (operation->id == 0) { 5280b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5281b0563631STom Van Eyck goto exit; 5282b0563631STom Van Eyck } 5283b0563631STom Van Eyck 5284b0563631STom Van Eyck if (!operation->nonce_set) { 5285b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5286b0563631STom Van Eyck goto exit; 5287b0563631STom Van Eyck } 5288b0563631STom Van Eyck 5289b0563631STom Van Eyck if (operation->lengths_set) { 5290b0563631STom Van Eyck /* Additional data length was supplied, but not all the additional 5291b0563631STom Van Eyck data was supplied.*/ 5292b0563631STom Van Eyck if (operation->ad_remaining != 0) { 5293b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 5294b0563631STom Van Eyck goto exit; 5295b0563631STom Van Eyck } 5296b0563631STom Van Eyck 5297b0563631STom Van Eyck /* Too much data provided. */ 5298b0563631STom Van Eyck if (operation->body_remaining < input_length) { 5299b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 5300b0563631STom Van Eyck goto exit; 5301b0563631STom Van Eyck } 5302b0563631STom Van Eyck 5303b0563631STom Van Eyck operation->body_remaining -= input_length; 5304b0563631STom Van Eyck } 5305b0563631STom Van Eyck #if defined(PSA_WANT_ALG_CCM) 5306b0563631STom Van Eyck else if (operation->alg == PSA_ALG_CCM) { 5307b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5308b0563631STom Van Eyck goto exit; 5309b0563631STom Van Eyck } 5310b0563631STom Van Eyck #endif /* PSA_WANT_ALG_CCM */ 5311b0563631STom Van Eyck 5312b0563631STom Van Eyck status = psa_driver_wrapper_aead_update(operation, input, input_length, 5313b0563631STom Van Eyck output, output_size, 5314b0563631STom Van Eyck output_length); 5315b0563631STom Van Eyck 5316b0563631STom Van Eyck exit: 5317b0563631STom Van Eyck if (status == PSA_SUCCESS) { 5318b0563631STom Van Eyck operation->body_started = 1; 5319b0563631STom Van Eyck } else { 5320b0563631STom Van Eyck psa_aead_abort(operation); 5321b0563631STom Van Eyck } 5322b0563631STom Van Eyck 5323b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 5324b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 5325b0563631STom Van Eyck 5326b0563631STom Van Eyck return status; 5327b0563631STom Van Eyck } 5328b0563631STom Van Eyck 5329b0563631STom Van Eyck static psa_status_t psa_aead_final_checks(const psa_aead_operation_t *operation) 5330b0563631STom Van Eyck { 5331b0563631STom Van Eyck if (operation->id == 0 || !operation->nonce_set) { 5332b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 5333b0563631STom Van Eyck } 5334b0563631STom Van Eyck 5335b0563631STom Van Eyck if (operation->lengths_set && (operation->ad_remaining != 0 || 5336b0563631STom Van Eyck operation->body_remaining != 0)) { 5337b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 5338b0563631STom Van Eyck } 5339b0563631STom Van Eyck 5340b0563631STom Van Eyck return PSA_SUCCESS; 5341b0563631STom Van Eyck } 5342b0563631STom Van Eyck 5343b0563631STom Van Eyck /* Finish encrypting a message in a multipart AEAD operation. */ 5344b0563631STom Van Eyck psa_status_t psa_aead_finish(psa_aead_operation_t *operation, 5345b0563631STom Van Eyck uint8_t *ciphertext_external, 5346b0563631STom Van Eyck size_t ciphertext_size, 5347b0563631STom Van Eyck size_t *ciphertext_length, 5348b0563631STom Van Eyck uint8_t *tag_external, 5349b0563631STom Van Eyck size_t tag_size, 5350b0563631STom Van Eyck size_t *tag_length) 5351b0563631STom Van Eyck { 5352b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 5353b0563631STom Van Eyck 5354b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(ciphertext_external, ciphertext); 5355b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(tag_external, tag); 5356b0563631STom Van Eyck 5357b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(ciphertext_external, ciphertext_size, ciphertext); 5358b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(tag_external, tag_size, tag); 5359b0563631STom Van Eyck 5360b0563631STom Van Eyck *ciphertext_length = 0; 5361b0563631STom Van Eyck *tag_length = tag_size; 5362b0563631STom Van Eyck 5363b0563631STom Van Eyck status = psa_aead_final_checks(operation); 5364b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5365b0563631STom Van Eyck goto exit; 5366b0563631STom Van Eyck } 5367b0563631STom Van Eyck 5368b0563631STom Van Eyck if (!operation->is_encrypt) { 5369b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5370b0563631STom Van Eyck goto exit; 5371b0563631STom Van Eyck } 5372b0563631STom Van Eyck 5373b0563631STom Van Eyck status = psa_driver_wrapper_aead_finish(operation, ciphertext, 5374b0563631STom Van Eyck ciphertext_size, 5375b0563631STom Van Eyck ciphertext_length, 5376b0563631STom Van Eyck tag, tag_size, tag_length); 5377b0563631STom Van Eyck 5378b0563631STom Van Eyck exit: 5379b0563631STom Van Eyck 5380b0563631STom Van Eyck 5381b0563631STom Van Eyck /* In case the operation fails and the user fails to check for failure or 5382b0563631STom Van Eyck * the zero tag size, make sure the tag is set to something implausible. 5383b0563631STom Van Eyck * Even if the operation succeeds, make sure we clear the rest of the 5384b0563631STom Van Eyck * buffer to prevent potential leakage of anything previously placed in 5385b0563631STom Van Eyck * the same buffer.*/ 5386b0563631STom Van Eyck psa_wipe_tag_output_buffer(tag, status, tag_size, *tag_length); 5387b0563631STom Van Eyck 5388b0563631STom Van Eyck psa_aead_abort(operation); 5389b0563631STom Van Eyck 5390b0563631STom Van Eyck LOCAL_OUTPUT_FREE(ciphertext_external, ciphertext); 5391b0563631STom Van Eyck LOCAL_OUTPUT_FREE(tag_external, tag); 5392b0563631STom Van Eyck 5393b0563631STom Van Eyck return status; 5394b0563631STom Van Eyck } 5395b0563631STom Van Eyck 5396b0563631STom Van Eyck /* Finish authenticating and decrypting a message in a multipart AEAD 5397b0563631STom Van Eyck operation.*/ 5398b0563631STom Van Eyck psa_status_t psa_aead_verify(psa_aead_operation_t *operation, 5399b0563631STom Van Eyck uint8_t *plaintext_external, 5400b0563631STom Van Eyck size_t plaintext_size, 5401b0563631STom Van Eyck size_t *plaintext_length, 5402b0563631STom Van Eyck const uint8_t *tag_external, 5403b0563631STom Van Eyck size_t tag_length) 5404b0563631STom Van Eyck { 5405b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 5406b0563631STom Van Eyck 5407b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(plaintext_external, plaintext); 5408b0563631STom Van Eyck LOCAL_INPUT_DECLARE(tag_external, tag); 5409b0563631STom Van Eyck 5410b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(plaintext_external, plaintext_size, plaintext); 5411b0563631STom Van Eyck LOCAL_INPUT_ALLOC(tag_external, tag_length, tag); 5412b0563631STom Van Eyck 5413b0563631STom Van Eyck *plaintext_length = 0; 5414b0563631STom Van Eyck 5415b0563631STom Van Eyck status = psa_aead_final_checks(operation); 5416b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5417b0563631STom Van Eyck goto exit; 5418b0563631STom Van Eyck } 5419b0563631STom Van Eyck 5420b0563631STom Van Eyck if (operation->is_encrypt) { 5421b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5422b0563631STom Van Eyck goto exit; 5423b0563631STom Van Eyck } 5424b0563631STom Van Eyck 5425b0563631STom Van Eyck status = psa_driver_wrapper_aead_verify(operation, plaintext, 5426b0563631STom Van Eyck plaintext_size, 5427b0563631STom Van Eyck plaintext_length, 5428b0563631STom Van Eyck tag, tag_length); 5429b0563631STom Van Eyck 5430b0563631STom Van Eyck exit: 5431b0563631STom Van Eyck psa_aead_abort(operation); 5432b0563631STom Van Eyck 5433b0563631STom Van Eyck LOCAL_OUTPUT_FREE(plaintext_external, plaintext); 5434b0563631STom Van Eyck LOCAL_INPUT_FREE(tag_external, tag); 5435b0563631STom Van Eyck 5436b0563631STom Van Eyck return status; 5437b0563631STom Van Eyck } 5438b0563631STom Van Eyck 5439b0563631STom Van Eyck /* Abort an AEAD operation. */ 5440b0563631STom Van Eyck psa_status_t psa_aead_abort(psa_aead_operation_t *operation) 5441b0563631STom Van Eyck { 5442b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 5443b0563631STom Van Eyck 5444b0563631STom Van Eyck if (operation->id == 0) { 5445b0563631STom Van Eyck /* The object has (apparently) been initialized but it is not (yet) 5446b0563631STom Van Eyck * in use. It's ok to call abort on such an object, and there's 5447b0563631STom Van Eyck * nothing to do. */ 5448b0563631STom Van Eyck return PSA_SUCCESS; 5449b0563631STom Van Eyck } 5450b0563631STom Van Eyck 5451b0563631STom Van Eyck status = psa_driver_wrapper_aead_abort(operation); 5452b0563631STom Van Eyck 5453b0563631STom Van Eyck memset(operation, 0, sizeof(*operation)); 5454b0563631STom Van Eyck 5455b0563631STom Van Eyck return status; 5456b0563631STom Van Eyck } 5457b0563631STom Van Eyck 5458b0563631STom Van Eyck /****************************************************************/ 5459b0563631STom Van Eyck /* Generators */ 5460b0563631STom Van Eyck /****************************************************************/ 5461b0563631STom Van Eyck 5462b0563631STom Van Eyck #if defined(BUILTIN_ALG_ANY_HKDF) || \ 5463b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ 5464b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) || \ 5465b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) || \ 5466b0563631STom Van Eyck defined(PSA_HAVE_SOFT_PBKDF2) 5467b0563631STom Van Eyck #define AT_LEAST_ONE_BUILTIN_KDF 5468b0563631STom Van Eyck #endif /* At least one builtin KDF */ 5469b0563631STom Van Eyck 5470b0563631STom Van Eyck #if defined(BUILTIN_ALG_ANY_HKDF) || \ 5471b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ 5472b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) 5473b0563631STom Van Eyck static psa_status_t psa_key_derivation_start_hmac( 5474b0563631STom Van Eyck psa_mac_operation_t *operation, 5475b0563631STom Van Eyck psa_algorithm_t hash_alg, 5476b0563631STom Van Eyck const uint8_t *hmac_key, 5477b0563631STom Van Eyck size_t hmac_key_length) 5478b0563631STom Van Eyck { 5479b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 5480b0563631STom Van Eyck psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 5481b0563631STom Van Eyck psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); 5482b0563631STom Van Eyck psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(hmac_key_length)); 5483b0563631STom Van Eyck psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); 5484b0563631STom Van Eyck 5485b0563631STom Van Eyck operation->is_sign = 1; 5486b0563631STom Van Eyck operation->mac_size = PSA_HASH_LENGTH(hash_alg); 5487b0563631STom Van Eyck 5488b0563631STom Van Eyck status = psa_driver_wrapper_mac_sign_setup(operation, 5489b0563631STom Van Eyck &attributes, 5490b0563631STom Van Eyck hmac_key, hmac_key_length, 5491b0563631STom Van Eyck PSA_ALG_HMAC(hash_alg)); 5492b0563631STom Van Eyck 5493b0563631STom Van Eyck psa_reset_key_attributes(&attributes); 5494b0563631STom Van Eyck return status; 5495b0563631STom Van Eyck } 5496b0563631STom Van Eyck #endif /* KDF algorithms reliant on HMAC */ 5497b0563631STom Van Eyck 5498b0563631STom Van Eyck #define HKDF_STATE_INIT 0 /* no input yet */ 5499b0563631STom Van Eyck #define HKDF_STATE_STARTED 1 /* got salt */ 5500b0563631STom Van Eyck #define HKDF_STATE_KEYED 2 /* got key */ 5501b0563631STom Van Eyck #define HKDF_STATE_OUTPUT 3 /* output started */ 5502b0563631STom Van Eyck 5503b0563631STom Van Eyck static psa_algorithm_t psa_key_derivation_get_kdf_alg( 5504b0563631STom Van Eyck const psa_key_derivation_operation_t *operation) 5505b0563631STom Van Eyck { 5506b0563631STom Van Eyck if (PSA_ALG_IS_KEY_AGREEMENT(operation->alg)) { 5507b0563631STom Van Eyck return PSA_ALG_KEY_AGREEMENT_GET_KDF(operation->alg); 5508b0563631STom Van Eyck } else { 5509b0563631STom Van Eyck return operation->alg; 5510b0563631STom Van Eyck } 5511b0563631STom Van Eyck } 5512b0563631STom Van Eyck 5513b0563631STom Van Eyck psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t *operation) 5514b0563631STom Van Eyck { 5515b0563631STom Van Eyck psa_status_t status = PSA_SUCCESS; 5516b0563631STom Van Eyck psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation); 5517b0563631STom Van Eyck if (kdf_alg == 0) { 5518b0563631STom Van Eyck /* The object has (apparently) been initialized but it is not 5519b0563631STom Van Eyck * in use. It's ok to call abort on such an object, and there's 5520b0563631STom Van Eyck * nothing to do. */ 5521b0563631STom Van Eyck } else 5522b0563631STom Van Eyck #if defined(BUILTIN_ALG_ANY_HKDF) 5523b0563631STom Van Eyck if (PSA_ALG_IS_ANY_HKDF(kdf_alg)) { 5524b0563631STom Van Eyck mbedtls_free(operation->ctx.hkdf.info); 5525b0563631STom Van Eyck status = psa_mac_abort(&operation->ctx.hkdf.hmac); 5526b0563631STom Van Eyck } else 5527b0563631STom Van Eyck #endif /* BUILTIN_ALG_ANY_HKDF */ 5528b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ 5529b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) 5530b0563631STom Van Eyck if (PSA_ALG_IS_TLS12_PRF(kdf_alg) || 5531b0563631STom Van Eyck /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */ 5532b0563631STom Van Eyck PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) { 5533b0563631STom Van Eyck if (operation->ctx.tls12_prf.secret != NULL) { 5534b0563631STom Van Eyck mbedtls_zeroize_and_free(operation->ctx.tls12_prf.secret, 5535b0563631STom Van Eyck operation->ctx.tls12_prf.secret_length); 5536b0563631STom Van Eyck } 5537b0563631STom Van Eyck 5538b0563631STom Van Eyck if (operation->ctx.tls12_prf.seed != NULL) { 5539b0563631STom Van Eyck mbedtls_zeroize_and_free(operation->ctx.tls12_prf.seed, 5540b0563631STom Van Eyck operation->ctx.tls12_prf.seed_length); 5541b0563631STom Van Eyck } 5542b0563631STom Van Eyck 5543b0563631STom Van Eyck if (operation->ctx.tls12_prf.label != NULL) { 5544b0563631STom Van Eyck mbedtls_zeroize_and_free(operation->ctx.tls12_prf.label, 5545b0563631STom Van Eyck operation->ctx.tls12_prf.label_length); 5546b0563631STom Van Eyck } 5547b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) 5548b0563631STom Van Eyck if (operation->ctx.tls12_prf.other_secret != NULL) { 5549b0563631STom Van Eyck mbedtls_zeroize_and_free(operation->ctx.tls12_prf.other_secret, 5550b0563631STom Van Eyck operation->ctx.tls12_prf.other_secret_length); 5551b0563631STom Van Eyck } 5552b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ 5553b0563631STom Van Eyck status = PSA_SUCCESS; 5554b0563631STom Van Eyck 5555b0563631STom Van Eyck /* We leave the fields Ai and output_block to be erased safely by the 5556b0563631STom Van Eyck * mbedtls_platform_zeroize() in the end of this function. */ 5557b0563631STom Van Eyck } else 5558b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || 5559b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */ 5560b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) 5561b0563631STom Van Eyck if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { 5562b0563631STom Van Eyck mbedtls_platform_zeroize(operation->ctx.tls12_ecjpake_to_pms.data, 5563b0563631STom Van Eyck sizeof(operation->ctx.tls12_ecjpake_to_pms.data)); 5564b0563631STom Van Eyck } else 5565b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) */ 5566b0563631STom Van Eyck #if defined(PSA_HAVE_SOFT_PBKDF2) 5567b0563631STom Van Eyck if (PSA_ALG_IS_PBKDF2(kdf_alg)) { 5568b0563631STom Van Eyck if (operation->ctx.pbkdf2.salt != NULL) { 5569b0563631STom Van Eyck mbedtls_zeroize_and_free(operation->ctx.pbkdf2.salt, 5570b0563631STom Van Eyck operation->ctx.pbkdf2.salt_length); 5571b0563631STom Van Eyck } 5572b0563631STom Van Eyck 5573b0563631STom Van Eyck status = PSA_SUCCESS; 5574b0563631STom Van Eyck } else 5575b0563631STom Van Eyck #endif /* defined(PSA_HAVE_SOFT_PBKDF2) */ 5576b0563631STom Van Eyck { 5577b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 5578b0563631STom Van Eyck } 5579b0563631STom Van Eyck mbedtls_platform_zeroize(operation, sizeof(*operation)); 5580b0563631STom Van Eyck return status; 5581b0563631STom Van Eyck } 5582b0563631STom Van Eyck 5583b0563631STom Van Eyck psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation, 5584b0563631STom Van Eyck size_t *capacity) 5585b0563631STom Van Eyck { 5586b0563631STom Van Eyck if (operation->alg == 0) { 5587b0563631STom Van Eyck /* This is a blank key derivation operation. */ 5588b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 5589b0563631STom Van Eyck } 5590b0563631STom Van Eyck 5591b0563631STom Van Eyck *capacity = operation->capacity; 5592b0563631STom Van Eyck return PSA_SUCCESS; 5593b0563631STom Van Eyck } 5594b0563631STom Van Eyck 5595b0563631STom Van Eyck psa_status_t psa_key_derivation_set_capacity(psa_key_derivation_operation_t *operation, 5596b0563631STom Van Eyck size_t capacity) 5597b0563631STom Van Eyck { 5598b0563631STom Van Eyck if (operation->alg == 0) { 5599b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 5600b0563631STom Van Eyck } 5601b0563631STom Van Eyck if (capacity > operation->capacity) { 5602b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 5603b0563631STom Van Eyck } 5604b0563631STom Van Eyck operation->capacity = capacity; 5605b0563631STom Van Eyck return PSA_SUCCESS; 5606b0563631STom Van Eyck } 5607b0563631STom Van Eyck 5608b0563631STom Van Eyck #if defined(BUILTIN_ALG_ANY_HKDF) 5609b0563631STom Van Eyck /* Read some bytes from an HKDF-based operation. */ 5610b0563631STom Van Eyck static psa_status_t psa_key_derivation_hkdf_read(psa_hkdf_key_derivation_t *hkdf, 5611b0563631STom Van Eyck psa_algorithm_t kdf_alg, 5612b0563631STom Van Eyck uint8_t *output, 5613b0563631STom Van Eyck size_t output_length) 5614b0563631STom Van Eyck { 5615b0563631STom Van Eyck psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg); 5616b0563631STom Van Eyck uint8_t hash_length = PSA_HASH_LENGTH(hash_alg); 5617b0563631STom Van Eyck size_t hmac_output_length; 5618b0563631STom Van Eyck psa_status_t status; 5619b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) 5620b0563631STom Van Eyck const uint8_t last_block = PSA_ALG_IS_HKDF_EXTRACT(kdf_alg) ? 0 : 0xff; 5621b0563631STom Van Eyck #else 5622b0563631STom Van Eyck const uint8_t last_block = 0xff; 5623b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ 5624b0563631STom Van Eyck 5625b0563631STom Van Eyck if (hkdf->state < HKDF_STATE_KEYED || 5626b0563631STom Van Eyck (!hkdf->info_set 5627b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) 5628b0563631STom Van Eyck && !PSA_ALG_IS_HKDF_EXTRACT(kdf_alg) 5629b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ 5630b0563631STom Van Eyck )) { 5631b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 5632b0563631STom Van Eyck } 5633b0563631STom Van Eyck hkdf->state = HKDF_STATE_OUTPUT; 5634b0563631STom Van Eyck 5635b0563631STom Van Eyck while (output_length != 0) { 5636b0563631STom Van Eyck /* Copy what remains of the current block */ 5637b0563631STom Van Eyck uint8_t n = hash_length - hkdf->offset_in_block; 5638b0563631STom Van Eyck if (n > output_length) { 5639b0563631STom Van Eyck n = (uint8_t) output_length; 5640b0563631STom Van Eyck } 5641b0563631STom Van Eyck memcpy(output, hkdf->output_block + hkdf->offset_in_block, n); 5642b0563631STom Van Eyck output += n; 5643b0563631STom Van Eyck output_length -= n; 5644b0563631STom Van Eyck hkdf->offset_in_block += n; 5645b0563631STom Van Eyck if (output_length == 0) { 5646b0563631STom Van Eyck break; 5647b0563631STom Van Eyck } 5648b0563631STom Van Eyck /* We can't be wanting more output after the last block, otherwise 5649b0563631STom Van Eyck * the capacity check in psa_key_derivation_output_bytes() would have 5650b0563631STom Van Eyck * prevented this call. It could happen only if the operation 5651b0563631STom Van Eyck * object was corrupted or if this function is called directly 5652b0563631STom Van Eyck * inside the library. */ 5653b0563631STom Van Eyck if (hkdf->block_number == last_block) { 5654b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 5655b0563631STom Van Eyck } 5656b0563631STom Van Eyck 5657b0563631STom Van Eyck /* We need a new block */ 5658b0563631STom Van Eyck ++hkdf->block_number; 5659b0563631STom Van Eyck hkdf->offset_in_block = 0; 5660b0563631STom Van Eyck 5661b0563631STom Van Eyck status = psa_key_derivation_start_hmac(&hkdf->hmac, 5662b0563631STom Van Eyck hash_alg, 5663b0563631STom Van Eyck hkdf->prk, 5664b0563631STom Van Eyck hash_length); 5665b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5666b0563631STom Van Eyck return status; 5667b0563631STom Van Eyck } 5668b0563631STom Van Eyck 5669b0563631STom Van Eyck if (hkdf->block_number != 1) { 5670b0563631STom Van Eyck status = psa_mac_update(&hkdf->hmac, 5671b0563631STom Van Eyck hkdf->output_block, 5672b0563631STom Van Eyck hash_length); 5673b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5674b0563631STom Van Eyck return status; 5675b0563631STom Van Eyck } 5676b0563631STom Van Eyck } 5677b0563631STom Van Eyck status = psa_mac_update(&hkdf->hmac, 5678b0563631STom Van Eyck hkdf->info, 5679b0563631STom Van Eyck hkdf->info_length); 5680b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5681b0563631STom Van Eyck return status; 5682b0563631STom Van Eyck } 5683b0563631STom Van Eyck status = psa_mac_update(&hkdf->hmac, 5684b0563631STom Van Eyck &hkdf->block_number, 1); 5685b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5686b0563631STom Van Eyck return status; 5687b0563631STom Van Eyck } 5688b0563631STom Van Eyck status = psa_mac_sign_finish(&hkdf->hmac, 5689b0563631STom Van Eyck hkdf->output_block, 5690b0563631STom Van Eyck sizeof(hkdf->output_block), 5691b0563631STom Van Eyck &hmac_output_length); 5692b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5693b0563631STom Van Eyck return status; 5694b0563631STom Van Eyck } 5695b0563631STom Van Eyck } 5696b0563631STom Van Eyck 5697b0563631STom Van Eyck return PSA_SUCCESS; 5698b0563631STom Van Eyck } 5699b0563631STom Van Eyck #endif /* BUILTIN_ALG_ANY_HKDF */ 5700b0563631STom Van Eyck 5701b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ 5702b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) 5703b0563631STom Van Eyck static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( 5704b0563631STom Van Eyck psa_tls12_prf_key_derivation_t *tls12_prf, 5705b0563631STom Van Eyck psa_algorithm_t alg) 5706b0563631STom Van Eyck { 5707b0563631STom Van Eyck psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(alg); 5708b0563631STom Van Eyck uint8_t hash_length = PSA_HASH_LENGTH(hash_alg); 5709b0563631STom Van Eyck psa_mac_operation_t hmac = PSA_MAC_OPERATION_INIT; 5710b0563631STom Van Eyck size_t hmac_output_length; 5711b0563631STom Van Eyck psa_status_t status, cleanup_status; 5712b0563631STom Van Eyck 5713b0563631STom Van Eyck /* We can't be wanting more output after block 0xff, otherwise 5714b0563631STom Van Eyck * the capacity check in psa_key_derivation_output_bytes() would have 5715b0563631STom Van Eyck * prevented this call. It could happen only if the operation 5716b0563631STom Van Eyck * object was corrupted or if this function is called directly 5717b0563631STom Van Eyck * inside the library. */ 5718b0563631STom Van Eyck if (tls12_prf->block_number == 0xff) { 5719b0563631STom Van Eyck return PSA_ERROR_CORRUPTION_DETECTED; 5720b0563631STom Van Eyck } 5721b0563631STom Van Eyck 5722b0563631STom Van Eyck /* We need a new block */ 5723b0563631STom Van Eyck ++tls12_prf->block_number; 5724b0563631STom Van Eyck tls12_prf->left_in_block = hash_length; 5725b0563631STom Van Eyck 5726b0563631STom Van Eyck /* Recall the definition of the TLS-1.2-PRF from RFC 5246: 5727b0563631STom Van Eyck * 5728b0563631STom Van Eyck * PRF(secret, label, seed) = P_<hash>(secret, label + seed) 5729b0563631STom Van Eyck * 5730b0563631STom Van Eyck * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + 5731b0563631STom Van Eyck * HMAC_hash(secret, A(2) + seed) + 5732b0563631STom Van Eyck * HMAC_hash(secret, A(3) + seed) + ... 5733b0563631STom Van Eyck * 5734b0563631STom Van Eyck * A(0) = seed 5735b0563631STom Van Eyck * A(i) = HMAC_hash(secret, A(i-1)) 5736b0563631STom Van Eyck * 5737b0563631STom Van Eyck * The `psa_tls12_prf_key_derivation` structure saves the block 5738b0563631STom Van Eyck * `HMAC_hash(secret, A(i) + seed)` from which the output 5739b0563631STom Van Eyck * is currently extracted as `output_block` and where i is 5740b0563631STom Van Eyck * `block_number`. 5741b0563631STom Van Eyck */ 5742b0563631STom Van Eyck 5743b0563631STom Van Eyck status = psa_key_derivation_start_hmac(&hmac, 5744b0563631STom Van Eyck hash_alg, 5745b0563631STom Van Eyck tls12_prf->secret, 5746b0563631STom Van Eyck tls12_prf->secret_length); 5747b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5748b0563631STom Van Eyck goto cleanup; 5749b0563631STom Van Eyck } 5750b0563631STom Van Eyck 5751b0563631STom Van Eyck /* Calculate A(i) where i = tls12_prf->block_number. */ 5752b0563631STom Van Eyck if (tls12_prf->block_number == 1) { 5753b0563631STom Van Eyck /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads 5754b0563631STom Van Eyck * the variable seed and in this instance means it in the context of the 5755b0563631STom Van Eyck * P_hash function, where seed = label + seed.) */ 5756b0563631STom Van Eyck status = psa_mac_update(&hmac, 5757b0563631STom Van Eyck tls12_prf->label, 5758b0563631STom Van Eyck tls12_prf->label_length); 5759b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5760b0563631STom Van Eyck goto cleanup; 5761b0563631STom Van Eyck } 5762b0563631STom Van Eyck status = psa_mac_update(&hmac, 5763b0563631STom Van Eyck tls12_prf->seed, 5764b0563631STom Van Eyck tls12_prf->seed_length); 5765b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5766b0563631STom Van Eyck goto cleanup; 5767b0563631STom Van Eyck } 5768b0563631STom Van Eyck } else { 5769b0563631STom Van Eyck /* A(i) = HMAC_hash(secret, A(i-1)) */ 5770b0563631STom Van Eyck status = psa_mac_update(&hmac, tls12_prf->Ai, hash_length); 5771b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5772b0563631STom Van Eyck goto cleanup; 5773b0563631STom Van Eyck } 5774b0563631STom Van Eyck } 5775b0563631STom Van Eyck 5776b0563631STom Van Eyck status = psa_mac_sign_finish(&hmac, 5777b0563631STom Van Eyck tls12_prf->Ai, hash_length, 5778b0563631STom Van Eyck &hmac_output_length); 5779b0563631STom Van Eyck if (hmac_output_length != hash_length) { 5780b0563631STom Van Eyck status = PSA_ERROR_CORRUPTION_DETECTED; 5781b0563631STom Van Eyck } 5782b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5783b0563631STom Van Eyck goto cleanup; 5784b0563631STom Van Eyck } 5785b0563631STom Van Eyck 5786b0563631STom Van Eyck /* Calculate HMAC_hash(secret, A(i) + label + seed). */ 5787b0563631STom Van Eyck status = psa_key_derivation_start_hmac(&hmac, 5788b0563631STom Van Eyck hash_alg, 5789b0563631STom Van Eyck tls12_prf->secret, 5790b0563631STom Van Eyck tls12_prf->secret_length); 5791b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5792b0563631STom Van Eyck goto cleanup; 5793b0563631STom Van Eyck } 5794b0563631STom Van Eyck status = psa_mac_update(&hmac, tls12_prf->Ai, hash_length); 5795b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5796b0563631STom Van Eyck goto cleanup; 5797b0563631STom Van Eyck } 5798b0563631STom Van Eyck status = psa_mac_update(&hmac, tls12_prf->label, tls12_prf->label_length); 5799b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5800b0563631STom Van Eyck goto cleanup; 5801b0563631STom Van Eyck } 5802b0563631STom Van Eyck status = psa_mac_update(&hmac, tls12_prf->seed, tls12_prf->seed_length); 5803b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5804b0563631STom Van Eyck goto cleanup; 5805b0563631STom Van Eyck } 5806b0563631STom Van Eyck status = psa_mac_sign_finish(&hmac, 5807b0563631STom Van Eyck tls12_prf->output_block, hash_length, 5808b0563631STom Van Eyck &hmac_output_length); 5809b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5810b0563631STom Van Eyck goto cleanup; 5811b0563631STom Van Eyck } 5812b0563631STom Van Eyck 5813b0563631STom Van Eyck 5814b0563631STom Van Eyck cleanup: 5815b0563631STom Van Eyck cleanup_status = psa_mac_abort(&hmac); 5816b0563631STom Van Eyck if (status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS) { 5817b0563631STom Van Eyck status = cleanup_status; 5818b0563631STom Van Eyck } 5819b0563631STom Van Eyck 5820b0563631STom Van Eyck return status; 5821b0563631STom Van Eyck } 5822b0563631STom Van Eyck 5823b0563631STom Van Eyck static psa_status_t psa_key_derivation_tls12_prf_read( 5824b0563631STom Van Eyck psa_tls12_prf_key_derivation_t *tls12_prf, 5825b0563631STom Van Eyck psa_algorithm_t alg, 5826b0563631STom Van Eyck uint8_t *output, 5827b0563631STom Van Eyck size_t output_length) 5828b0563631STom Van Eyck { 5829b0563631STom Van Eyck psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH(alg); 5830b0563631STom Van Eyck uint8_t hash_length = PSA_HASH_LENGTH(hash_alg); 5831b0563631STom Van Eyck psa_status_t status; 5832b0563631STom Van Eyck uint8_t offset, length; 5833b0563631STom Van Eyck 5834b0563631STom Van Eyck switch (tls12_prf->state) { 5835b0563631STom Van Eyck case PSA_TLS12_PRF_STATE_LABEL_SET: 5836b0563631STom Van Eyck tls12_prf->state = PSA_TLS12_PRF_STATE_OUTPUT; 5837b0563631STom Van Eyck break; 5838b0563631STom Van Eyck case PSA_TLS12_PRF_STATE_OUTPUT: 5839b0563631STom Van Eyck break; 5840b0563631STom Van Eyck default: 5841b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 5842b0563631STom Van Eyck } 5843b0563631STom Van Eyck 5844b0563631STom Van Eyck while (output_length != 0) { 5845b0563631STom Van Eyck /* Check if we have fully processed the current block. */ 5846b0563631STom Van Eyck if (tls12_prf->left_in_block == 0) { 5847b0563631STom Van Eyck status = psa_key_derivation_tls12_prf_generate_next_block(tls12_prf, 5848b0563631STom Van Eyck alg); 5849b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5850b0563631STom Van Eyck return status; 5851b0563631STom Van Eyck } 5852b0563631STom Van Eyck 5853b0563631STom Van Eyck continue; 5854b0563631STom Van Eyck } 5855b0563631STom Van Eyck 5856b0563631STom Van Eyck if (tls12_prf->left_in_block > output_length) { 5857b0563631STom Van Eyck length = (uint8_t) output_length; 5858b0563631STom Van Eyck } else { 5859b0563631STom Van Eyck length = tls12_prf->left_in_block; 5860b0563631STom Van Eyck } 5861b0563631STom Van Eyck 5862b0563631STom Van Eyck offset = hash_length - tls12_prf->left_in_block; 5863b0563631STom Van Eyck memcpy(output, tls12_prf->output_block + offset, length); 5864b0563631STom Van Eyck output += length; 5865b0563631STom Van Eyck output_length -= length; 5866b0563631STom Van Eyck tls12_prf->left_in_block -= length; 5867b0563631STom Van Eyck } 5868b0563631STom Van Eyck 5869b0563631STom Van Eyck return PSA_SUCCESS; 5870b0563631STom Van Eyck } 5871b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF || 5872b0563631STom Van Eyck * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ 5873b0563631STom Van Eyck 5874b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) 5875b0563631STom Van Eyck static psa_status_t psa_key_derivation_tls12_ecjpake_to_pms_read( 5876b0563631STom Van Eyck psa_tls12_ecjpake_to_pms_t *ecjpake, 5877b0563631STom Van Eyck uint8_t *output, 5878b0563631STom Van Eyck size_t output_length) 5879b0563631STom Van Eyck { 5880b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 5881b0563631STom Van Eyck size_t output_size = 0; 5882b0563631STom Van Eyck 5883b0563631STom Van Eyck if (output_length != 32) { 5884b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 5885b0563631STom Van Eyck } 5886b0563631STom Van Eyck 5887b0563631STom Van Eyck status = psa_hash_compute(PSA_ALG_SHA_256, ecjpake->data, 5888b0563631STom Van Eyck PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE, output, output_length, 5889b0563631STom Van Eyck &output_size); 5890b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5891b0563631STom Van Eyck return status; 5892b0563631STom Van Eyck } 5893b0563631STom Van Eyck 5894b0563631STom Van Eyck if (output_size != output_length) { 5895b0563631STom Van Eyck return PSA_ERROR_GENERIC_ERROR; 5896b0563631STom Van Eyck } 5897b0563631STom Van Eyck 5898b0563631STom Van Eyck return PSA_SUCCESS; 5899b0563631STom Van Eyck } 5900b0563631STom Van Eyck #endif 5901b0563631STom Van Eyck 5902b0563631STom Van Eyck #if defined(PSA_HAVE_SOFT_PBKDF2) 5903b0563631STom Van Eyck static psa_status_t psa_key_derivation_pbkdf2_generate_block( 5904b0563631STom Van Eyck psa_pbkdf2_key_derivation_t *pbkdf2, 5905b0563631STom Van Eyck psa_algorithm_t prf_alg, 5906b0563631STom Van Eyck uint8_t prf_output_length, 5907b0563631STom Van Eyck psa_key_attributes_t *attributes) 5908b0563631STom Van Eyck { 5909b0563631STom Van Eyck psa_status_t status; 5910b0563631STom Van Eyck psa_mac_operation_t mac_operation = PSA_MAC_OPERATION_INIT; 5911b0563631STom Van Eyck size_t mac_output_length; 5912b0563631STom Van Eyck uint8_t U_i[PSA_MAC_MAX_SIZE]; 5913b0563631STom Van Eyck uint8_t *U_accumulator = pbkdf2->output_block; 5914b0563631STom Van Eyck uint64_t i; 5915b0563631STom Van Eyck uint8_t block_counter[4]; 5916b0563631STom Van Eyck 5917b0563631STom Van Eyck mac_operation.is_sign = 1; 5918b0563631STom Van Eyck mac_operation.mac_size = prf_output_length; 5919b0563631STom Van Eyck MBEDTLS_PUT_UINT32_BE(pbkdf2->block_number, block_counter, 0); 5920b0563631STom Van Eyck 5921b0563631STom Van Eyck status = psa_driver_wrapper_mac_sign_setup(&mac_operation, 5922b0563631STom Van Eyck attributes, 5923b0563631STom Van Eyck pbkdf2->password, 5924b0563631STom Van Eyck pbkdf2->password_length, 5925b0563631STom Van Eyck prf_alg); 5926b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5927b0563631STom Van Eyck goto cleanup; 5928b0563631STom Van Eyck } 5929b0563631STom Van Eyck status = psa_mac_update(&mac_operation, pbkdf2->salt, pbkdf2->salt_length); 5930b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5931b0563631STom Van Eyck goto cleanup; 5932b0563631STom Van Eyck } 5933b0563631STom Van Eyck status = psa_mac_update(&mac_operation, block_counter, sizeof(block_counter)); 5934b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5935b0563631STom Van Eyck goto cleanup; 5936b0563631STom Van Eyck } 5937b0563631STom Van Eyck status = psa_mac_sign_finish(&mac_operation, U_i, sizeof(U_i), 5938b0563631STom Van Eyck &mac_output_length); 5939b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5940b0563631STom Van Eyck goto cleanup; 5941b0563631STom Van Eyck } 5942b0563631STom Van Eyck 5943b0563631STom Van Eyck if (mac_output_length != prf_output_length) { 5944b0563631STom Van Eyck status = PSA_ERROR_CORRUPTION_DETECTED; 5945b0563631STom Van Eyck goto cleanup; 5946b0563631STom Van Eyck } 5947b0563631STom Van Eyck 5948b0563631STom Van Eyck memcpy(U_accumulator, U_i, prf_output_length); 5949b0563631STom Van Eyck 5950b0563631STom Van Eyck for (i = 1; i < pbkdf2->input_cost; i++) { 5951b0563631STom Van Eyck /* We are passing prf_output_length as mac_size because the driver 5952b0563631STom Van Eyck * function directly sets mac_output_length as mac_size upon success. 5953b0563631STom Van Eyck * See https://github.com/Mbed-TLS/mbedtls/issues/7801 */ 5954b0563631STom Van Eyck status = psa_driver_wrapper_mac_compute(attributes, 5955b0563631STom Van Eyck pbkdf2->password, 5956b0563631STom Van Eyck pbkdf2->password_length, 5957b0563631STom Van Eyck prf_alg, U_i, prf_output_length, 5958b0563631STom Van Eyck U_i, prf_output_length, 5959b0563631STom Van Eyck &mac_output_length); 5960b0563631STom Van Eyck if (status != PSA_SUCCESS) { 5961b0563631STom Van Eyck goto cleanup; 5962b0563631STom Van Eyck } 5963b0563631STom Van Eyck 5964b0563631STom Van Eyck mbedtls_xor(U_accumulator, U_accumulator, U_i, prf_output_length); 5965b0563631STom Van Eyck } 5966b0563631STom Van Eyck 5967b0563631STom Van Eyck cleanup: 5968b0563631STom Van Eyck /* Zeroise buffers to clear sensitive data from memory. */ 5969b0563631STom Van Eyck mbedtls_platform_zeroize(U_i, PSA_MAC_MAX_SIZE); 5970b0563631STom Van Eyck return status; 5971b0563631STom Van Eyck } 5972b0563631STom Van Eyck 5973b0563631STom Van Eyck static psa_status_t psa_key_derivation_pbkdf2_read( 5974b0563631STom Van Eyck psa_pbkdf2_key_derivation_t *pbkdf2, 5975b0563631STom Van Eyck psa_algorithm_t kdf_alg, 5976b0563631STom Van Eyck uint8_t *output, 5977b0563631STom Van Eyck size_t output_length) 5978b0563631STom Van Eyck { 5979b0563631STom Van Eyck psa_status_t status; 5980b0563631STom Van Eyck psa_algorithm_t prf_alg; 5981b0563631STom Van Eyck uint8_t prf_output_length; 5982b0563631STom Van Eyck psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 5983b0563631STom Van Eyck psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(pbkdf2->password_length)); 5984b0563631STom Van Eyck psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); 5985b0563631STom Van Eyck 5986b0563631STom Van Eyck if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) { 5987b0563631STom Van Eyck prf_alg = PSA_ALG_HMAC(PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg)); 5988b0563631STom Van Eyck prf_output_length = PSA_HASH_LENGTH(prf_alg); 5989b0563631STom Van Eyck psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); 5990b0563631STom Van Eyck } else if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) { 5991b0563631STom Van Eyck prf_alg = PSA_ALG_CMAC; 5992b0563631STom Van Eyck prf_output_length = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC); 5993b0563631STom Van Eyck psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); 5994b0563631STom Van Eyck } else { 5995b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 5996b0563631STom Van Eyck } 5997b0563631STom Van Eyck 5998b0563631STom Van Eyck switch (pbkdf2->state) { 5999b0563631STom Van Eyck case PSA_PBKDF2_STATE_PASSWORD_SET: 6000b0563631STom Van Eyck /* Initially we need a new block so bytes_used is equal to block size*/ 6001b0563631STom Van Eyck pbkdf2->bytes_used = prf_output_length; 6002b0563631STom Van Eyck pbkdf2->state = PSA_PBKDF2_STATE_OUTPUT; 6003b0563631STom Van Eyck break; 6004b0563631STom Van Eyck case PSA_PBKDF2_STATE_OUTPUT: 6005b0563631STom Van Eyck break; 6006b0563631STom Van Eyck default: 6007b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6008b0563631STom Van Eyck } 6009b0563631STom Van Eyck 6010b0563631STom Van Eyck while (output_length != 0) { 6011b0563631STom Van Eyck uint8_t n = prf_output_length - pbkdf2->bytes_used; 6012b0563631STom Van Eyck if (n > output_length) { 6013b0563631STom Van Eyck n = (uint8_t) output_length; 6014b0563631STom Van Eyck } 6015b0563631STom Van Eyck memcpy(output, pbkdf2->output_block + pbkdf2->bytes_used, n); 6016b0563631STom Van Eyck output += n; 6017b0563631STom Van Eyck output_length -= n; 6018b0563631STom Van Eyck pbkdf2->bytes_used += n; 6019b0563631STom Van Eyck 6020b0563631STom Van Eyck if (output_length == 0) { 6021b0563631STom Van Eyck break; 6022b0563631STom Van Eyck } 6023b0563631STom Van Eyck 6024b0563631STom Van Eyck /* We need a new block */ 6025b0563631STom Van Eyck pbkdf2->bytes_used = 0; 6026b0563631STom Van Eyck pbkdf2->block_number++; 6027b0563631STom Van Eyck 6028b0563631STom Van Eyck status = psa_key_derivation_pbkdf2_generate_block(pbkdf2, prf_alg, 6029b0563631STom Van Eyck prf_output_length, 6030b0563631STom Van Eyck &attributes); 6031b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6032b0563631STom Van Eyck return status; 6033b0563631STom Van Eyck } 6034b0563631STom Van Eyck } 6035b0563631STom Van Eyck 6036b0563631STom Van Eyck return PSA_SUCCESS; 6037b0563631STom Van Eyck } 6038b0563631STom Van Eyck #endif /* PSA_HAVE_SOFT_PBKDF2 */ 6039b0563631STom Van Eyck 6040b0563631STom Van Eyck psa_status_t psa_key_derivation_output_bytes( 6041b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 6042b0563631STom Van Eyck uint8_t *output_external, 6043b0563631STom Van Eyck size_t output_length) 6044b0563631STom Van Eyck { 6045b0563631STom Van Eyck psa_status_t status; 6046b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 6047b0563631STom Van Eyck 6048b0563631STom Van Eyck psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation); 6049b0563631STom Van Eyck 6050b0563631STom Van Eyck if (operation->alg == 0) { 6051b0563631STom Van Eyck /* This is a blank operation. */ 6052b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6053b0563631STom Van Eyck } 6054b0563631STom Van Eyck 6055b0563631STom Van Eyck if (output_length == 0 && operation->capacity == 0) { 6056b0563631STom Van Eyck /* Edge case: this is a finished operation, and 0 bytes 6057b0563631STom Van Eyck * were requested. The right error in this case could 6058b0563631STom Van Eyck * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return 6059b0563631STom Van Eyck * INSUFFICIENT_CAPACITY, which is right for a finished 6060b0563631STom Van Eyck * operation, for consistency with the case when 6061b0563631STom Van Eyck * output_length > 0. */ 6062b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_DATA; 6063b0563631STom Van Eyck } 6064b0563631STom Van Eyck 6065b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_length, output); 6066b0563631STom Van Eyck if (output_length > operation->capacity) { 6067b0563631STom Van Eyck operation->capacity = 0; 6068b0563631STom Van Eyck /* Go through the error path to wipe all confidential data now 6069b0563631STom Van Eyck * that the operation object is useless. */ 6070b0563631STom Van Eyck status = PSA_ERROR_INSUFFICIENT_DATA; 6071b0563631STom Van Eyck goto exit; 6072b0563631STom Van Eyck } 6073b0563631STom Van Eyck 6074b0563631STom Van Eyck operation->capacity -= output_length; 6075b0563631STom Van Eyck 6076b0563631STom Van Eyck #if defined(BUILTIN_ALG_ANY_HKDF) 6077b0563631STom Van Eyck if (PSA_ALG_IS_ANY_HKDF(kdf_alg)) { 6078b0563631STom Van Eyck status = psa_key_derivation_hkdf_read(&operation->ctx.hkdf, kdf_alg, 6079b0563631STom Van Eyck output, output_length); 6080b0563631STom Van Eyck } else 6081b0563631STom Van Eyck #endif /* BUILTIN_ALG_ANY_HKDF */ 6082b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ 6083b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) 6084b0563631STom Van Eyck if (PSA_ALG_IS_TLS12_PRF(kdf_alg) || 6085b0563631STom Van Eyck PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) { 6086b0563631STom Van Eyck status = psa_key_derivation_tls12_prf_read(&operation->ctx.tls12_prf, 6087b0563631STom Van Eyck kdf_alg, output, 6088b0563631STom Van Eyck output_length); 6089b0563631STom Van Eyck } else 6090b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF || 6091b0563631STom Van Eyck * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ 6092b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) 6093b0563631STom Van Eyck if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { 6094b0563631STom Van Eyck status = psa_key_derivation_tls12_ecjpake_to_pms_read( 6095b0563631STom Van Eyck &operation->ctx.tls12_ecjpake_to_pms, output, output_length); 6096b0563631STom Van Eyck } else 6097b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */ 6098b0563631STom Van Eyck #if defined(PSA_HAVE_SOFT_PBKDF2) 6099b0563631STom Van Eyck if (PSA_ALG_IS_PBKDF2(kdf_alg)) { 6100b0563631STom Van Eyck status = psa_key_derivation_pbkdf2_read(&operation->ctx.pbkdf2, kdf_alg, 6101b0563631STom Van Eyck output, output_length); 6102b0563631STom Van Eyck } else 6103b0563631STom Van Eyck #endif /* PSA_HAVE_SOFT_PBKDF2 */ 6104b0563631STom Van Eyck 6105b0563631STom Van Eyck { 6106b0563631STom Van Eyck (void) kdf_alg; 6107b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 6108b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 6109b0563631STom Van Eyck 6110b0563631STom Van Eyck return status; 6111b0563631STom Van Eyck } 6112b0563631STom Van Eyck 6113b0563631STom Van Eyck exit: 6114b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6115b0563631STom Van Eyck /* Preserve the algorithm upon errors, but clear all sensitive state. 6116b0563631STom Van Eyck * This allows us to differentiate between exhausted operations and 6117b0563631STom Van Eyck * blank operations, so we can return PSA_ERROR_BAD_STATE on blank 6118b0563631STom Van Eyck * operations. */ 6119b0563631STom Van Eyck psa_algorithm_t alg = operation->alg; 6120b0563631STom Van Eyck psa_key_derivation_abort(operation); 6121b0563631STom Van Eyck operation->alg = alg; 6122b0563631STom Van Eyck if (output != NULL) { 6123b0563631STom Van Eyck memset(output, '!', output_length); 6124b0563631STom Van Eyck } 6125b0563631STom Van Eyck } 6126b0563631STom Van Eyck 6127b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 6128b0563631STom Van Eyck return status; 6129b0563631STom Van Eyck } 6130b0563631STom Van Eyck 6131b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) 6132b0563631STom Van Eyck static void psa_des_set_key_parity(uint8_t *data, size_t data_size) 6133b0563631STom Van Eyck { 6134b0563631STom Van Eyck if (data_size >= 8) { 6135b0563631STom Van Eyck mbedtls_des_key_set_parity(data); 6136b0563631STom Van Eyck } 6137b0563631STom Van Eyck if (data_size >= 16) { 6138b0563631STom Van Eyck mbedtls_des_key_set_parity(data + 8); 6139b0563631STom Van Eyck } 6140b0563631STom Van Eyck if (data_size >= 24) { 6141b0563631STom Van Eyck mbedtls_des_key_set_parity(data + 16); 6142b0563631STom Van Eyck } 6143b0563631STom Van Eyck } 6144b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */ 6145b0563631STom Van Eyck 6146b0563631STom Van Eyck /* 6147b0563631STom Van Eyck * ECC keys on a Weierstrass elliptic curve require the generation 6148b0563631STom Van Eyck * of a private key which is an integer 6149b0563631STom Van Eyck * in the range [1, N - 1], where N is the boundary of the private key domain: 6150b0563631STom Van Eyck * N is the prime p for Diffie-Hellman, or the order of the 6151b0563631STom Van Eyck * curve’s base point for ECC. 6152b0563631STom Van Eyck * 6153b0563631STom Van Eyck * Let m be the bit size of N, such that 2^m > N >= 2^(m-1). 6154b0563631STom Van Eyck * This function generates the private key using the following process: 6155b0563631STom Van Eyck * 6156b0563631STom Van Eyck * 1. Draw a byte string of length ceiling(m/8) bytes. 6157b0563631STom Van Eyck * 2. If m is not a multiple of 8, set the most significant 6158b0563631STom Van Eyck * (8 * ceiling(m/8) - m) bits of the first byte in the string to zero. 6159b0563631STom Van Eyck * 3. Convert the string to integer k by decoding it as a big-endian byte string. 6160b0563631STom Van Eyck * 4. If k > N - 2, discard the result and return to step 1. 6161b0563631STom Van Eyck * 5. Output k + 1 as the private key. 6162b0563631STom Van Eyck * 6163b0563631STom Van Eyck * This method allows compliance to NIST standards, specifically the methods titled 6164b0563631STom Van Eyck * Key-Pair Generation by Testing Candidates in the following publications: 6165b0563631STom Van Eyck * - NIST Special Publication 800-56A: Recommendation for Pair-Wise Key-Establishment 6166b0563631STom Van Eyck * Schemes Using Discrete Logarithm Cryptography [SP800-56A] §5.6.1.1.4 for 6167b0563631STom Van Eyck * Diffie-Hellman keys. 6168b0563631STom Van Eyck * 6169b0563631STom Van Eyck * - [SP800-56A] §5.6.1.2.2 or FIPS Publication 186-4: Digital Signature 6170b0563631STom Van Eyck * Standard (DSS) [FIPS186-4] §B.4.2 for elliptic curve keys. 6171b0563631STom Van Eyck * 6172b0563631STom Van Eyck * Note: Function allocates memory for *data buffer, so given *data should be 6173b0563631STom Van Eyck * always NULL. 6174b0563631STom Van Eyck */ 6175b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) 6176b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) 6177b0563631STom Van Eyck static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper( 6178b0563631STom Van Eyck psa_key_slot_t *slot, 6179b0563631STom Van Eyck size_t bits, 6180b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 6181b0563631STom Van Eyck uint8_t **data 6182b0563631STom Van Eyck ) 6183b0563631STom Van Eyck { 6184b0563631STom Van Eyck unsigned key_out_of_range = 1; 6185b0563631STom Van Eyck mbedtls_mpi k; 6186b0563631STom Van Eyck mbedtls_mpi diff_N_2; 6187b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 6188b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 6189b0563631STom Van Eyck size_t m; 6190b0563631STom Van Eyck size_t m_bytes; 6191b0563631STom Van Eyck 6192b0563631STom Van Eyck mbedtls_mpi_init(&k); 6193b0563631STom Van Eyck mbedtls_mpi_init(&diff_N_2); 6194b0563631STom Van Eyck 6195b0563631STom Van Eyck psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( 6196b0563631STom Van Eyck slot->attr.type); 6197b0563631STom Van Eyck mbedtls_ecp_group_id grp_id = 6198b0563631STom Van Eyck mbedtls_ecc_group_from_psa(curve, bits); 6199b0563631STom Van Eyck 6200b0563631STom Van Eyck if (grp_id == MBEDTLS_ECP_DP_NONE) { 6201b0563631STom Van Eyck ret = MBEDTLS_ERR_ASN1_INVALID_DATA; 6202b0563631STom Van Eyck goto cleanup; 6203b0563631STom Van Eyck } 6204b0563631STom Van Eyck 6205b0563631STom Van Eyck mbedtls_ecp_group ecp_group; 6206b0563631STom Van Eyck mbedtls_ecp_group_init(&ecp_group); 6207b0563631STom Van Eyck 6208b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&ecp_group, grp_id)); 6209b0563631STom Van Eyck 6210b0563631STom Van Eyck /* N is the boundary of the private key domain (ecp_group.N). */ 6211b0563631STom Van Eyck /* Let m be the bit size of N. */ 6212b0563631STom Van Eyck m = ecp_group.nbits; 6213b0563631STom Van Eyck 6214b0563631STom Van Eyck m_bytes = PSA_BITS_TO_BYTES(m); 6215b0563631STom Van Eyck 6216b0563631STom Van Eyck /* Calculate N - 2 - it will be needed later. */ 6217b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&diff_N_2, &ecp_group.N, 2)); 6218b0563631STom Van Eyck 6219b0563631STom Van Eyck /* Note: This function is always called with *data == NULL and it 6220b0563631STom Van Eyck * allocates memory for the data buffer. */ 6221b0563631STom Van Eyck *data = mbedtls_calloc(1, m_bytes); 6222b0563631STom Van Eyck if (*data == NULL) { 6223b0563631STom Van Eyck ret = MBEDTLS_ERR_ASN1_ALLOC_FAILED; 6224b0563631STom Van Eyck goto cleanup; 6225b0563631STom Van Eyck } 6226b0563631STom Van Eyck 6227b0563631STom Van Eyck while (key_out_of_range) { 6228b0563631STom Van Eyck /* 1. Draw a byte string of length ceiling(m/8) bytes. */ 6229b0563631STom Van Eyck if ((status = psa_key_derivation_output_bytes(operation, *data, m_bytes)) != 0) { 6230b0563631STom Van Eyck goto cleanup; 6231b0563631STom Van Eyck } 6232b0563631STom Van Eyck 6233b0563631STom Van Eyck /* 2. If m is not a multiple of 8 */ 6234b0563631STom Van Eyck if (m % 8 != 0) { 6235b0563631STom Van Eyck /* Set the most significant 6236b0563631STom Van Eyck * (8 * ceiling(m/8) - m) bits of the first byte in 6237b0563631STom Van Eyck * the string to zero. 6238b0563631STom Van Eyck */ 6239b0563631STom Van Eyck uint8_t clear_bit_mask = (1 << (m % 8)) - 1; 6240b0563631STom Van Eyck (*data)[0] &= clear_bit_mask; 6241b0563631STom Van Eyck } 6242b0563631STom Van Eyck 6243b0563631STom Van Eyck /* 3. Convert the string to integer k by decoding it as a 6244b0563631STom Van Eyck * big-endian byte string. 6245b0563631STom Van Eyck */ 6246b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&k, *data, m_bytes)); 6247b0563631STom Van Eyck 6248b0563631STom Van Eyck /* 4. If k > N - 2, discard the result and return to step 1. 6249b0563631STom Van Eyck * Result of comparison is returned. When it indicates error 6250b0563631STom Van Eyck * then this function is called again. 6251b0563631STom Van Eyck */ 6252b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_lt_mpi_ct(&diff_N_2, &k, &key_out_of_range)); 6253b0563631STom Van Eyck } 6254b0563631STom Van Eyck 6255b0563631STom Van Eyck /* 5. Output k + 1 as the private key. */ 6256b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&k, &k, 1)); 6257b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&k, *data, m_bytes)); 6258b0563631STom Van Eyck cleanup: 6259b0563631STom Van Eyck if (ret != 0) { 6260b0563631STom Van Eyck status = mbedtls_to_psa_error(ret); 6261b0563631STom Van Eyck } 6262b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6263b0563631STom Van Eyck mbedtls_free(*data); 6264b0563631STom Van Eyck *data = NULL; 6265b0563631STom Van Eyck } 6266b0563631STom Van Eyck mbedtls_mpi_free(&k); 6267b0563631STom Van Eyck mbedtls_mpi_free(&diff_N_2); 6268b0563631STom Van Eyck return status; 6269b0563631STom Van Eyck } 6270b0563631STom Van Eyck 6271b0563631STom Van Eyck /* ECC keys on a Montgomery elliptic curve draws a byte string whose length 6272b0563631STom Van Eyck * is determined by the curve, and sets the mandatory bits accordingly. That is: 6273b0563631STom Van Eyck * 6274b0563631STom Van Eyck * - Curve25519 (PSA_ECC_FAMILY_MONTGOMERY, 255 bits): 6275b0563631STom Van Eyck * draw a 32-byte string and process it as specified in 6276b0563631STom Van Eyck * Elliptic Curves for Security [RFC7748] §5. 6277b0563631STom Van Eyck * 6278b0563631STom Van Eyck * - Curve448 (PSA_ECC_FAMILY_MONTGOMERY, 448 bits): 6279b0563631STom Van Eyck * draw a 56-byte string and process it as specified in [RFC7748] §5. 6280b0563631STom Van Eyck * 6281b0563631STom Van Eyck * Note: Function allocates memory for *data buffer, so given *data should be 6282b0563631STom Van Eyck * always NULL. 6283b0563631STom Van Eyck */ 6284b0563631STom Van Eyck 6285b0563631STom Van Eyck static psa_status_t psa_generate_derived_ecc_key_montgomery_helper( 6286b0563631STom Van Eyck size_t bits, 6287b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 6288b0563631STom Van Eyck uint8_t **data 6289b0563631STom Van Eyck ) 6290b0563631STom Van Eyck { 6291b0563631STom Van Eyck size_t output_length; 6292b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 6293b0563631STom Van Eyck 6294b0563631STom Van Eyck switch (bits) { 6295b0563631STom Van Eyck case 255: 6296b0563631STom Van Eyck output_length = 32; 6297b0563631STom Van Eyck break; 6298b0563631STom Van Eyck case 448: 6299b0563631STom Van Eyck output_length = 56; 6300b0563631STom Van Eyck break; 6301b0563631STom Van Eyck default: 6302b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6303b0563631STom Van Eyck break; 6304b0563631STom Van Eyck } 6305b0563631STom Van Eyck 6306b0563631STom Van Eyck *data = mbedtls_calloc(1, output_length); 6307b0563631STom Van Eyck 6308b0563631STom Van Eyck if (*data == NULL) { 6309b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 6310b0563631STom Van Eyck } 6311b0563631STom Van Eyck 6312b0563631STom Van Eyck status = psa_key_derivation_output_bytes(operation, *data, output_length); 6313b0563631STom Van Eyck 6314b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6315b0563631STom Van Eyck return status; 6316b0563631STom Van Eyck } 6317b0563631STom Van Eyck 6318b0563631STom Van Eyck switch (bits) { 6319b0563631STom Van Eyck case 255: 6320b0563631STom Van Eyck (*data)[0] &= 248; 6321b0563631STom Van Eyck (*data)[31] &= 127; 6322b0563631STom Van Eyck (*data)[31] |= 64; 6323b0563631STom Van Eyck break; 6324b0563631STom Van Eyck case 448: 6325b0563631STom Van Eyck (*data)[0] &= 252; 6326b0563631STom Van Eyck (*data)[55] |= 128; 6327b0563631STom Van Eyck break; 6328b0563631STom Van Eyck default: 6329b0563631STom Van Eyck return PSA_ERROR_CORRUPTION_DETECTED; 6330b0563631STom Van Eyck break; 6331b0563631STom Van Eyck } 6332b0563631STom Van Eyck 6333b0563631STom Van Eyck return status; 6334b0563631STom Van Eyck } 6335b0563631STom Van Eyck #else /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE */ 6336b0563631STom Van Eyck static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper( 6337b0563631STom Van Eyck psa_key_slot_t *slot, size_t bits, 6338b0563631STom Van Eyck psa_key_derivation_operation_t *operation, uint8_t **data) 6339b0563631STom Van Eyck { 6340b0563631STom Van Eyck (void) slot; 6341b0563631STom Van Eyck (void) bits; 6342b0563631STom Van Eyck (void) operation; 6343b0563631STom Van Eyck (void) data; 6344b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 6345b0563631STom Van Eyck } 6346b0563631STom Van Eyck 6347b0563631STom Van Eyck static psa_status_t psa_generate_derived_ecc_key_montgomery_helper( 6348b0563631STom Van Eyck size_t bits, psa_key_derivation_operation_t *operation, uint8_t **data) 6349b0563631STom Van Eyck { 6350b0563631STom Van Eyck (void) bits; 6351b0563631STom Van Eyck (void) operation; 6352b0563631STom Van Eyck (void) data; 6353b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 6354b0563631STom Van Eyck } 6355b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE */ 6356b0563631STom Van Eyck #endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE */ 6357b0563631STom Van Eyck 6358b0563631STom Van Eyck static psa_status_t psa_generate_derived_key_internal( 6359b0563631STom Van Eyck psa_key_slot_t *slot, 6360b0563631STom Van Eyck size_t bits, 6361b0563631STom Van Eyck psa_key_derivation_operation_t *operation) 6362b0563631STom Van Eyck { 6363b0563631STom Van Eyck uint8_t *data = NULL; 6364b0563631STom Van Eyck size_t bytes = PSA_BITS_TO_BYTES(bits); 6365b0563631STom Van Eyck size_t storage_size = bytes; 6366b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 6367b0563631STom Van Eyck 6368b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type)) { 6369b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6370b0563631STom Van Eyck } 6371b0563631STom Van Eyck 6372b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || \ 6373b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) 6374b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_ECC(slot->attr.type)) { 6375b0563631STom Van Eyck psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(slot->attr.type); 6376b0563631STom Van Eyck if (PSA_ECC_FAMILY_IS_WEIERSTRASS(curve)) { 6377b0563631STom Van Eyck /* Weierstrass elliptic curve */ 6378b0563631STom Van Eyck status = psa_generate_derived_ecc_key_weierstrass_helper(slot, bits, operation, &data); 6379b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6380b0563631STom Van Eyck goto exit; 6381b0563631STom Van Eyck } 6382b0563631STom Van Eyck } else { 6383b0563631STom Van Eyck /* Montgomery elliptic curve */ 6384b0563631STom Van Eyck status = psa_generate_derived_ecc_key_montgomery_helper(bits, operation, &data); 6385b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6386b0563631STom Van Eyck goto exit; 6387b0563631STom Van Eyck } 6388b0563631STom Van Eyck } 6389b0563631STom Van Eyck } else 6390b0563631STom Van Eyck #endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || 6391b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) */ 6392b0563631STom Van Eyck if (key_type_is_raw_bytes(slot->attr.type)) { 6393b0563631STom Van Eyck if (bits % 8 != 0) { 6394b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6395b0563631STom Van Eyck } 6396b0563631STom Van Eyck data = mbedtls_calloc(1, bytes); 6397b0563631STom Van Eyck if (data == NULL) { 6398b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 6399b0563631STom Van Eyck } 6400b0563631STom Van Eyck 6401b0563631STom Van Eyck status = psa_key_derivation_output_bytes(operation, data, bytes); 6402b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6403b0563631STom Van Eyck goto exit; 6404b0563631STom Van Eyck } 6405b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) 6406b0563631STom Van Eyck if (slot->attr.type == PSA_KEY_TYPE_DES) { 6407b0563631STom Van Eyck psa_des_set_key_parity(data, bytes); 6408b0563631STom Van Eyck } 6409b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) */ 6410b0563631STom Van Eyck } else { 6411b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 6412b0563631STom Van Eyck } 6413b0563631STom Van Eyck 6414b0563631STom Van Eyck slot->attr.bits = (psa_key_bits_t) bits; 6415b0563631STom Van Eyck 6416b0563631STom Van Eyck if (psa_key_lifetime_is_external(slot->attr.lifetime)) { 6417b0563631STom Van Eyck status = psa_driver_wrapper_get_key_buffer_size(&slot->attr, 6418b0563631STom Van Eyck &storage_size); 6419b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6420b0563631STom Van Eyck goto exit; 6421b0563631STom Van Eyck } 6422b0563631STom Van Eyck } 6423b0563631STom Van Eyck status = psa_allocate_buffer_to_slot(slot, storage_size); 6424b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6425b0563631STom Van Eyck goto exit; 6426b0563631STom Van Eyck } 6427b0563631STom Van Eyck 6428b0563631STom Van Eyck status = psa_driver_wrapper_import_key(&slot->attr, 6429b0563631STom Van Eyck data, bytes, 6430b0563631STom Van Eyck slot->key.data, 6431b0563631STom Van Eyck slot->key.bytes, 6432b0563631STom Van Eyck &slot->key.bytes, &bits); 6433b0563631STom Van Eyck if (bits != slot->attr.bits) { 6434b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 6435b0563631STom Van Eyck } 6436b0563631STom Van Eyck 6437b0563631STom Van Eyck exit: 6438b0563631STom Van Eyck mbedtls_free(data); 6439b0563631STom Van Eyck return status; 6440b0563631STom Van Eyck } 6441b0563631STom Van Eyck 6442*cb034002SJerome Forissier static const psa_custom_key_parameters_t default_custom_production = 6443*cb034002SJerome Forissier PSA_CUSTOM_KEY_PARAMETERS_INIT; 6444b0563631STom Van Eyck 6445*cb034002SJerome Forissier int psa_custom_key_parameters_are_default( 6446*cb034002SJerome Forissier const psa_custom_key_parameters_t *custom, 6447*cb034002SJerome Forissier size_t custom_data_length) 6448b0563631STom Van Eyck { 6449*cb034002SJerome Forissier if (custom->flags != 0) { 6450b0563631STom Van Eyck return 0; 6451b0563631STom Van Eyck } 6452*cb034002SJerome Forissier if (custom_data_length != 0) { 6453b0563631STom Van Eyck return 0; 6454b0563631STom Van Eyck } 6455b0563631STom Van Eyck return 1; 6456b0563631STom Van Eyck } 6457b0563631STom Van Eyck 6458*cb034002SJerome Forissier psa_status_t psa_key_derivation_output_key_custom( 6459b0563631STom Van Eyck const psa_key_attributes_t *attributes, 6460b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 6461*cb034002SJerome Forissier const psa_custom_key_parameters_t *custom, 6462*cb034002SJerome Forissier const uint8_t *custom_data, 6463*cb034002SJerome Forissier size_t custom_data_length, 6464b0563631STom Van Eyck mbedtls_svc_key_id_t *key) 6465b0563631STom Van Eyck { 6466b0563631STom Van Eyck psa_status_t status; 6467b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 6468b0563631STom Van Eyck psa_se_drv_table_entry_t *driver = NULL; 6469b0563631STom Van Eyck 6470b0563631STom Van Eyck *key = MBEDTLS_SVC_KEY_ID_INIT; 6471b0563631STom Van Eyck 6472b0563631STom Van Eyck /* Reject any attempt to create a zero-length key so that we don't 6473b0563631STom Van Eyck * risk tripping up later, e.g. on a malloc(0) that returns NULL. */ 6474b0563631STom Van Eyck if (psa_get_key_bits(attributes) == 0) { 6475b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6476b0563631STom Van Eyck } 6477b0563631STom Van Eyck 6478*cb034002SJerome Forissier (void) custom_data; /* We only accept 0-length data */ 6479*cb034002SJerome Forissier if (!psa_custom_key_parameters_are_default(custom, custom_data_length)) { 6480b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6481b0563631STom Van Eyck } 6482b0563631STom Van Eyck 6483b0563631STom Van Eyck if (operation->alg == PSA_ALG_NONE) { 6484b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6485b0563631STom Van Eyck } 6486b0563631STom Van Eyck 6487b0563631STom Van Eyck if (!operation->can_output_key) { 6488b0563631STom Van Eyck return PSA_ERROR_NOT_PERMITTED; 6489b0563631STom Van Eyck } 6490b0563631STom Van Eyck 6491b0563631STom Van Eyck status = psa_start_key_creation(PSA_KEY_CREATION_DERIVE, attributes, 6492b0563631STom Van Eyck &slot, &driver); 6493b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_SE_C) 6494b0563631STom Van Eyck if (driver != NULL) { 6495b0563631STom Van Eyck /* Deriving a key in a secure element is not implemented yet. */ 6496b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 6497b0563631STom Van Eyck } 6498b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ 6499b0563631STom Van Eyck if (status == PSA_SUCCESS) { 6500b0563631STom Van Eyck status = psa_generate_derived_key_internal(slot, 6501b0563631STom Van Eyck attributes->bits, 6502b0563631STom Van Eyck operation); 6503b0563631STom Van Eyck } 6504b0563631STom Van Eyck if (status == PSA_SUCCESS) { 6505b0563631STom Van Eyck status = psa_finish_key_creation(slot, driver, key); 6506b0563631STom Van Eyck } 6507b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6508b0563631STom Van Eyck psa_fail_key_creation(slot, driver); 6509b0563631STom Van Eyck } 6510b0563631STom Van Eyck 6511b0563631STom Van Eyck return status; 6512b0563631STom Van Eyck } 6513b0563631STom Van Eyck 6514*cb034002SJerome Forissier psa_status_t psa_key_derivation_output_key_ext( 6515*cb034002SJerome Forissier const psa_key_attributes_t *attributes, 6516*cb034002SJerome Forissier psa_key_derivation_operation_t *operation, 6517*cb034002SJerome Forissier const psa_key_production_parameters_t *params, 6518*cb034002SJerome Forissier size_t params_data_length, 6519*cb034002SJerome Forissier mbedtls_svc_key_id_t *key) 6520*cb034002SJerome Forissier { 6521*cb034002SJerome Forissier return psa_key_derivation_output_key_custom( 6522*cb034002SJerome Forissier attributes, operation, 6523*cb034002SJerome Forissier (const psa_custom_key_parameters_t *) params, 6524*cb034002SJerome Forissier params->data, params_data_length, 6525*cb034002SJerome Forissier key); 6526*cb034002SJerome Forissier } 6527*cb034002SJerome Forissier 6528b0563631STom Van Eyck psa_status_t psa_key_derivation_output_key( 6529b0563631STom Van Eyck const psa_key_attributes_t *attributes, 6530b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 6531b0563631STom Van Eyck mbedtls_svc_key_id_t *key) 6532b0563631STom Van Eyck { 6533*cb034002SJerome Forissier return psa_key_derivation_output_key_custom(attributes, operation, 6534*cb034002SJerome Forissier &default_custom_production, 6535*cb034002SJerome Forissier NULL, 0, 6536b0563631STom Van Eyck key); 6537b0563631STom Van Eyck } 6538b0563631STom Van Eyck 6539b0563631STom Van Eyck 6540b0563631STom Van Eyck /****************************************************************/ 6541b0563631STom Van Eyck /* Key derivation */ 6542b0563631STom Van Eyck /****************************************************************/ 6543b0563631STom Van Eyck 6544b0563631STom Van Eyck #if defined(AT_LEAST_ONE_BUILTIN_KDF) 6545b0563631STom Van Eyck static int is_kdf_alg_supported(psa_algorithm_t kdf_alg) 6546b0563631STom Van Eyck { 6547b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) 6548b0563631STom Van Eyck if (PSA_ALG_IS_HKDF(kdf_alg)) { 6549b0563631STom Van Eyck return 1; 6550b0563631STom Van Eyck } 6551b0563631STom Van Eyck #endif 6552b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) 6553b0563631STom Van Eyck if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) { 6554b0563631STom Van Eyck return 1; 6555b0563631STom Van Eyck } 6556b0563631STom Van Eyck #endif 6557b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) 6558b0563631STom Van Eyck if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) { 6559b0563631STom Van Eyck return 1; 6560b0563631STom Van Eyck } 6561b0563631STom Van Eyck #endif 6562b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) 6563b0563631STom Van Eyck if (PSA_ALG_IS_TLS12_PRF(kdf_alg)) { 6564b0563631STom Van Eyck return 1; 6565b0563631STom Van Eyck } 6566b0563631STom Van Eyck #endif 6567b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) 6568b0563631STom Van Eyck if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) { 6569b0563631STom Van Eyck return 1; 6570b0563631STom Van Eyck } 6571b0563631STom Van Eyck #endif 6572b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) 6573b0563631STom Van Eyck if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { 6574b0563631STom Van Eyck return 1; 6575b0563631STom Van Eyck } 6576b0563631STom Van Eyck #endif 6577b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC) 6578b0563631STom Van Eyck if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) { 6579b0563631STom Van Eyck return 1; 6580b0563631STom Van Eyck } 6581b0563631STom Van Eyck #endif 6582b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128) 6583b0563631STom Van Eyck if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) { 6584b0563631STom Van Eyck return 1; 6585b0563631STom Van Eyck } 6586b0563631STom Van Eyck #endif 6587b0563631STom Van Eyck return 0; 6588b0563631STom Van Eyck } 6589b0563631STom Van Eyck 6590b0563631STom Van Eyck static psa_status_t psa_hash_try_support(psa_algorithm_t alg) 6591b0563631STom Van Eyck { 6592b0563631STom Van Eyck psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; 6593b0563631STom Van Eyck psa_status_t status = psa_hash_setup(&operation, alg); 6594b0563631STom Van Eyck psa_hash_abort(&operation); 6595b0563631STom Van Eyck return status; 6596b0563631STom Van Eyck } 6597b0563631STom Van Eyck 6598b0563631STom Van Eyck static psa_status_t psa_key_derivation_set_maximum_capacity( 6599b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 6600b0563631STom Van Eyck psa_algorithm_t kdf_alg) 6601b0563631STom Van Eyck { 6602b0563631STom Van Eyck #if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) 6603b0563631STom Van Eyck if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { 6604b0563631STom Van Eyck operation->capacity = PSA_HASH_LENGTH(PSA_ALG_SHA_256); 6605b0563631STom Van Eyck return PSA_SUCCESS; 6606b0563631STom Van Eyck } 6607b0563631STom Van Eyck #endif 6608b0563631STom Van Eyck #if defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128) 6609b0563631STom Van Eyck if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) { 6610b0563631STom Van Eyck #if (SIZE_MAX > UINT32_MAX) 6611b0563631STom Van Eyck operation->capacity = UINT32_MAX * (size_t) PSA_MAC_LENGTH( 6612b0563631STom Van Eyck PSA_KEY_TYPE_AES, 6613b0563631STom Van Eyck 128U, 6614b0563631STom Van Eyck PSA_ALG_CMAC); 6615b0563631STom Van Eyck #else 6616b0563631STom Van Eyck operation->capacity = SIZE_MAX; 6617b0563631STom Van Eyck #endif 6618b0563631STom Van Eyck return PSA_SUCCESS; 6619b0563631STom Van Eyck } 6620b0563631STom Van Eyck #endif /* PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 */ 6621b0563631STom Van Eyck 6622b0563631STom Van Eyck /* After this point, if kdf_alg is not valid then value of hash_alg may be 6623b0563631STom Van Eyck * invalid or meaningless but it does not affect this function */ 6624b0563631STom Van Eyck psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(kdf_alg); 6625b0563631STom Van Eyck size_t hash_size = PSA_HASH_LENGTH(hash_alg); 6626b0563631STom Van Eyck if (hash_size == 0) { 6627b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 6628b0563631STom Van Eyck } 6629b0563631STom Van Eyck 6630b0563631STom Van Eyck /* Make sure that hash_alg is a supported hash algorithm. Otherwise 6631b0563631STom Van Eyck * we might fail later, which is somewhat unfriendly and potentially 6632b0563631STom Van Eyck * risk-prone. */ 6633b0563631STom Van Eyck psa_status_t status = psa_hash_try_support(hash_alg); 6634b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6635b0563631STom Van Eyck return status; 6636b0563631STom Van Eyck } 6637b0563631STom Van Eyck 6638b0563631STom Van Eyck #if defined(PSA_WANT_ALG_HKDF) 6639b0563631STom Van Eyck if (PSA_ALG_IS_HKDF(kdf_alg)) { 6640b0563631STom Van Eyck operation->capacity = 255 * hash_size; 6641b0563631STom Van Eyck } else 6642b0563631STom Van Eyck #endif 6643b0563631STom Van Eyck #if defined(PSA_WANT_ALG_HKDF_EXTRACT) 6644b0563631STom Van Eyck if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) { 6645b0563631STom Van Eyck operation->capacity = hash_size; 6646b0563631STom Van Eyck } else 6647b0563631STom Van Eyck #endif 6648b0563631STom Van Eyck #if defined(PSA_WANT_ALG_HKDF_EXPAND) 6649b0563631STom Van Eyck if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) { 6650b0563631STom Van Eyck operation->capacity = 255 * hash_size; 6651b0563631STom Van Eyck } else 6652b0563631STom Van Eyck #endif 6653b0563631STom Van Eyck #if defined(PSA_WANT_ALG_TLS12_PRF) 6654b0563631STom Van Eyck if (PSA_ALG_IS_TLS12_PRF(kdf_alg) && 6655b0563631STom Van Eyck (hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384)) { 6656b0563631STom Van Eyck operation->capacity = SIZE_MAX; 6657b0563631STom Van Eyck } else 6658b0563631STom Van Eyck #endif 6659b0563631STom Van Eyck #if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS) 6660b0563631STom Van Eyck if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg) && 6661b0563631STom Van Eyck (hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384)) { 6662b0563631STom Van Eyck /* Master Secret is always 48 bytes 6663b0563631STom Van Eyck * https://datatracker.ietf.org/doc/html/rfc5246.html#section-8.1 */ 6664b0563631STom Van Eyck operation->capacity = 48U; 6665b0563631STom Van Eyck } else 6666b0563631STom Van Eyck #endif 6667b0563631STom Van Eyck #if defined(PSA_WANT_ALG_PBKDF2_HMAC) 6668b0563631STom Van Eyck if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) { 6669b0563631STom Van Eyck #if (SIZE_MAX > UINT32_MAX) 6670b0563631STom Van Eyck operation->capacity = UINT32_MAX * hash_size; 6671b0563631STom Van Eyck #else 6672b0563631STom Van Eyck operation->capacity = SIZE_MAX; 6673b0563631STom Van Eyck #endif 6674b0563631STom Van Eyck } else 6675b0563631STom Van Eyck #endif /* PSA_WANT_ALG_PBKDF2_HMAC */ 6676b0563631STom Van Eyck { 6677b0563631STom Van Eyck (void) hash_size; 6678b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 6679b0563631STom Van Eyck } 6680b0563631STom Van Eyck return status; 6681b0563631STom Van Eyck } 6682b0563631STom Van Eyck 6683b0563631STom Van Eyck static psa_status_t psa_key_derivation_setup_kdf( 6684b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 6685b0563631STom Van Eyck psa_algorithm_t kdf_alg) 6686b0563631STom Van Eyck { 6687b0563631STom Van Eyck /* Make sure that operation->ctx is properly zero-initialised. (Macro 6688b0563631STom Van Eyck * initialisers for this union leave some bytes unspecified.) */ 6689b0563631STom Van Eyck memset(&operation->ctx, 0, sizeof(operation->ctx)); 6690b0563631STom Van Eyck 6691b0563631STom Van Eyck /* Make sure that kdf_alg is a supported key derivation algorithm. */ 6692b0563631STom Van Eyck if (!is_kdf_alg_supported(kdf_alg)) { 6693b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 6694b0563631STom Van Eyck } 6695b0563631STom Van Eyck 6696b0563631STom Van Eyck psa_status_t status = psa_key_derivation_set_maximum_capacity(operation, 6697b0563631STom Van Eyck kdf_alg); 6698b0563631STom Van Eyck return status; 6699b0563631STom Van Eyck } 6700b0563631STom Van Eyck 6701b0563631STom Van Eyck static psa_status_t psa_key_agreement_try_support(psa_algorithm_t alg) 6702b0563631STom Van Eyck { 6703b0563631STom Van Eyck #if defined(PSA_WANT_ALG_ECDH) 6704b0563631STom Van Eyck if (alg == PSA_ALG_ECDH) { 6705b0563631STom Van Eyck return PSA_SUCCESS; 6706b0563631STom Van Eyck } 6707b0563631STom Van Eyck #endif 6708b0563631STom Van Eyck #if defined(PSA_WANT_ALG_FFDH) 6709b0563631STom Van Eyck if (alg == PSA_ALG_FFDH) { 6710b0563631STom Van Eyck return PSA_SUCCESS; 6711b0563631STom Van Eyck } 6712b0563631STom Van Eyck #endif 6713b0563631STom Van Eyck (void) alg; 6714b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 6715b0563631STom Van Eyck } 6716b0563631STom Van Eyck 6717b0563631STom Van Eyck static int psa_key_derivation_allows_free_form_secret_input( 6718b0563631STom Van Eyck psa_algorithm_t kdf_alg) 6719b0563631STom Van Eyck { 6720b0563631STom Van Eyck #if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) 6721b0563631STom Van Eyck if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { 6722b0563631STom Van Eyck return 0; 6723b0563631STom Van Eyck } 6724b0563631STom Van Eyck #endif 6725b0563631STom Van Eyck (void) kdf_alg; 6726b0563631STom Van Eyck return 1; 6727b0563631STom Van Eyck } 6728b0563631STom Van Eyck #endif /* AT_LEAST_ONE_BUILTIN_KDF */ 6729b0563631STom Van Eyck 6730b0563631STom Van Eyck psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation, 6731b0563631STom Van Eyck psa_algorithm_t alg) 6732b0563631STom Van Eyck { 6733b0563631STom Van Eyck psa_status_t status; 6734b0563631STom Van Eyck 6735b0563631STom Van Eyck if (operation->alg != 0) { 6736b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6737b0563631STom Van Eyck } 6738b0563631STom Van Eyck 6739b0563631STom Van Eyck if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) { 6740b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6741b0563631STom Van Eyck } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) { 6742b0563631STom Van Eyck #if defined(AT_LEAST_ONE_BUILTIN_KDF) 6743b0563631STom Van Eyck psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg); 6744b0563631STom Van Eyck psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE(alg); 6745b0563631STom Van Eyck status = psa_key_agreement_try_support(ka_alg); 6746b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6747b0563631STom Van Eyck return status; 6748b0563631STom Van Eyck } 6749b0563631STom Van Eyck if (!psa_key_derivation_allows_free_form_secret_input(kdf_alg)) { 6750b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6751b0563631STom Van Eyck } 6752b0563631STom Van Eyck status = psa_key_derivation_setup_kdf(operation, kdf_alg); 6753b0563631STom Van Eyck #else 6754b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 6755b0563631STom Van Eyck #endif /* AT_LEAST_ONE_BUILTIN_KDF */ 6756b0563631STom Van Eyck } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) { 6757b0563631STom Van Eyck #if defined(AT_LEAST_ONE_BUILTIN_KDF) 6758b0563631STom Van Eyck status = psa_key_derivation_setup_kdf(operation, alg); 6759b0563631STom Van Eyck #else 6760b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 6761b0563631STom Van Eyck #endif /* AT_LEAST_ONE_BUILTIN_KDF */ 6762b0563631STom Van Eyck } else { 6763b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6764b0563631STom Van Eyck } 6765b0563631STom Van Eyck 6766b0563631STom Van Eyck if (status == PSA_SUCCESS) { 6767b0563631STom Van Eyck operation->alg = alg; 6768b0563631STom Van Eyck } 6769b0563631STom Van Eyck return status; 6770b0563631STom Van Eyck } 6771b0563631STom Van Eyck 6772b0563631STom Van Eyck #if defined(BUILTIN_ALG_ANY_HKDF) 6773b0563631STom Van Eyck static psa_status_t psa_hkdf_input(psa_hkdf_key_derivation_t *hkdf, 6774b0563631STom Van Eyck psa_algorithm_t kdf_alg, 6775b0563631STom Van Eyck psa_key_derivation_step_t step, 6776b0563631STom Van Eyck const uint8_t *data, 6777b0563631STom Van Eyck size_t data_length) 6778b0563631STom Van Eyck { 6779b0563631STom Van Eyck psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg); 6780b0563631STom Van Eyck psa_status_t status; 6781b0563631STom Van Eyck switch (step) { 6782b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_SALT: 6783b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) 6784b0563631STom Van Eyck if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) { 6785b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6786b0563631STom Van Eyck } 6787b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND */ 6788b0563631STom Van Eyck if (hkdf->state != HKDF_STATE_INIT) { 6789b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6790b0563631STom Van Eyck } else { 6791b0563631STom Van Eyck status = psa_key_derivation_start_hmac(&hkdf->hmac, 6792b0563631STom Van Eyck hash_alg, 6793b0563631STom Van Eyck data, data_length); 6794b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6795b0563631STom Van Eyck return status; 6796b0563631STom Van Eyck } 6797b0563631STom Van Eyck hkdf->state = HKDF_STATE_STARTED; 6798b0563631STom Van Eyck return PSA_SUCCESS; 6799b0563631STom Van Eyck } 6800b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_SECRET: 6801b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) 6802b0563631STom Van Eyck if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) { 6803b0563631STom Van Eyck /* We shouldn't be in different state as HKDF_EXPAND only allows 6804b0563631STom Van Eyck * two inputs: SECRET (this case) and INFO which does not modify 6805b0563631STom Van Eyck * the state. It could happen only if the hkdf 6806b0563631STom Van Eyck * object was corrupted. */ 6807b0563631STom Van Eyck if (hkdf->state != HKDF_STATE_INIT) { 6808b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6809b0563631STom Van Eyck } 6810b0563631STom Van Eyck 6811b0563631STom Van Eyck /* Allow only input that fits expected prk size */ 6812b0563631STom Van Eyck if (data_length != PSA_HASH_LENGTH(hash_alg)) { 6813b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6814b0563631STom Van Eyck } 6815b0563631STom Van Eyck 6816b0563631STom Van Eyck memcpy(hkdf->prk, data, data_length); 6817b0563631STom Van Eyck } else 6818b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND */ 6819b0563631STom Van Eyck { 6820b0563631STom Van Eyck /* HKDF: If no salt was provided, use an empty salt. 6821b0563631STom Van Eyck * HKDF-EXTRACT: salt is mandatory. */ 6822b0563631STom Van Eyck if (hkdf->state == HKDF_STATE_INIT) { 6823b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) 6824b0563631STom Van Eyck if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) { 6825b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6826b0563631STom Van Eyck } 6827b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ 6828b0563631STom Van Eyck status = psa_key_derivation_start_hmac(&hkdf->hmac, 6829b0563631STom Van Eyck hash_alg, 6830b0563631STom Van Eyck NULL, 0); 6831b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6832b0563631STom Van Eyck return status; 6833b0563631STom Van Eyck } 6834b0563631STom Van Eyck hkdf->state = HKDF_STATE_STARTED; 6835b0563631STom Van Eyck } 6836b0563631STom Van Eyck if (hkdf->state != HKDF_STATE_STARTED) { 6837b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6838b0563631STom Van Eyck } 6839b0563631STom Van Eyck status = psa_mac_update(&hkdf->hmac, 6840b0563631STom Van Eyck data, data_length); 6841b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6842b0563631STom Van Eyck return status; 6843b0563631STom Van Eyck } 6844b0563631STom Van Eyck status = psa_mac_sign_finish(&hkdf->hmac, 6845b0563631STom Van Eyck hkdf->prk, 6846b0563631STom Van Eyck sizeof(hkdf->prk), 6847b0563631STom Van Eyck &data_length); 6848b0563631STom Van Eyck if (status != PSA_SUCCESS) { 6849b0563631STom Van Eyck return status; 6850b0563631STom Van Eyck } 6851b0563631STom Van Eyck } 6852b0563631STom Van Eyck 6853b0563631STom Van Eyck hkdf->state = HKDF_STATE_KEYED; 6854b0563631STom Van Eyck hkdf->block_number = 0; 6855b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) 6856b0563631STom Van Eyck if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) { 6857b0563631STom Van Eyck /* The only block of output is the PRK. */ 6858b0563631STom Van Eyck memcpy(hkdf->output_block, hkdf->prk, PSA_HASH_LENGTH(hash_alg)); 6859b0563631STom Van Eyck hkdf->offset_in_block = 0; 6860b0563631STom Van Eyck } else 6861b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ 6862b0563631STom Van Eyck { 6863b0563631STom Van Eyck /* Block 0 is empty, and the next block will be 6864b0563631STom Van Eyck * generated by psa_key_derivation_hkdf_read(). */ 6865b0563631STom Van Eyck hkdf->offset_in_block = PSA_HASH_LENGTH(hash_alg); 6866b0563631STom Van Eyck } 6867b0563631STom Van Eyck 6868b0563631STom Van Eyck return PSA_SUCCESS; 6869b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_INFO: 6870b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) 6871b0563631STom Van Eyck if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) { 6872b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6873b0563631STom Van Eyck } 6874b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ 6875b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) 6876b0563631STom Van Eyck if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg) && 6877b0563631STom Van Eyck hkdf->state == HKDF_STATE_INIT) { 6878b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6879b0563631STom Van Eyck } 6880b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ 6881b0563631STom Van Eyck if (hkdf->state == HKDF_STATE_OUTPUT) { 6882b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6883b0563631STom Van Eyck } 6884b0563631STom Van Eyck if (hkdf->info_set) { 6885b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6886b0563631STom Van Eyck } 6887b0563631STom Van Eyck hkdf->info_length = data_length; 6888b0563631STom Van Eyck if (data_length != 0) { 6889b0563631STom Van Eyck hkdf->info = mbedtls_calloc(1, data_length); 6890b0563631STom Van Eyck if (hkdf->info == NULL) { 6891b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 6892b0563631STom Van Eyck } 6893b0563631STom Van Eyck memcpy(hkdf->info, data, data_length); 6894b0563631STom Van Eyck } 6895b0563631STom Van Eyck hkdf->info_set = 1; 6896b0563631STom Van Eyck return PSA_SUCCESS; 6897b0563631STom Van Eyck default: 6898b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6899b0563631STom Van Eyck } 6900b0563631STom Van Eyck } 6901b0563631STom Van Eyck #endif /* BUILTIN_ALG_ANY_HKDF */ 6902b0563631STom Van Eyck 6903b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ 6904b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) 6905b0563631STom Van Eyck static psa_status_t psa_tls12_prf_set_seed(psa_tls12_prf_key_derivation_t *prf, 6906b0563631STom Van Eyck const uint8_t *data, 6907b0563631STom Van Eyck size_t data_length) 6908b0563631STom Van Eyck { 6909b0563631STom Van Eyck if (prf->state != PSA_TLS12_PRF_STATE_INIT) { 6910b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6911b0563631STom Van Eyck } 6912b0563631STom Van Eyck 6913b0563631STom Van Eyck if (data_length != 0) { 6914b0563631STom Van Eyck prf->seed = mbedtls_calloc(1, data_length); 6915b0563631STom Van Eyck if (prf->seed == NULL) { 6916b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 6917b0563631STom Van Eyck } 6918b0563631STom Van Eyck 6919b0563631STom Van Eyck memcpy(prf->seed, data, data_length); 6920b0563631STom Van Eyck prf->seed_length = data_length; 6921b0563631STom Van Eyck } 6922b0563631STom Van Eyck 6923b0563631STom Van Eyck prf->state = PSA_TLS12_PRF_STATE_SEED_SET; 6924b0563631STom Van Eyck 6925b0563631STom Van Eyck return PSA_SUCCESS; 6926b0563631STom Van Eyck } 6927b0563631STom Van Eyck 6928b0563631STom Van Eyck static psa_status_t psa_tls12_prf_set_key(psa_tls12_prf_key_derivation_t *prf, 6929b0563631STom Van Eyck const uint8_t *data, 6930b0563631STom Van Eyck size_t data_length) 6931b0563631STom Van Eyck { 6932b0563631STom Van Eyck if (prf->state != PSA_TLS12_PRF_STATE_SEED_SET && 6933b0563631STom Van Eyck prf->state != PSA_TLS12_PRF_STATE_OTHER_KEY_SET) { 6934b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6935b0563631STom Van Eyck } 6936b0563631STom Van Eyck 6937b0563631STom Van Eyck if (data_length != 0) { 6938b0563631STom Van Eyck prf->secret = mbedtls_calloc(1, data_length); 6939b0563631STom Van Eyck if (prf->secret == NULL) { 6940b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 6941b0563631STom Van Eyck } 6942b0563631STom Van Eyck 6943b0563631STom Van Eyck memcpy(prf->secret, data, data_length); 6944b0563631STom Van Eyck prf->secret_length = data_length; 6945b0563631STom Van Eyck } 6946b0563631STom Van Eyck 6947b0563631STom Van Eyck prf->state = PSA_TLS12_PRF_STATE_KEY_SET; 6948b0563631STom Van Eyck 6949b0563631STom Van Eyck return PSA_SUCCESS; 6950b0563631STom Van Eyck } 6951b0563631STom Van Eyck 6952b0563631STom Van Eyck static psa_status_t psa_tls12_prf_set_label(psa_tls12_prf_key_derivation_t *prf, 6953b0563631STom Van Eyck const uint8_t *data, 6954b0563631STom Van Eyck size_t data_length) 6955b0563631STom Van Eyck { 6956b0563631STom Van Eyck if (prf->state != PSA_TLS12_PRF_STATE_KEY_SET) { 6957b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 6958b0563631STom Van Eyck } 6959b0563631STom Van Eyck 6960b0563631STom Van Eyck if (data_length != 0) { 6961b0563631STom Van Eyck prf->label = mbedtls_calloc(1, data_length); 6962b0563631STom Van Eyck if (prf->label == NULL) { 6963b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 6964b0563631STom Van Eyck } 6965b0563631STom Van Eyck 6966b0563631STom Van Eyck memcpy(prf->label, data, data_length); 6967b0563631STom Van Eyck prf->label_length = data_length; 6968b0563631STom Van Eyck } 6969b0563631STom Van Eyck 6970b0563631STom Van Eyck prf->state = PSA_TLS12_PRF_STATE_LABEL_SET; 6971b0563631STom Van Eyck 6972b0563631STom Van Eyck return PSA_SUCCESS; 6973b0563631STom Van Eyck } 6974b0563631STom Van Eyck 6975b0563631STom Van Eyck static psa_status_t psa_tls12_prf_input(psa_tls12_prf_key_derivation_t *prf, 6976b0563631STom Van Eyck psa_key_derivation_step_t step, 6977b0563631STom Van Eyck const uint8_t *data, 6978b0563631STom Van Eyck size_t data_length) 6979b0563631STom Van Eyck { 6980b0563631STom Van Eyck switch (step) { 6981b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_SEED: 6982b0563631STom Van Eyck return psa_tls12_prf_set_seed(prf, data, data_length); 6983b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_SECRET: 6984b0563631STom Van Eyck return psa_tls12_prf_set_key(prf, data, data_length); 6985b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_LABEL: 6986b0563631STom Van Eyck return psa_tls12_prf_set_label(prf, data, data_length); 6987b0563631STom Van Eyck default: 6988b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 6989b0563631STom Van Eyck } 6990b0563631STom Van Eyck } 6991b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || 6992b0563631STom Van Eyck * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ 6993b0563631STom Van Eyck 6994b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) 6995b0563631STom Van Eyck static psa_status_t psa_tls12_prf_psk_to_ms_set_key( 6996b0563631STom Van Eyck psa_tls12_prf_key_derivation_t *prf, 6997b0563631STom Van Eyck const uint8_t *data, 6998b0563631STom Van Eyck size_t data_length) 6999b0563631STom Van Eyck { 7000b0563631STom Van Eyck psa_status_t status; 7001b0563631STom Van Eyck const size_t pms_len = (prf->state == PSA_TLS12_PRF_STATE_OTHER_KEY_SET ? 7002b0563631STom Van Eyck 4 + data_length + prf->other_secret_length : 7003b0563631STom Van Eyck 4 + 2 * data_length); 7004b0563631STom Van Eyck 7005b0563631STom Van Eyck if (data_length > PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE) { 7006b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7007b0563631STom Van Eyck } 7008b0563631STom Van Eyck 7009b0563631STom Van Eyck uint8_t *pms = mbedtls_calloc(1, pms_len); 7010b0563631STom Van Eyck if (pms == NULL) { 7011b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 7012b0563631STom Van Eyck } 7013b0563631STom Van Eyck uint8_t *cur = pms; 7014b0563631STom Van Eyck 7015b0563631STom Van Eyck /* pure-PSK: 7016b0563631STom Van Eyck * Quoting RFC 4279, Section 2: 7017b0563631STom Van Eyck * 7018b0563631STom Van Eyck * The premaster secret is formed as follows: if the PSK is N octets 7019b0563631STom Van Eyck * long, concatenate a uint16 with the value N, N zero octets, a second 7020b0563631STom Van Eyck * uint16 with the value N, and the PSK itself. 7021b0563631STom Van Eyck * 7022b0563631STom Van Eyck * mixed-PSK: 7023b0563631STom Van Eyck * In a DHE-PSK, RSA-PSK, ECDHE-PSK the premaster secret is formed as 7024b0563631STom Van Eyck * follows: concatenate a uint16 with the length of the other secret, 7025b0563631STom Van Eyck * the other secret itself, uint16 with the length of PSK, and the 7026b0563631STom Van Eyck * PSK itself. 7027b0563631STom Van Eyck * For details please check: 7028b0563631STom Van Eyck * - RFC 4279, Section 4 for the definition of RSA-PSK, 7029b0563631STom Van Eyck * - RFC 4279, Section 3 for the definition of DHE-PSK, 7030b0563631STom Van Eyck * - RFC 5489 for the definition of ECDHE-PSK. 7031b0563631STom Van Eyck */ 7032b0563631STom Van Eyck 7033b0563631STom Van Eyck if (prf->state == PSA_TLS12_PRF_STATE_OTHER_KEY_SET) { 7034b0563631STom Van Eyck *cur++ = MBEDTLS_BYTE_1(prf->other_secret_length); 7035b0563631STom Van Eyck *cur++ = MBEDTLS_BYTE_0(prf->other_secret_length); 7036b0563631STom Van Eyck if (prf->other_secret_length != 0) { 7037b0563631STom Van Eyck memcpy(cur, prf->other_secret, prf->other_secret_length); 7038b0563631STom Van Eyck mbedtls_platform_zeroize(prf->other_secret, prf->other_secret_length); 7039b0563631STom Van Eyck cur += prf->other_secret_length; 7040b0563631STom Van Eyck } 7041b0563631STom Van Eyck } else { 7042b0563631STom Van Eyck *cur++ = MBEDTLS_BYTE_1(data_length); 7043b0563631STom Van Eyck *cur++ = MBEDTLS_BYTE_0(data_length); 7044b0563631STom Van Eyck memset(cur, 0, data_length); 7045b0563631STom Van Eyck cur += data_length; 7046b0563631STom Van Eyck } 7047b0563631STom Van Eyck 7048b0563631STom Van Eyck *cur++ = MBEDTLS_BYTE_1(data_length); 7049b0563631STom Van Eyck *cur++ = MBEDTLS_BYTE_0(data_length); 7050b0563631STom Van Eyck memcpy(cur, data, data_length); 7051b0563631STom Van Eyck cur += data_length; 7052b0563631STom Van Eyck 7053b0563631STom Van Eyck status = psa_tls12_prf_set_key(prf, pms, (size_t) (cur - pms)); 7054b0563631STom Van Eyck 7055b0563631STom Van Eyck mbedtls_zeroize_and_free(pms, pms_len); 7056b0563631STom Van Eyck return status; 7057b0563631STom Van Eyck } 7058b0563631STom Van Eyck 7059b0563631STom Van Eyck static psa_status_t psa_tls12_prf_psk_to_ms_set_other_key( 7060b0563631STom Van Eyck psa_tls12_prf_key_derivation_t *prf, 7061b0563631STom Van Eyck const uint8_t *data, 7062b0563631STom Van Eyck size_t data_length) 7063b0563631STom Van Eyck { 7064b0563631STom Van Eyck if (prf->state != PSA_TLS12_PRF_STATE_SEED_SET) { 7065b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 7066b0563631STom Van Eyck } 7067b0563631STom Van Eyck 7068b0563631STom Van Eyck if (data_length != 0) { 7069b0563631STom Van Eyck prf->other_secret = mbedtls_calloc(1, data_length); 7070b0563631STom Van Eyck if (prf->other_secret == NULL) { 7071b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 7072b0563631STom Van Eyck } 7073b0563631STom Van Eyck 7074b0563631STom Van Eyck memcpy(prf->other_secret, data, data_length); 7075b0563631STom Van Eyck prf->other_secret_length = data_length; 7076b0563631STom Van Eyck } else { 7077b0563631STom Van Eyck prf->other_secret_length = 0; 7078b0563631STom Van Eyck } 7079b0563631STom Van Eyck 7080b0563631STom Van Eyck prf->state = PSA_TLS12_PRF_STATE_OTHER_KEY_SET; 7081b0563631STom Van Eyck 7082b0563631STom Van Eyck return PSA_SUCCESS; 7083b0563631STom Van Eyck } 7084b0563631STom Van Eyck 7085b0563631STom Van Eyck static psa_status_t psa_tls12_prf_psk_to_ms_input( 7086b0563631STom Van Eyck psa_tls12_prf_key_derivation_t *prf, 7087b0563631STom Van Eyck psa_key_derivation_step_t step, 7088b0563631STom Van Eyck const uint8_t *data, 7089b0563631STom Van Eyck size_t data_length) 7090b0563631STom Van Eyck { 7091b0563631STom Van Eyck switch (step) { 7092b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_SECRET: 7093b0563631STom Van Eyck return psa_tls12_prf_psk_to_ms_set_key(prf, 7094b0563631STom Van Eyck data, data_length); 7095b0563631STom Van Eyck break; 7096b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_OTHER_SECRET: 7097b0563631STom Van Eyck return psa_tls12_prf_psk_to_ms_set_other_key(prf, 7098b0563631STom Van Eyck data, 7099b0563631STom Van Eyck data_length); 7100b0563631STom Van Eyck break; 7101b0563631STom Van Eyck default: 7102b0563631STom Van Eyck return psa_tls12_prf_input(prf, step, data, data_length); 7103b0563631STom Van Eyck break; 7104b0563631STom Van Eyck 7105b0563631STom Van Eyck } 7106b0563631STom Van Eyck } 7107b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ 7108b0563631STom Van Eyck 7109b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) 7110b0563631STom Van Eyck static psa_status_t psa_tls12_ecjpake_to_pms_input( 7111b0563631STom Van Eyck psa_tls12_ecjpake_to_pms_t *ecjpake, 7112b0563631STom Van Eyck psa_key_derivation_step_t step, 7113b0563631STom Van Eyck const uint8_t *data, 7114b0563631STom Van Eyck size_t data_length) 7115b0563631STom Van Eyck { 7116b0563631STom Van Eyck if (data_length != PSA_TLS12_ECJPAKE_TO_PMS_INPUT_SIZE || 7117b0563631STom Van Eyck step != PSA_KEY_DERIVATION_INPUT_SECRET) { 7118b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7119b0563631STom Van Eyck } 7120b0563631STom Van Eyck 7121b0563631STom Van Eyck /* Check if the passed point is in an uncompressed form */ 7122b0563631STom Van Eyck if (data[0] != 0x04) { 7123b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7124b0563631STom Van Eyck } 7125b0563631STom Van Eyck 7126b0563631STom Van Eyck /* Only K.X has to be extracted - bytes 1 to 32 inclusive. */ 7127b0563631STom Van Eyck memcpy(ecjpake->data, data + 1, PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE); 7128b0563631STom Van Eyck 7129b0563631STom Van Eyck return PSA_SUCCESS; 7130b0563631STom Van Eyck } 7131b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */ 7132b0563631STom Van Eyck 7133b0563631STom Van Eyck #if defined(PSA_HAVE_SOFT_PBKDF2) 7134b0563631STom Van Eyck static psa_status_t psa_pbkdf2_set_input_cost( 7135b0563631STom Van Eyck psa_pbkdf2_key_derivation_t *pbkdf2, 7136b0563631STom Van Eyck psa_key_derivation_step_t step, 7137b0563631STom Van Eyck uint64_t data) 7138b0563631STom Van Eyck { 7139b0563631STom Van Eyck if (step != PSA_KEY_DERIVATION_INPUT_COST) { 7140b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7141b0563631STom Van Eyck } 7142b0563631STom Van Eyck 7143b0563631STom Van Eyck if (pbkdf2->state != PSA_PBKDF2_STATE_INIT) { 7144b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 7145b0563631STom Van Eyck } 7146b0563631STom Van Eyck 7147b0563631STom Van Eyck if (data > PSA_VENDOR_PBKDF2_MAX_ITERATIONS) { 7148b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 7149b0563631STom Van Eyck } 7150b0563631STom Van Eyck 7151b0563631STom Van Eyck if (data == 0) { 7152b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7153b0563631STom Van Eyck } 7154b0563631STom Van Eyck 7155b0563631STom Van Eyck pbkdf2->input_cost = data; 7156b0563631STom Van Eyck pbkdf2->state = PSA_PBKDF2_STATE_INPUT_COST_SET; 7157b0563631STom Van Eyck 7158b0563631STom Van Eyck return PSA_SUCCESS; 7159b0563631STom Van Eyck } 7160b0563631STom Van Eyck 7161b0563631STom Van Eyck static psa_status_t psa_pbkdf2_set_salt(psa_pbkdf2_key_derivation_t *pbkdf2, 7162b0563631STom Van Eyck const uint8_t *data, 7163b0563631STom Van Eyck size_t data_length) 7164b0563631STom Van Eyck { 7165b0563631STom Van Eyck if (pbkdf2->state == PSA_PBKDF2_STATE_INPUT_COST_SET) { 7166b0563631STom Van Eyck pbkdf2->state = PSA_PBKDF2_STATE_SALT_SET; 7167b0563631STom Van Eyck } else if (pbkdf2->state == PSA_PBKDF2_STATE_SALT_SET) { 7168b0563631STom Van Eyck /* Appending to existing salt. No state change. */ 7169b0563631STom Van Eyck } else { 7170b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 7171b0563631STom Van Eyck } 7172b0563631STom Van Eyck 7173b0563631STom Van Eyck if (data_length == 0) { 7174b0563631STom Van Eyck /* Appending an empty string, nothing to do. */ 7175b0563631STom Van Eyck } else { 7176b0563631STom Van Eyck uint8_t *next_salt; 7177b0563631STom Van Eyck 7178b0563631STom Van Eyck next_salt = mbedtls_calloc(1, data_length + pbkdf2->salt_length); 7179b0563631STom Van Eyck if (next_salt == NULL) { 7180b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 7181b0563631STom Van Eyck } 7182b0563631STom Van Eyck 7183b0563631STom Van Eyck if (pbkdf2->salt_length != 0) { 7184b0563631STom Van Eyck memcpy(next_salt, pbkdf2->salt, pbkdf2->salt_length); 7185b0563631STom Van Eyck } 7186b0563631STom Van Eyck memcpy(next_salt + pbkdf2->salt_length, data, data_length); 7187b0563631STom Van Eyck pbkdf2->salt_length += data_length; 7188b0563631STom Van Eyck mbedtls_free(pbkdf2->salt); 7189b0563631STom Van Eyck pbkdf2->salt = next_salt; 7190b0563631STom Van Eyck } 7191b0563631STom Van Eyck return PSA_SUCCESS; 7192b0563631STom Van Eyck } 7193b0563631STom Van Eyck 7194b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC) 7195b0563631STom Van Eyck static psa_status_t psa_pbkdf2_hmac_set_password(psa_algorithm_t hash_alg, 7196b0563631STom Van Eyck const uint8_t *input, 7197b0563631STom Van Eyck size_t input_len, 7198b0563631STom Van Eyck uint8_t *output, 7199b0563631STom Van Eyck size_t *output_len) 7200b0563631STom Van Eyck { 7201b0563631STom Van Eyck psa_status_t status = PSA_SUCCESS; 7202b0563631STom Van Eyck if (input_len > PSA_HASH_BLOCK_LENGTH(hash_alg)) { 7203b0563631STom Van Eyck return psa_hash_compute(hash_alg, input, input_len, output, 7204b0563631STom Van Eyck PSA_HMAC_MAX_HASH_BLOCK_SIZE, output_len); 7205b0563631STom Van Eyck } else if (input_len > 0) { 7206b0563631STom Van Eyck memcpy(output, input, input_len); 7207b0563631STom Van Eyck } 7208b0563631STom Van Eyck *output_len = PSA_HASH_BLOCK_LENGTH(hash_alg); 7209b0563631STom Van Eyck return status; 7210b0563631STom Van Eyck } 7211b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */ 7212b0563631STom Van Eyck 7213b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128) 7214b0563631STom Van Eyck static psa_status_t psa_pbkdf2_cmac_set_password(const uint8_t *input, 7215b0563631STom Van Eyck size_t input_len, 7216b0563631STom Van Eyck uint8_t *output, 7217b0563631STom Van Eyck size_t *output_len) 7218b0563631STom Van Eyck { 7219b0563631STom Van Eyck psa_status_t status = PSA_SUCCESS; 7220b0563631STom Van Eyck if (input_len != PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC)) { 7221b0563631STom Van Eyck psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 7222b0563631STom Van Eyck uint8_t zeros[16] = { 0 }; 7223b0563631STom Van Eyck psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); 7224b0563631STom Van Eyck psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(sizeof(zeros))); 7225b0563631STom Van Eyck psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); 7226b0563631STom Van Eyck /* Passing PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC) as 7227b0563631STom Van Eyck * mac_size as the driver function sets mac_output_length = mac_size 7228b0563631STom Van Eyck * on success. See https://github.com/Mbed-TLS/mbedtls/issues/7801 */ 7229b0563631STom Van Eyck status = psa_driver_wrapper_mac_compute(&attributes, 7230b0563631STom Van Eyck zeros, sizeof(zeros), 7231b0563631STom Van Eyck PSA_ALG_CMAC, input, input_len, 7232b0563631STom Van Eyck output, 7233b0563631STom Van Eyck PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 7234b0563631STom Van Eyck 128U, 7235b0563631STom Van Eyck PSA_ALG_CMAC), 7236b0563631STom Van Eyck output_len); 7237b0563631STom Van Eyck } else { 7238b0563631STom Van Eyck memcpy(output, input, input_len); 7239b0563631STom Van Eyck *output_len = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC); 7240b0563631STom Van Eyck } 7241b0563631STom Van Eyck return status; 7242b0563631STom Van Eyck } 7243b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 */ 7244b0563631STom Van Eyck 7245b0563631STom Van Eyck static psa_status_t psa_pbkdf2_set_password(psa_pbkdf2_key_derivation_t *pbkdf2, 7246b0563631STom Van Eyck psa_algorithm_t kdf_alg, 7247b0563631STom Van Eyck const uint8_t *data, 7248b0563631STom Van Eyck size_t data_length) 7249b0563631STom Van Eyck { 7250b0563631STom Van Eyck psa_status_t status = PSA_SUCCESS; 7251b0563631STom Van Eyck if (pbkdf2->state != PSA_PBKDF2_STATE_SALT_SET) { 7252b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 7253b0563631STom Van Eyck } 7254b0563631STom Van Eyck 7255b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC) 7256b0563631STom Van Eyck if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) { 7257b0563631STom Van Eyck psa_algorithm_t hash_alg = PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg); 7258b0563631STom Van Eyck status = psa_pbkdf2_hmac_set_password(hash_alg, data, data_length, 7259b0563631STom Van Eyck pbkdf2->password, 7260b0563631STom Van Eyck &pbkdf2->password_length); 7261b0563631STom Van Eyck } else 7262b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */ 7263b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128) 7264b0563631STom Van Eyck if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) { 7265b0563631STom Van Eyck status = psa_pbkdf2_cmac_set_password(data, data_length, 7266b0563631STom Van Eyck pbkdf2->password, 7267b0563631STom Van Eyck &pbkdf2->password_length); 7268b0563631STom Van Eyck } else 7269b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 */ 7270b0563631STom Van Eyck { 7271b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7272b0563631STom Van Eyck } 7273b0563631STom Van Eyck 7274b0563631STom Van Eyck pbkdf2->state = PSA_PBKDF2_STATE_PASSWORD_SET; 7275b0563631STom Van Eyck 7276b0563631STom Van Eyck return status; 7277b0563631STom Van Eyck } 7278b0563631STom Van Eyck 7279b0563631STom Van Eyck static psa_status_t psa_pbkdf2_input(psa_pbkdf2_key_derivation_t *pbkdf2, 7280b0563631STom Van Eyck psa_algorithm_t kdf_alg, 7281b0563631STom Van Eyck psa_key_derivation_step_t step, 7282b0563631STom Van Eyck const uint8_t *data, 7283b0563631STom Van Eyck size_t data_length) 7284b0563631STom Van Eyck { 7285b0563631STom Van Eyck switch (step) { 7286b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_SALT: 7287b0563631STom Van Eyck return psa_pbkdf2_set_salt(pbkdf2, data, data_length); 7288b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_PASSWORD: 7289b0563631STom Van Eyck return psa_pbkdf2_set_password(pbkdf2, kdf_alg, data, data_length); 7290b0563631STom Van Eyck default: 7291b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7292b0563631STom Van Eyck } 7293b0563631STom Van Eyck } 7294b0563631STom Van Eyck #endif /* PSA_HAVE_SOFT_PBKDF2 */ 7295b0563631STom Van Eyck 7296b0563631STom Van Eyck /** Check whether the given key type is acceptable for the given 7297b0563631STom Van Eyck * input step of a key derivation. 7298b0563631STom Van Eyck * 7299b0563631STom Van Eyck * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE. 7300b0563631STom Van Eyck * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA. 7301b0563631STom Van Eyck * Both secret and non-secret inputs can alternatively have the type 7302b0563631STom Van Eyck * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning 7303b0563631STom Van Eyck * that the input was passed as a buffer rather than via a key object. 7304b0563631STom Van Eyck */ 7305b0563631STom Van Eyck static int psa_key_derivation_check_input_type( 7306b0563631STom Van Eyck psa_key_derivation_step_t step, 7307b0563631STom Van Eyck psa_key_type_t key_type) 7308b0563631STom Van Eyck { 7309b0563631STom Van Eyck switch (step) { 7310b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_SECRET: 7311b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_DERIVE) { 7312b0563631STom Van Eyck return PSA_SUCCESS; 7313b0563631STom Van Eyck } 7314b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_NONE) { 7315b0563631STom Van Eyck return PSA_SUCCESS; 7316b0563631STom Van Eyck } 7317b0563631STom Van Eyck break; 7318b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_OTHER_SECRET: 7319b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_DERIVE) { 7320b0563631STom Van Eyck return PSA_SUCCESS; 7321b0563631STom Van Eyck } 7322b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_NONE) { 7323b0563631STom Van Eyck return PSA_SUCCESS; 7324b0563631STom Van Eyck } 7325b0563631STom Van Eyck break; 7326b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_LABEL: 7327b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_SALT: 7328b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_INFO: 7329b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_SEED: 7330b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_RAW_DATA) { 7331b0563631STom Van Eyck return PSA_SUCCESS; 7332b0563631STom Van Eyck } 7333b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_NONE) { 7334b0563631STom Van Eyck return PSA_SUCCESS; 7335b0563631STom Van Eyck } 7336b0563631STom Van Eyck break; 7337b0563631STom Van Eyck case PSA_KEY_DERIVATION_INPUT_PASSWORD: 7338b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_PASSWORD) { 7339b0563631STom Van Eyck return PSA_SUCCESS; 7340b0563631STom Van Eyck } 7341b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_DERIVE) { 7342b0563631STom Van Eyck return PSA_SUCCESS; 7343b0563631STom Van Eyck } 7344b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_NONE) { 7345b0563631STom Van Eyck return PSA_SUCCESS; 7346b0563631STom Van Eyck } 7347b0563631STom Van Eyck break; 7348b0563631STom Van Eyck } 7349b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7350b0563631STom Van Eyck } 7351b0563631STom Van Eyck 7352b0563631STom Van Eyck static psa_status_t psa_key_derivation_input_internal( 7353b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 7354b0563631STom Van Eyck psa_key_derivation_step_t step, 7355b0563631STom Van Eyck psa_key_type_t key_type, 7356b0563631STom Van Eyck const uint8_t *data, 7357b0563631STom Van Eyck size_t data_length) 7358b0563631STom Van Eyck { 7359b0563631STom Van Eyck psa_status_t status; 7360b0563631STom Van Eyck psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation); 7361b0563631STom Van Eyck 7362b0563631STom Van Eyck status = psa_key_derivation_check_input_type(step, key_type); 7363b0563631STom Van Eyck if (status != PSA_SUCCESS) { 7364b0563631STom Van Eyck goto exit; 7365b0563631STom Van Eyck } 7366b0563631STom Van Eyck 7367b0563631STom Van Eyck #if defined(BUILTIN_ALG_ANY_HKDF) 7368b0563631STom Van Eyck if (PSA_ALG_IS_ANY_HKDF(kdf_alg)) { 7369b0563631STom Van Eyck status = psa_hkdf_input(&operation->ctx.hkdf, kdf_alg, 7370b0563631STom Van Eyck step, data, data_length); 7371b0563631STom Van Eyck } else 7372b0563631STom Van Eyck #endif /* BUILTIN_ALG_ANY_HKDF */ 7373b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) 7374b0563631STom Van Eyck if (PSA_ALG_IS_TLS12_PRF(kdf_alg)) { 7375b0563631STom Van Eyck status = psa_tls12_prf_input(&operation->ctx.tls12_prf, 7376b0563631STom Van Eyck step, data, data_length); 7377b0563631STom Van Eyck } else 7378b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF */ 7379b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) 7380b0563631STom Van Eyck if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) { 7381b0563631STom Van Eyck status = psa_tls12_prf_psk_to_ms_input(&operation->ctx.tls12_prf, 7382b0563631STom Van Eyck step, data, data_length); 7383b0563631STom Van Eyck } else 7384b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ 7385b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) 7386b0563631STom Van Eyck if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { 7387b0563631STom Van Eyck status = psa_tls12_ecjpake_to_pms_input( 7388b0563631STom Van Eyck &operation->ctx.tls12_ecjpake_to_pms, step, data, data_length); 7389b0563631STom Van Eyck } else 7390b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */ 7391b0563631STom Van Eyck #if defined(PSA_HAVE_SOFT_PBKDF2) 7392b0563631STom Van Eyck if (PSA_ALG_IS_PBKDF2(kdf_alg)) { 7393b0563631STom Van Eyck status = psa_pbkdf2_input(&operation->ctx.pbkdf2, kdf_alg, 7394b0563631STom Van Eyck step, data, data_length); 7395b0563631STom Van Eyck } else 7396b0563631STom Van Eyck #endif /* PSA_HAVE_SOFT_PBKDF2 */ 7397b0563631STom Van Eyck { 7398b0563631STom Van Eyck /* This can't happen unless the operation object was not initialized */ 7399b0563631STom Van Eyck (void) data; 7400b0563631STom Van Eyck (void) data_length; 7401b0563631STom Van Eyck (void) kdf_alg; 7402b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 7403b0563631STom Van Eyck } 7404b0563631STom Van Eyck 7405b0563631STom Van Eyck exit: 7406b0563631STom Van Eyck if (status != PSA_SUCCESS) { 7407b0563631STom Van Eyck psa_key_derivation_abort(operation); 7408b0563631STom Van Eyck } 7409b0563631STom Van Eyck return status; 7410b0563631STom Van Eyck } 7411b0563631STom Van Eyck 7412b0563631STom Van Eyck static psa_status_t psa_key_derivation_input_integer_internal( 7413b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 7414b0563631STom Van Eyck psa_key_derivation_step_t step, 7415b0563631STom Van Eyck uint64_t value) 7416b0563631STom Van Eyck { 7417b0563631STom Van Eyck psa_status_t status; 7418b0563631STom Van Eyck psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation); 7419b0563631STom Van Eyck 7420b0563631STom Van Eyck #if defined(PSA_HAVE_SOFT_PBKDF2) 7421b0563631STom Van Eyck if (PSA_ALG_IS_PBKDF2(kdf_alg)) { 7422b0563631STom Van Eyck status = psa_pbkdf2_set_input_cost( 7423b0563631STom Van Eyck &operation->ctx.pbkdf2, step, value); 7424b0563631STom Van Eyck } else 7425b0563631STom Van Eyck #endif /* PSA_HAVE_SOFT_PBKDF2 */ 7426b0563631STom Van Eyck { 7427b0563631STom Van Eyck (void) step; 7428b0563631STom Van Eyck (void) value; 7429b0563631STom Van Eyck (void) kdf_alg; 7430b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 7431b0563631STom Van Eyck } 7432b0563631STom Van Eyck 7433b0563631STom Van Eyck if (status != PSA_SUCCESS) { 7434b0563631STom Van Eyck psa_key_derivation_abort(operation); 7435b0563631STom Van Eyck } 7436b0563631STom Van Eyck return status; 7437b0563631STom Van Eyck } 7438b0563631STom Van Eyck 7439b0563631STom Van Eyck psa_status_t psa_key_derivation_input_bytes( 7440b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 7441b0563631STom Van Eyck psa_key_derivation_step_t step, 7442b0563631STom Van Eyck const uint8_t *data_external, 7443b0563631STom Van Eyck size_t data_length) 7444b0563631STom Van Eyck { 7445b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 7446b0563631STom Van Eyck LOCAL_INPUT_DECLARE(data_external, data); 7447b0563631STom Van Eyck 7448b0563631STom Van Eyck LOCAL_INPUT_ALLOC(data_external, data_length, data); 7449b0563631STom Van Eyck 7450b0563631STom Van Eyck status = psa_key_derivation_input_internal(operation, step, 7451b0563631STom Van Eyck PSA_KEY_TYPE_NONE, 7452b0563631STom Van Eyck data, data_length); 7453b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 7454b0563631STom Van Eyck exit: 7455b0563631STom Van Eyck #endif 7456b0563631STom Van Eyck LOCAL_INPUT_FREE(data_external, data); 7457b0563631STom Van Eyck return status; 7458b0563631STom Van Eyck } 7459b0563631STom Van Eyck 7460b0563631STom Van Eyck psa_status_t psa_key_derivation_input_integer( 7461b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 7462b0563631STom Van Eyck psa_key_derivation_step_t step, 7463b0563631STom Van Eyck uint64_t value) 7464b0563631STom Van Eyck { 7465b0563631STom Van Eyck return psa_key_derivation_input_integer_internal(operation, step, value); 7466b0563631STom Van Eyck } 7467b0563631STom Van Eyck 7468b0563631STom Van Eyck psa_status_t psa_key_derivation_input_key( 7469b0563631STom Van Eyck psa_key_derivation_operation_t *operation, 7470b0563631STom Van Eyck psa_key_derivation_step_t step, 7471b0563631STom Van Eyck mbedtls_svc_key_id_t key) 7472b0563631STom Van Eyck { 7473b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 7474b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 7475b0563631STom Van Eyck psa_key_slot_t *slot; 7476b0563631STom Van Eyck 7477b0563631STom Van Eyck status = psa_get_and_lock_transparent_key_slot_with_policy( 7478b0563631STom Van Eyck key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg); 7479b0563631STom Van Eyck if (status != PSA_SUCCESS) { 7480b0563631STom Van Eyck psa_key_derivation_abort(operation); 7481b0563631STom Van Eyck return status; 7482b0563631STom Van Eyck } 7483b0563631STom Van Eyck 7484b0563631STom Van Eyck /* Passing a key object as a SECRET or PASSWORD input unlocks the 7485b0563631STom Van Eyck * permission to output to a key object. */ 7486b0563631STom Van Eyck if (step == PSA_KEY_DERIVATION_INPUT_SECRET || 7487b0563631STom Van Eyck step == PSA_KEY_DERIVATION_INPUT_PASSWORD) { 7488b0563631STom Van Eyck operation->can_output_key = 1; 7489b0563631STom Van Eyck } 7490b0563631STom Van Eyck 7491b0563631STom Van Eyck status = psa_key_derivation_input_internal(operation, 7492b0563631STom Van Eyck step, slot->attr.type, 7493b0563631STom Van Eyck slot->key.data, 7494b0563631STom Van Eyck slot->key.bytes); 7495b0563631STom Van Eyck 7496b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 7497b0563631STom Van Eyck 7498b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 7499b0563631STom Van Eyck } 7500b0563631STom Van Eyck 7501b0563631STom Van Eyck 7502b0563631STom Van Eyck 7503b0563631STom Van Eyck /****************************************************************/ 7504b0563631STom Van Eyck /* Key agreement */ 7505b0563631STom Van Eyck /****************************************************************/ 7506b0563631STom Van Eyck 7507b0563631STom Van Eyck psa_status_t psa_key_agreement_raw_builtin(const psa_key_attributes_t *attributes, 7508b0563631STom Van Eyck const uint8_t *key_buffer, 7509b0563631STom Van Eyck size_t key_buffer_size, 7510b0563631STom Van Eyck psa_algorithm_t alg, 7511b0563631STom Van Eyck const uint8_t *peer_key, 7512b0563631STom Van Eyck size_t peer_key_length, 7513b0563631STom Van Eyck uint8_t *shared_secret, 7514b0563631STom Van Eyck size_t shared_secret_size, 7515b0563631STom Van Eyck size_t *shared_secret_length) 7516b0563631STom Van Eyck { 7517b0563631STom Van Eyck switch (alg) { 7518b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) 7519b0563631STom Van Eyck case PSA_ALG_ECDH: 7520b0563631STom Van Eyck return mbedtls_psa_key_agreement_ecdh(attributes, key_buffer, 7521b0563631STom Van Eyck key_buffer_size, alg, 7522b0563631STom Van Eyck peer_key, peer_key_length, 7523b0563631STom Van Eyck shared_secret, 7524b0563631STom Van Eyck shared_secret_size, 7525b0563631STom Van Eyck shared_secret_length); 7526b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */ 7527b0563631STom Van Eyck 7528b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH) 7529b0563631STom Van Eyck case PSA_ALG_FFDH: 7530b0563631STom Van Eyck return mbedtls_psa_ffdh_key_agreement(attributes, 7531b0563631STom Van Eyck peer_key, 7532b0563631STom Van Eyck peer_key_length, 7533b0563631STom Van Eyck key_buffer, 7534b0563631STom Van Eyck key_buffer_size, 7535b0563631STom Van Eyck shared_secret, 7536b0563631STom Van Eyck shared_secret_size, 7537b0563631STom Van Eyck shared_secret_length); 7538b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */ 7539b0563631STom Van Eyck 7540b0563631STom Van Eyck default: 7541b0563631STom Van Eyck (void) attributes; 7542b0563631STom Van Eyck (void) key_buffer; 7543b0563631STom Van Eyck (void) key_buffer_size; 7544b0563631STom Van Eyck (void) peer_key; 7545b0563631STom Van Eyck (void) peer_key_length; 7546b0563631STom Van Eyck (void) shared_secret; 7547b0563631STom Van Eyck (void) shared_secret_size; 7548b0563631STom Van Eyck (void) shared_secret_length; 7549b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 7550b0563631STom Van Eyck } 7551b0563631STom Van Eyck } 7552b0563631STom Van Eyck 7553b0563631STom Van Eyck /** Internal function for raw key agreement 7554b0563631STom Van Eyck * Calls the driver wrapper which will hand off key agreement task 7555b0563631STom Van Eyck * to the driver's implementation if a driver is present. 7556b0563631STom Van Eyck * Fallback specified in the driver wrapper is built-in raw key agreement 7557b0563631STom Van Eyck * (psa_key_agreement_raw_builtin). 7558b0563631STom Van Eyck */ 7559b0563631STom Van Eyck static psa_status_t psa_key_agreement_raw_internal(psa_algorithm_t alg, 7560b0563631STom Van Eyck psa_key_slot_t *private_key, 7561b0563631STom Van Eyck const uint8_t *peer_key, 7562b0563631STom Van Eyck size_t peer_key_length, 7563b0563631STom Van Eyck uint8_t *shared_secret, 7564b0563631STom Van Eyck size_t shared_secret_size, 7565b0563631STom Van Eyck size_t *shared_secret_length) 7566b0563631STom Van Eyck { 7567b0563631STom Van Eyck if (!PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) { 7568b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 7569b0563631STom Van Eyck } 7570b0563631STom Van Eyck 7571b0563631STom Van Eyck return psa_driver_wrapper_key_agreement(&private_key->attr, 7572b0563631STom Van Eyck private_key->key.data, 7573b0563631STom Van Eyck private_key->key.bytes, alg, 7574b0563631STom Van Eyck peer_key, peer_key_length, 7575b0563631STom Van Eyck shared_secret, 7576b0563631STom Van Eyck shared_secret_size, 7577b0563631STom Van Eyck shared_secret_length); 7578b0563631STom Van Eyck } 7579b0563631STom Van Eyck 7580b0563631STom Van Eyck /* Note that if this function fails, you must call psa_key_derivation_abort() 7581b0563631STom Van Eyck * to potentially free embedded data structures and wipe confidential data. 7582b0563631STom Van Eyck */ 7583b0563631STom Van Eyck static psa_status_t psa_key_agreement_internal(psa_key_derivation_operation_t *operation, 7584b0563631STom Van Eyck psa_key_derivation_step_t step, 7585b0563631STom Van Eyck psa_key_slot_t *private_key, 7586b0563631STom Van Eyck const uint8_t *peer_key, 7587b0563631STom Van Eyck size_t peer_key_length) 7588b0563631STom Van Eyck { 7589b0563631STom Van Eyck psa_status_t status; 7590b0563631STom Van Eyck uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE] = { 0 }; 7591b0563631STom Van Eyck size_t shared_secret_length = 0; 7592b0563631STom Van Eyck psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE(operation->alg); 7593b0563631STom Van Eyck 7594b0563631STom Van Eyck /* Step 1: run the secret agreement algorithm to generate the shared 7595b0563631STom Van Eyck * secret. */ 7596b0563631STom Van Eyck status = psa_key_agreement_raw_internal(ka_alg, 7597b0563631STom Van Eyck private_key, 7598b0563631STom Van Eyck peer_key, peer_key_length, 7599b0563631STom Van Eyck shared_secret, 7600b0563631STom Van Eyck sizeof(shared_secret), 7601b0563631STom Van Eyck &shared_secret_length); 7602b0563631STom Van Eyck if (status != PSA_SUCCESS) { 7603b0563631STom Van Eyck goto exit; 7604b0563631STom Van Eyck } 7605b0563631STom Van Eyck 7606b0563631STom Van Eyck /* Step 2: set up the key derivation to generate key material from 7607b0563631STom Van Eyck * the shared secret. A shared secret is permitted wherever a key 7608b0563631STom Van Eyck * of type DERIVE is permitted. */ 7609b0563631STom Van Eyck status = psa_key_derivation_input_internal(operation, step, 7610b0563631STom Van Eyck PSA_KEY_TYPE_DERIVE, 7611b0563631STom Van Eyck shared_secret, 7612b0563631STom Van Eyck shared_secret_length); 7613b0563631STom Van Eyck exit: 7614b0563631STom Van Eyck mbedtls_platform_zeroize(shared_secret, shared_secret_length); 7615b0563631STom Van Eyck return status; 7616b0563631STom Van Eyck } 7617b0563631STom Van Eyck 7618b0563631STom Van Eyck psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *operation, 7619b0563631STom Van Eyck psa_key_derivation_step_t step, 7620b0563631STom Van Eyck mbedtls_svc_key_id_t private_key, 7621b0563631STom Van Eyck const uint8_t *peer_key_external, 7622b0563631STom Van Eyck size_t peer_key_length) 7623b0563631STom Van Eyck { 7624b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 7625b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 7626b0563631STom Van Eyck psa_key_slot_t *slot; 7627b0563631STom Van Eyck LOCAL_INPUT_DECLARE(peer_key_external, peer_key); 7628b0563631STom Van Eyck 7629b0563631STom Van Eyck if (!PSA_ALG_IS_KEY_AGREEMENT(operation->alg)) { 7630b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7631b0563631STom Van Eyck } 7632b0563631STom Van Eyck status = psa_get_and_lock_transparent_key_slot_with_policy( 7633b0563631STom Van Eyck private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg); 7634b0563631STom Van Eyck if (status != PSA_SUCCESS) { 7635b0563631STom Van Eyck return status; 7636b0563631STom Van Eyck } 7637b0563631STom Van Eyck 7638b0563631STom Van Eyck LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key); 7639b0563631STom Van Eyck status = psa_key_agreement_internal(operation, step, 7640b0563631STom Van Eyck slot, 7641b0563631STom Van Eyck peer_key, peer_key_length); 7642b0563631STom Van Eyck 7643b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 7644b0563631STom Van Eyck exit: 7645b0563631STom Van Eyck #endif 7646b0563631STom Van Eyck if (status != PSA_SUCCESS) { 7647b0563631STom Van Eyck psa_key_derivation_abort(operation); 7648b0563631STom Van Eyck } else { 7649b0563631STom Van Eyck /* If a private key has been added as SECRET, we allow the derived 7650b0563631STom Van Eyck * key material to be used as a key in PSA Crypto. */ 7651b0563631STom Van Eyck if (step == PSA_KEY_DERIVATION_INPUT_SECRET) { 7652b0563631STom Van Eyck operation->can_output_key = 1; 7653b0563631STom Van Eyck } 7654b0563631STom Van Eyck } 7655b0563631STom Van Eyck 7656b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 7657b0563631STom Van Eyck LOCAL_INPUT_FREE(peer_key_external, peer_key); 7658b0563631STom Van Eyck 7659b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 7660b0563631STom Van Eyck } 7661b0563631STom Van Eyck 7662b0563631STom Van Eyck psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, 7663b0563631STom Van Eyck mbedtls_svc_key_id_t private_key, 7664b0563631STom Van Eyck const uint8_t *peer_key_external, 7665b0563631STom Van Eyck size_t peer_key_length, 7666b0563631STom Van Eyck uint8_t *output_external, 7667b0563631STom Van Eyck size_t output_size, 7668b0563631STom Van Eyck size_t *output_length) 7669b0563631STom Van Eyck { 7670b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 7671b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 7672b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 7673b0563631STom Van Eyck size_t expected_length; 7674b0563631STom Van Eyck LOCAL_INPUT_DECLARE(peer_key_external, peer_key); 7675b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 7676b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_size, output); 7677b0563631STom Van Eyck 7678b0563631STom Van Eyck if (!PSA_ALG_IS_KEY_AGREEMENT(alg)) { 7679b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 7680b0563631STom Van Eyck goto exit; 7681b0563631STom Van Eyck } 7682b0563631STom Van Eyck status = psa_get_and_lock_transparent_key_slot_with_policy( 7683b0563631STom Van Eyck private_key, &slot, PSA_KEY_USAGE_DERIVE, alg); 7684b0563631STom Van Eyck if (status != PSA_SUCCESS) { 7685b0563631STom Van Eyck goto exit; 7686b0563631STom Van Eyck } 7687b0563631STom Van Eyck 7688b0563631STom Van Eyck /* PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is in general an upper bound 7689b0563631STom Van Eyck * for the output size. The PSA specification only guarantees that this 7690b0563631STom Van Eyck * function works if output_size >= PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(...), 7691b0563631STom Van Eyck * but it might be nice to allow smaller buffers if the output fits. 7692b0563631STom Van Eyck * At the time of writing this comment, with only ECDH implemented, 7693b0563631STom Van Eyck * PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is exact so the point is moot. 7694b0563631STom Van Eyck * If FFDH is implemented, PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() can easily 7695b0563631STom Van Eyck * be exact for it as well. */ 7696b0563631STom Van Eyck expected_length = 7697b0563631STom Van Eyck PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(slot->attr.type, slot->attr.bits); 7698b0563631STom Van Eyck if (output_size < expected_length) { 7699b0563631STom Van Eyck status = PSA_ERROR_BUFFER_TOO_SMALL; 7700b0563631STom Van Eyck goto exit; 7701b0563631STom Van Eyck } 7702b0563631STom Van Eyck 7703b0563631STom Van Eyck LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key); 7704b0563631STom Van Eyck status = psa_key_agreement_raw_internal(alg, slot, 7705b0563631STom Van Eyck peer_key, peer_key_length, 7706b0563631STom Van Eyck output, output_size, 7707b0563631STom Van Eyck output_length); 7708b0563631STom Van Eyck 7709b0563631STom Van Eyck exit: 7710b0563631STom Van Eyck /* Check for successful allocation of output, 7711b0563631STom Van Eyck * with an unsuccessful status. */ 7712b0563631STom Van Eyck if (output != NULL && status != PSA_SUCCESS) { 7713b0563631STom Van Eyck /* If an error happens and is not handled properly, the output 7714b0563631STom Van Eyck * may be used as a key to protect sensitive data. Arrange for such 7715b0563631STom Van Eyck * a key to be random, which is likely to result in decryption or 7716b0563631STom Van Eyck * verification errors. This is better than filling the buffer with 7717b0563631STom Van Eyck * some constant data such as zeros, which would result in the data 7718b0563631STom Van Eyck * being protected with a reproducible, easily knowable key. 7719b0563631STom Van Eyck */ 7720b0563631STom Van Eyck psa_generate_random_internal(output, output_size); 7721b0563631STom Van Eyck *output_length = output_size; 7722b0563631STom Van Eyck } 7723b0563631STom Van Eyck 7724b0563631STom Van Eyck if (output == NULL) { 7725b0563631STom Van Eyck /* output allocation failed. */ 7726b0563631STom Van Eyck *output_length = 0; 7727b0563631STom Van Eyck } 7728b0563631STom Van Eyck 7729b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 7730b0563631STom Van Eyck 7731b0563631STom Van Eyck LOCAL_INPUT_FREE(peer_key_external, peer_key); 7732b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 7733b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 7734b0563631STom Van Eyck } 7735b0563631STom Van Eyck 7736b0563631STom Van Eyck 7737b0563631STom Van Eyck /****************************************************************/ 7738b0563631STom Van Eyck /* Random generation */ 7739b0563631STom Van Eyck /****************************************************************/ 7740b0563631STom Van Eyck 7741b0563631STom Van Eyck #if defined(MBEDTLS_PSA_INJECT_ENTROPY) 7742b0563631STom Van Eyck #include "entropy_poll.h" 7743b0563631STom Van Eyck #endif 7744b0563631STom Van Eyck 7745b0563631STom Van Eyck /** Initialize the PSA random generator. 7746b0563631STom Van Eyck * 7747b0563631STom Van Eyck * Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling 7748b0563631STom Van Eyck * this function if mutexes are enabled. 7749b0563631STom Van Eyck */ 7750b0563631STom Van Eyck static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng) 7751b0563631STom Van Eyck { 7752b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) 7753b0563631STom Van Eyck memset(rng, 0, sizeof(*rng)); 7754b0563631STom Van Eyck #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 7755b0563631STom Van Eyck 7756b0563631STom Van Eyck /* Set default configuration if 7757b0563631STom Van Eyck * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */ 7758b0563631STom Van Eyck if (rng->entropy_init == NULL) { 7759b0563631STom Van Eyck rng->entropy_init = mbedtls_entropy_init; 7760b0563631STom Van Eyck } 7761b0563631STom Van Eyck if (rng->entropy_free == NULL) { 7762b0563631STom Van Eyck rng->entropy_free = mbedtls_entropy_free; 7763b0563631STom Van Eyck } 7764b0563631STom Van Eyck 7765b0563631STom Van Eyck rng->entropy_init(&rng->entropy); 7766b0563631STom Van Eyck #if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ 7767b0563631STom Van Eyck defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) 7768b0563631STom Van Eyck /* The PSA entropy injection feature depends on using NV seed as an entropy 7769b0563631STom Van Eyck * source. Add NV seed as an entropy source for PSA entropy injection. */ 7770b0563631STom Van Eyck mbedtls_entropy_add_source(&rng->entropy, 7771b0563631STom Van Eyck mbedtls_nv_seed_poll, NULL, 7772b0563631STom Van Eyck MBEDTLS_ENTROPY_BLOCK_SIZE, 7773b0563631STom Van Eyck MBEDTLS_ENTROPY_SOURCE_STRONG); 7774b0563631STom Van Eyck #endif 7775b0563631STom Van Eyck 7776b0563631STom Van Eyck mbedtls_psa_drbg_init(&rng->drbg); 7777b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 7778b0563631STom Van Eyck } 7779b0563631STom Van Eyck 7780b0563631STom Van Eyck /** Deinitialize the PSA random generator. 7781b0563631STom Van Eyck * 7782b0563631STom Van Eyck * Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling 7783b0563631STom Van Eyck * this function if mutexes are enabled. 7784b0563631STom Van Eyck */ 7785b0563631STom Van Eyck static void mbedtls_psa_random_free(mbedtls_psa_random_context_t *rng) 7786b0563631STom Van Eyck { 7787b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) 7788b0563631STom Van Eyck memset(rng, 0, sizeof(*rng)); 7789b0563631STom Van Eyck #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 7790b0563631STom Van Eyck mbedtls_psa_drbg_free(&rng->drbg); 7791b0563631STom Van Eyck rng->entropy_free(&rng->entropy); 7792b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 7793b0563631STom Van Eyck } 7794b0563631STom Van Eyck 7795b0563631STom Van Eyck /** Seed the PSA random generator. 7796b0563631STom Van Eyck */ 7797b0563631STom Van Eyck static psa_status_t mbedtls_psa_random_seed(mbedtls_psa_random_context_t *rng) 7798b0563631STom Van Eyck { 7799b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) 7800b0563631STom Van Eyck /* Do nothing: the external RNG seeds itself. */ 7801b0563631STom Van Eyck (void) rng; 7802b0563631STom Van Eyck return PSA_SUCCESS; 7803b0563631STom Van Eyck #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 7804b0563631STom Van Eyck const unsigned char drbg_seed[] = "PSA"; 7805b0563631STom Van Eyck int ret = mbedtls_psa_drbg_seed(&rng->drbg, &rng->entropy, 7806b0563631STom Van Eyck drbg_seed, sizeof(drbg_seed) - 1); 7807b0563631STom Van Eyck return mbedtls_to_psa_error(ret); 7808b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 7809b0563631STom Van Eyck } 7810b0563631STom Van Eyck 7811b0563631STom Van Eyck psa_status_t psa_generate_random(uint8_t *output_external, 7812b0563631STom Van Eyck size_t output_size) 7813b0563631STom Van Eyck { 7814b0563631STom Van Eyck psa_status_t status; 7815b0563631STom Van Eyck 7816b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 7817b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_size, output); 7818b0563631STom Van Eyck 7819b0563631STom Van Eyck status = psa_generate_random_internal(output, output_size); 7820b0563631STom Van Eyck 7821b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) 7822b0563631STom Van Eyck exit: 7823b0563631STom Van Eyck #endif 7824b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 7825b0563631STom Van Eyck return status; 7826b0563631STom Van Eyck } 7827b0563631STom Van Eyck 7828b0563631STom Van Eyck #if defined(MBEDTLS_PSA_INJECT_ENTROPY) 7829b0563631STom Van Eyck psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, 7830b0563631STom Van Eyck size_t seed_size) 7831b0563631STom Van Eyck { 7832b0563631STom Van Eyck if (psa_get_initialized()) { 7833b0563631STom Van Eyck return PSA_ERROR_NOT_PERMITTED; 7834b0563631STom Van Eyck } 7835b0563631STom Van Eyck 7836b0563631STom Van Eyck if (((seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM) || 7837b0563631STom Van Eyck (seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE)) || 7838b0563631STom Van Eyck (seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE)) { 7839b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7840b0563631STom Van Eyck } 7841b0563631STom Van Eyck 7842b0563631STom Van Eyck return mbedtls_psa_storage_inject_entropy(seed, seed_size); 7843b0563631STom Van Eyck } 7844b0563631STom Van Eyck #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ 7845b0563631STom Van Eyck 7846b0563631STom Van Eyck /** Validate the key type and size for key generation 7847b0563631STom Van Eyck * 7848b0563631STom Van Eyck * \param type The key type 7849b0563631STom Van Eyck * \param bits The number of bits of the key 7850b0563631STom Van Eyck * 7851b0563631STom Van Eyck * \retval #PSA_SUCCESS 7852b0563631STom Van Eyck * The key type and size are valid. 7853b0563631STom Van Eyck * \retval #PSA_ERROR_INVALID_ARGUMENT 7854b0563631STom Van Eyck * The size in bits of the key is not valid. 7855b0563631STom Van Eyck * \retval #PSA_ERROR_NOT_SUPPORTED 7856b0563631STom Van Eyck * The type and/or the size in bits of the key or the combination of 7857b0563631STom Van Eyck * the two is not supported. 7858b0563631STom Van Eyck */ 7859b0563631STom Van Eyck static psa_status_t psa_validate_key_type_and_size_for_key_generation( 7860b0563631STom Van Eyck psa_key_type_t type, size_t bits) 7861b0563631STom Van Eyck { 7862b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 7863b0563631STom Van Eyck 7864b0563631STom Van Eyck if (key_type_is_raw_bytes(type)) { 7865b0563631STom Van Eyck status = psa_validate_unstructured_key_bit_size(type, bits); 7866b0563631STom Van Eyck if (status != PSA_SUCCESS) { 7867b0563631STom Van Eyck return status; 7868b0563631STom Van Eyck } 7869b0563631STom Van Eyck } else 7870b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) 7871b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_RSA(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) { 7872b0563631STom Van Eyck if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) { 7873b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 7874b0563631STom Van Eyck } 7875b0563631STom Van Eyck if (bits < PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS) { 7876b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 7877b0563631STom Van Eyck } 7878b0563631STom Van Eyck 7879b0563631STom Van Eyck /* Accept only byte-aligned keys, for the same reasons as 7880b0563631STom Van Eyck * in psa_import_rsa_key(). */ 7881b0563631STom Van Eyck if (bits % 8 != 0) { 7882b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 7883b0563631STom Van Eyck } 7884b0563631STom Van Eyck } else 7885b0563631STom Van Eyck #endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */ 7886b0563631STom Van Eyck 7887b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) 7888b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_ECC(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) { 7889b0563631STom Van Eyck /* To avoid empty block, return successfully here. */ 7890b0563631STom Van Eyck return PSA_SUCCESS; 7891b0563631STom Van Eyck } else 7892b0563631STom Van Eyck #endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) */ 7893b0563631STom Van Eyck 7894b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) 7895b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) { 7896b0563631STom Van Eyck if (psa_is_dh_key_size_valid(bits) == 0) { 7897b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 7898b0563631STom Van Eyck } 7899b0563631STom Van Eyck } else 7900b0563631STom Van Eyck #endif /* defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) */ 7901b0563631STom Van Eyck { 7902b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 7903b0563631STom Van Eyck } 7904b0563631STom Van Eyck 7905b0563631STom Van Eyck return PSA_SUCCESS; 7906b0563631STom Van Eyck } 7907b0563631STom Van Eyck 7908b0563631STom Van Eyck psa_status_t psa_generate_key_internal( 7909b0563631STom Van Eyck const psa_key_attributes_t *attributes, 7910*cb034002SJerome Forissier const psa_custom_key_parameters_t *custom, 7911*cb034002SJerome Forissier const uint8_t *custom_data, 7912*cb034002SJerome Forissier size_t custom_data_length, 7913b0563631STom Van Eyck uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) 7914b0563631STom Van Eyck { 7915b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 7916b0563631STom Van Eyck psa_key_type_t type = attributes->type; 7917b0563631STom Van Eyck 7918b0563631STom Van Eyck /* Only used for RSA */ 7919*cb034002SJerome Forissier (void) custom; 7920*cb034002SJerome Forissier (void) custom_data; 7921*cb034002SJerome Forissier (void) custom_data_length; 7922b0563631STom Van Eyck 7923b0563631STom Van Eyck if (key_type_is_raw_bytes(type)) { 7924b0563631STom Van Eyck status = psa_generate_random_internal(key_buffer, key_buffer_size); 7925b0563631STom Van Eyck if (status != PSA_SUCCESS) { 7926b0563631STom Van Eyck return status; 7927b0563631STom Van Eyck } 7928b0563631STom Van Eyck 7929b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) 7930b0563631STom Van Eyck if (type == PSA_KEY_TYPE_DES) { 7931b0563631STom Van Eyck psa_des_set_key_parity(key_buffer, key_buffer_size); 7932b0563631STom Van Eyck } 7933b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */ 7934b0563631STom Van Eyck } else 7935b0563631STom Van Eyck 7936b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) 7937b0563631STom Van Eyck if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 7938b0563631STom Van Eyck return mbedtls_psa_rsa_generate_key(attributes, 7939*cb034002SJerome Forissier custom_data, custom_data_length, 7940b0563631STom Van Eyck key_buffer, 7941b0563631STom Van Eyck key_buffer_size, 7942b0563631STom Van Eyck key_buffer_length); 7943b0563631STom Van Eyck } else 7944b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */ 7945b0563631STom Van Eyck 7946b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE) 7947b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_ECC(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) { 7948b0563631STom Van Eyck return mbedtls_psa_ecp_generate_key(attributes, 7949b0563631STom Van Eyck key_buffer, 7950b0563631STom Van Eyck key_buffer_size, 7951b0563631STom Van Eyck key_buffer_length); 7952b0563631STom Van Eyck } else 7953b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE) */ 7954b0563631STom Van Eyck 7955b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) 7956b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) { 7957b0563631STom Van Eyck return mbedtls_psa_ffdh_generate_key(attributes, 7958b0563631STom Van Eyck key_buffer, 7959b0563631STom Van Eyck key_buffer_size, 7960b0563631STom Van Eyck key_buffer_length); 7961b0563631STom Van Eyck } else 7962b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) */ 7963b0563631STom Van Eyck { 7964b0563631STom Van Eyck (void) key_buffer_length; 7965b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 7966b0563631STom Van Eyck } 7967b0563631STom Van Eyck 7968b0563631STom Van Eyck return PSA_SUCCESS; 7969b0563631STom Van Eyck } 7970b0563631STom Van Eyck 7971*cb034002SJerome Forissier psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes, 7972*cb034002SJerome Forissier const psa_custom_key_parameters_t *custom, 7973*cb034002SJerome Forissier const uint8_t *custom_data, 7974*cb034002SJerome Forissier size_t custom_data_length, 7975b0563631STom Van Eyck mbedtls_svc_key_id_t *key) 7976b0563631STom Van Eyck { 7977b0563631STom Van Eyck psa_status_t status; 7978b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 7979b0563631STom Van Eyck psa_se_drv_table_entry_t *driver = NULL; 7980b0563631STom Van Eyck size_t key_buffer_size; 7981b0563631STom Van Eyck 7982b0563631STom Van Eyck *key = MBEDTLS_SVC_KEY_ID_INIT; 7983b0563631STom Van Eyck 7984b0563631STom Van Eyck /* Reject any attempt to create a zero-length key so that we don't 7985b0563631STom Van Eyck * risk tripping up later, e.g. on a malloc(0) that returns NULL. */ 7986b0563631STom Van Eyck if (psa_get_key_bits(attributes) == 0) { 7987b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7988b0563631STom Van Eyck } 7989b0563631STom Van Eyck 7990b0563631STom Van Eyck /* Reject any attempt to create a public key. */ 7991b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->type)) { 7992b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7993b0563631STom Van Eyck } 7994b0563631STom Van Eyck 7995b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) 7996b0563631STom Van Eyck if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 7997*cb034002SJerome Forissier if (custom->flags != 0) { 7998b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 7999b0563631STom Van Eyck } 8000b0563631STom Van Eyck } else 8001b0563631STom Van Eyck #endif 8002*cb034002SJerome Forissier if (!psa_custom_key_parameters_are_default(custom, custom_data_length)) { 8003b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 8004b0563631STom Van Eyck } 8005b0563631STom Van Eyck 8006b0563631STom Van Eyck status = psa_start_key_creation(PSA_KEY_CREATION_GENERATE, attributes, 8007b0563631STom Van Eyck &slot, &driver); 8008b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8009b0563631STom Van Eyck goto exit; 8010b0563631STom Van Eyck } 8011b0563631STom Van Eyck 8012b0563631STom Van Eyck /* In the case of a transparent key or an opaque key stored in local 8013b0563631STom Van Eyck * storage ( thus not in the case of generating a key in a secure element 8014b0563631STom Van Eyck * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a 8015b0563631STom Van Eyck * buffer to hold the generated key material. */ 8016b0563631STom Van Eyck if (slot->key.data == NULL) { 8017b0563631STom Van Eyck if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime) == 8018b0563631STom Van Eyck PSA_KEY_LOCATION_LOCAL_STORAGE) { 8019b0563631STom Van Eyck status = psa_validate_key_type_and_size_for_key_generation( 8020b0563631STom Van Eyck attributes->type, attributes->bits); 8021b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8022b0563631STom Van Eyck goto exit; 8023b0563631STom Van Eyck } 8024b0563631STom Van Eyck 8025b0563631STom Van Eyck key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE( 8026b0563631STom Van Eyck attributes->type, 8027b0563631STom Van Eyck attributes->bits); 8028b0563631STom Van Eyck } else { 8029b0563631STom Van Eyck status = psa_driver_wrapper_get_key_buffer_size( 8030b0563631STom Van Eyck attributes, &key_buffer_size); 8031b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8032b0563631STom Van Eyck goto exit; 8033b0563631STom Van Eyck } 8034b0563631STom Van Eyck } 8035b0563631STom Van Eyck 8036b0563631STom Van Eyck status = psa_allocate_buffer_to_slot(slot, key_buffer_size); 8037b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8038b0563631STom Van Eyck goto exit; 8039b0563631STom Van Eyck } 8040b0563631STom Van Eyck } 8041b0563631STom Van Eyck 8042b0563631STom Van Eyck status = psa_driver_wrapper_generate_key(attributes, 8043*cb034002SJerome Forissier custom, 8044*cb034002SJerome Forissier custom_data, custom_data_length, 8045b0563631STom Van Eyck slot->key.data, slot->key.bytes, 8046b0563631STom Van Eyck &slot->key.bytes); 8047b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8048b0563631STom Van Eyck psa_remove_key_data_from_memory(slot); 8049b0563631STom Van Eyck } 8050b0563631STom Van Eyck 8051b0563631STom Van Eyck exit: 8052b0563631STom Van Eyck if (status == PSA_SUCCESS) { 8053b0563631STom Van Eyck status = psa_finish_key_creation(slot, driver, key); 8054b0563631STom Van Eyck } 8055b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8056b0563631STom Van Eyck psa_fail_key_creation(slot, driver); 8057b0563631STom Van Eyck } 8058b0563631STom Van Eyck 8059b0563631STom Van Eyck return status; 8060b0563631STom Van Eyck } 8061b0563631STom Van Eyck 8062*cb034002SJerome Forissier psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, 8063*cb034002SJerome Forissier const psa_key_production_parameters_t *params, 8064*cb034002SJerome Forissier size_t params_data_length, 8065*cb034002SJerome Forissier mbedtls_svc_key_id_t *key) 8066*cb034002SJerome Forissier { 8067*cb034002SJerome Forissier return psa_generate_key_custom( 8068*cb034002SJerome Forissier attributes, 8069*cb034002SJerome Forissier (const psa_custom_key_parameters_t *) params, 8070*cb034002SJerome Forissier params->data, params_data_length, 8071*cb034002SJerome Forissier key); 8072*cb034002SJerome Forissier } 8073*cb034002SJerome Forissier 8074b0563631STom Van Eyck psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, 8075b0563631STom Van Eyck mbedtls_svc_key_id_t *key) 8076b0563631STom Van Eyck { 8077*cb034002SJerome Forissier return psa_generate_key_custom(attributes, 8078*cb034002SJerome Forissier &default_custom_production, 8079*cb034002SJerome Forissier NULL, 0, 8080b0563631STom Van Eyck key); 8081b0563631STom Van Eyck } 8082b0563631STom Van Eyck 8083b0563631STom Van Eyck /****************************************************************/ 8084b0563631STom Van Eyck /* Module setup */ 8085b0563631STom Van Eyck /****************************************************************/ 8086b0563631STom Van Eyck 8087b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) 8088b0563631STom Van Eyck psa_status_t mbedtls_psa_crypto_configure_entropy_sources( 8089b0563631STom Van Eyck void (* entropy_init)(mbedtls_entropy_context *ctx), 8090b0563631STom Van Eyck void (* entropy_free)(mbedtls_entropy_context *ctx)) 8091b0563631STom Van Eyck { 8092b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 8093b0563631STom Van Eyck 8094b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8095b0563631STom Van Eyck mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); 8096b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8097b0563631STom Van Eyck 8098b0563631STom Van Eyck if (global_data.rng_state != RNG_NOT_INITIALIZED) { 8099b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8100b0563631STom Van Eyck } else { 8101b0563631STom Van Eyck global_data.rng.entropy_init = entropy_init; 8102b0563631STom Van Eyck global_data.rng.entropy_free = entropy_free; 8103b0563631STom Van Eyck status = PSA_SUCCESS; 8104b0563631STom Van Eyck } 8105b0563631STom Van Eyck 8106b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8107b0563631STom Van Eyck mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); 8108b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8109b0563631STom Van Eyck 8110b0563631STom Van Eyck return status; 8111b0563631STom Van Eyck } 8112b0563631STom Van Eyck #endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */ 8113b0563631STom Van Eyck 8114b0563631STom Van Eyck void mbedtls_psa_crypto_free(void) 8115b0563631STom Van Eyck { 8116b0563631STom Van Eyck 8117b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8118b0563631STom Van Eyck mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); 8119b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8120b0563631STom Van Eyck 8121b0563631STom Van Eyck /* Nothing to do to free transaction. */ 8122b0563631STom Van Eyck if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED) { 8123b0563631STom Van Eyck global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; 8124b0563631STom Van Eyck } 8125b0563631STom Van Eyck 8126b0563631STom Van Eyck if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED) { 8127b0563631STom Van Eyck psa_wipe_all_key_slots(); 8128b0563631STom Van Eyck global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED; 8129b0563631STom Van Eyck } 8130b0563631STom Van Eyck 8131b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8132b0563631STom Van Eyck mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); 8133b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8134b0563631STom Van Eyck 8135b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8136b0563631STom Van Eyck mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); 8137b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8138b0563631STom Van Eyck 8139b0563631STom Van Eyck if (global_data.rng_state != RNG_NOT_INITIALIZED) { 8140b0563631STom Van Eyck mbedtls_psa_random_free(&global_data.rng); 8141b0563631STom Van Eyck } 8142b0563631STom Van Eyck global_data.rng_state = RNG_NOT_INITIALIZED; 8143b0563631STom Van Eyck mbedtls_platform_zeroize(&global_data.rng, sizeof(global_data.rng)); 8144b0563631STom Van Eyck 8145b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8146b0563631STom Van Eyck mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); 8147b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8148b0563631STom Van Eyck 8149b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8150b0563631STom Van Eyck mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); 8151b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8152b0563631STom Van Eyck 8153b0563631STom Van Eyck /* Terminate drivers */ 8154b0563631STom Van Eyck if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED) { 8155b0563631STom Van Eyck psa_driver_wrapper_free(); 8156b0563631STom Van Eyck global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED; 8157b0563631STom Van Eyck } 8158b0563631STom Van Eyck 8159b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8160b0563631STom Van Eyck mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); 8161b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8162b0563631STom Van Eyck 8163b0563631STom Van Eyck } 8164b0563631STom Van Eyck 8165b0563631STom Van Eyck #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) 8166b0563631STom Van Eyck /** Recover a transaction that was interrupted by a power failure. 8167b0563631STom Van Eyck * 8168b0563631STom Van Eyck * This function is called during initialization, before psa_crypto_init() 8169b0563631STom Van Eyck * returns. If this function returns a failure status, the initialization 8170b0563631STom Van Eyck * fails. 8171b0563631STom Van Eyck */ 8172b0563631STom Van Eyck static psa_status_t psa_crypto_recover_transaction( 8173b0563631STom Van Eyck const psa_crypto_transaction_t *transaction) 8174b0563631STom Van Eyck { 8175b0563631STom Van Eyck switch (transaction->unknown.type) { 8176b0563631STom Van Eyck case PSA_CRYPTO_TRANSACTION_CREATE_KEY: 8177b0563631STom Van Eyck case PSA_CRYPTO_TRANSACTION_DESTROY_KEY: 8178b0563631STom Van Eyck /* TODO - fall through to the failure case until this 8179b0563631STom Van Eyck * is implemented. 8180b0563631STom Van Eyck * https://github.com/ARMmbed/mbed-crypto/issues/218 8181b0563631STom Van Eyck */ 8182b0563631STom Van Eyck default: 8183b0563631STom Van Eyck /* We found an unsupported transaction in the storage. 8184b0563631STom Van Eyck * We don't know what state the storage is in. Give up. */ 8185b0563631STom Van Eyck return PSA_ERROR_DATA_INVALID; 8186b0563631STom Van Eyck } 8187b0563631STom Van Eyck } 8188b0563631STom Van Eyck #endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */ 8189b0563631STom Van Eyck 8190b0563631STom Van Eyck static psa_status_t mbedtls_psa_crypto_init_subsystem(mbedtls_psa_crypto_subsystem subsystem) 8191b0563631STom Van Eyck { 8192b0563631STom Van Eyck psa_status_t status = PSA_SUCCESS; 8193b0563631STom Van Eyck uint8_t driver_wrappers_initialized = 0; 8194b0563631STom Van Eyck 8195b0563631STom Van Eyck switch (subsystem) { 8196b0563631STom Van Eyck case PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS: 8197b0563631STom Van Eyck 8198b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8199b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); 8200b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8201b0563631STom Van Eyck 8202b0563631STom Van Eyck if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED)) { 8203b0563631STom Van Eyck /* Init drivers */ 8204b0563631STom Van Eyck status = psa_driver_wrapper_init(); 8205b0563631STom Van Eyck 8206b0563631STom Van Eyck /* Drivers need shutdown regardless of startup errors. */ 8207b0563631STom Van Eyck global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED; 8208b0563631STom Van Eyck 8209b0563631STom Van Eyck 8210b0563631STom Van Eyck } 8211b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8212b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( 8213b0563631STom Van Eyck &mbedtls_threading_psa_globaldata_mutex)); 8214b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8215b0563631STom Van Eyck 8216b0563631STom Van Eyck break; 8217b0563631STom Van Eyck 8218b0563631STom Van Eyck case PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS: 8219b0563631STom Van Eyck 8220b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8221b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); 8222b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8223b0563631STom Van Eyck 8224b0563631STom Van Eyck if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED)) { 8225b0563631STom Van Eyck status = psa_initialize_key_slots(); 8226b0563631STom Van Eyck 8227b0563631STom Van Eyck /* Need to wipe keys even if initialization fails. */ 8228b0563631STom Van Eyck global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED; 8229b0563631STom Van Eyck 8230b0563631STom Van Eyck } 8231b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8232b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( 8233b0563631STom Van Eyck &mbedtls_threading_psa_globaldata_mutex)); 8234b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8235b0563631STom Van Eyck 8236b0563631STom Van Eyck break; 8237b0563631STom Van Eyck 8238b0563631STom Van Eyck case PSA_CRYPTO_SUBSYSTEM_RNG: 8239b0563631STom Van Eyck 8240b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8241b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); 8242b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8243b0563631STom Van Eyck 8244b0563631STom Van Eyck driver_wrappers_initialized = 8245b0563631STom Van Eyck (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED); 8246b0563631STom Van Eyck 8247b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8248b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( 8249b0563631STom Van Eyck &mbedtls_threading_psa_globaldata_mutex)); 8250b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8251b0563631STom Van Eyck 8252b0563631STom Van Eyck /* Need to use separate mutex here, as initialisation can require 8253b0563631STom Van Eyck * testing of init flags, which requires locking the global data 8254b0563631STom Van Eyck * mutex. */ 8255b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8256b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex)); 8257b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8258b0563631STom Van Eyck 8259b0563631STom Van Eyck /* Initialize and seed the random generator. */ 8260b0563631STom Van Eyck if (global_data.rng_state == RNG_NOT_INITIALIZED && driver_wrappers_initialized) { 8261b0563631STom Van Eyck mbedtls_psa_random_init(&global_data.rng); 8262b0563631STom Van Eyck global_data.rng_state = RNG_INITIALIZED; 8263b0563631STom Van Eyck 8264b0563631STom Van Eyck status = mbedtls_psa_random_seed(&global_data.rng); 8265b0563631STom Van Eyck if (status == PSA_SUCCESS) { 8266b0563631STom Van Eyck global_data.rng_state = RNG_SEEDED; 8267b0563631STom Van Eyck } 8268b0563631STom Van Eyck } 8269b0563631STom Van Eyck 8270b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8271b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( 8272b0563631STom Van Eyck &mbedtls_threading_psa_rngdata_mutex)); 8273b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8274b0563631STom Van Eyck 8275b0563631STom Van Eyck break; 8276b0563631STom Van Eyck 8277b0563631STom Van Eyck case PSA_CRYPTO_SUBSYSTEM_TRANSACTION: 8278b0563631STom Van Eyck 8279b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8280b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); 8281b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8282b0563631STom Van Eyck 8283b0563631STom Van Eyck if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED)) { 8284b0563631STom Van Eyck #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) 8285b0563631STom Van Eyck status = psa_crypto_load_transaction(); 8286b0563631STom Van Eyck if (status == PSA_SUCCESS) { 8287b0563631STom Van Eyck status = psa_crypto_recover_transaction(&psa_crypto_transaction); 8288b0563631STom Van Eyck if (status == PSA_SUCCESS) { 8289b0563631STom Van Eyck global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; 8290b0563631STom Van Eyck } 8291b0563631STom Van Eyck status = psa_crypto_stop_transaction(); 8292b0563631STom Van Eyck } else if (status == PSA_ERROR_DOES_NOT_EXIST) { 8293b0563631STom Van Eyck /* There's no transaction to complete. It's all good. */ 8294b0563631STom Van Eyck global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; 8295b0563631STom Van Eyck status = PSA_SUCCESS; 8296b0563631STom Van Eyck } 8297b0563631STom Van Eyck #else /* defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) */ 8298b0563631STom Van Eyck global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; 8299b0563631STom Van Eyck status = PSA_SUCCESS; 8300b0563631STom Van Eyck #endif /* defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) */ 8301b0563631STom Van Eyck } 8302b0563631STom Van Eyck 8303b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8304b0563631STom Van Eyck PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( 8305b0563631STom Van Eyck &mbedtls_threading_psa_globaldata_mutex)); 8306b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8307b0563631STom Van Eyck 8308b0563631STom Van Eyck break; 8309b0563631STom Van Eyck 8310b0563631STom Van Eyck default: 8311b0563631STom Van Eyck status = PSA_ERROR_CORRUPTION_DETECTED; 8312b0563631STom Van Eyck } 8313b0563631STom Van Eyck 8314b0563631STom Van Eyck /* Exit label only required when using threading macros. */ 8315b0563631STom Van Eyck #if defined(MBEDTLS_THREADING_C) 8316b0563631STom Van Eyck exit: 8317b0563631STom Van Eyck #endif /* defined(MBEDTLS_THREADING_C) */ 8318b0563631STom Van Eyck 8319b0563631STom Van Eyck return status; 8320b0563631STom Van Eyck } 8321b0563631STom Van Eyck 8322b0563631STom Van Eyck psa_status_t psa_crypto_init(void) 8323b0563631STom Van Eyck { 8324b0563631STom Van Eyck psa_status_t status; 8325b0563631STom Van Eyck 8326b0563631STom Van Eyck /* Double initialization is explicitly allowed. Early out if everything is 8327b0563631STom Van Eyck * done. */ 8328b0563631STom Van Eyck if (psa_get_initialized()) { 8329b0563631STom Van Eyck return PSA_SUCCESS; 8330b0563631STom Van Eyck } 8331b0563631STom Van Eyck 8332b0563631STom Van Eyck status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS); 8333b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8334b0563631STom Van Eyck goto exit; 8335b0563631STom Van Eyck } 8336b0563631STom Van Eyck 8337b0563631STom Van Eyck status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS); 8338b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8339b0563631STom Van Eyck goto exit; 8340b0563631STom Van Eyck } 8341b0563631STom Van Eyck 8342b0563631STom Van Eyck status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_RNG); 8343b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8344b0563631STom Van Eyck goto exit; 8345b0563631STom Van Eyck } 8346b0563631STom Van Eyck 8347b0563631STom Van Eyck status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_TRANSACTION); 8348b0563631STom Van Eyck 8349b0563631STom Van Eyck exit: 8350b0563631STom Van Eyck 8351b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8352b0563631STom Van Eyck mbedtls_psa_crypto_free(); 8353b0563631STom Van Eyck } 8354b0563631STom Van Eyck 8355b0563631STom Van Eyck return status; 8356b0563631STom Van Eyck } 8357b0563631STom Van Eyck 8358b0563631STom Van Eyck #if defined(PSA_WANT_ALG_SOME_PAKE) 8359b0563631STom Van Eyck psa_status_t psa_crypto_driver_pake_get_password_len( 8360b0563631STom Van Eyck const psa_crypto_driver_pake_inputs_t *inputs, 8361b0563631STom Van Eyck size_t *password_len) 8362b0563631STom Van Eyck { 8363b0563631STom Van Eyck if (inputs->password_len == 0) { 8364b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8365b0563631STom Van Eyck } 8366b0563631STom Van Eyck 8367b0563631STom Van Eyck *password_len = inputs->password_len; 8368b0563631STom Van Eyck 8369b0563631STom Van Eyck return PSA_SUCCESS; 8370b0563631STom Van Eyck } 8371b0563631STom Van Eyck 8372b0563631STom Van Eyck psa_status_t psa_crypto_driver_pake_get_password( 8373b0563631STom Van Eyck const psa_crypto_driver_pake_inputs_t *inputs, 8374b0563631STom Van Eyck uint8_t *buffer, size_t buffer_size, size_t *buffer_length) 8375b0563631STom Van Eyck { 8376b0563631STom Van Eyck if (inputs->password_len == 0) { 8377b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8378b0563631STom Van Eyck } 8379b0563631STom Van Eyck 8380b0563631STom Van Eyck if (buffer_size < inputs->password_len) { 8381b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 8382b0563631STom Van Eyck } 8383b0563631STom Van Eyck 8384b0563631STom Van Eyck memcpy(buffer, inputs->password, inputs->password_len); 8385b0563631STom Van Eyck *buffer_length = inputs->password_len; 8386b0563631STom Van Eyck 8387b0563631STom Van Eyck return PSA_SUCCESS; 8388b0563631STom Van Eyck } 8389b0563631STom Van Eyck 8390b0563631STom Van Eyck psa_status_t psa_crypto_driver_pake_get_user_len( 8391b0563631STom Van Eyck const psa_crypto_driver_pake_inputs_t *inputs, 8392b0563631STom Van Eyck size_t *user_len) 8393b0563631STom Van Eyck { 8394b0563631STom Van Eyck if (inputs->user_len == 0) { 8395b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8396b0563631STom Van Eyck } 8397b0563631STom Van Eyck 8398b0563631STom Van Eyck *user_len = inputs->user_len; 8399b0563631STom Van Eyck 8400b0563631STom Van Eyck return PSA_SUCCESS; 8401b0563631STom Van Eyck } 8402b0563631STom Van Eyck 8403b0563631STom Van Eyck psa_status_t psa_crypto_driver_pake_get_user( 8404b0563631STom Van Eyck const psa_crypto_driver_pake_inputs_t *inputs, 8405b0563631STom Van Eyck uint8_t *user_id, size_t user_id_size, size_t *user_id_len) 8406b0563631STom Van Eyck { 8407b0563631STom Van Eyck if (inputs->user_len == 0) { 8408b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8409b0563631STom Van Eyck } 8410b0563631STom Van Eyck 8411b0563631STom Van Eyck if (user_id_size < inputs->user_len) { 8412b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 8413b0563631STom Van Eyck } 8414b0563631STom Van Eyck 8415b0563631STom Van Eyck memcpy(user_id, inputs->user, inputs->user_len); 8416b0563631STom Van Eyck *user_id_len = inputs->user_len; 8417b0563631STom Van Eyck 8418b0563631STom Van Eyck return PSA_SUCCESS; 8419b0563631STom Van Eyck } 8420b0563631STom Van Eyck 8421b0563631STom Van Eyck psa_status_t psa_crypto_driver_pake_get_peer_len( 8422b0563631STom Van Eyck const psa_crypto_driver_pake_inputs_t *inputs, 8423b0563631STom Van Eyck size_t *peer_len) 8424b0563631STom Van Eyck { 8425b0563631STom Van Eyck if (inputs->peer_len == 0) { 8426b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8427b0563631STom Van Eyck } 8428b0563631STom Van Eyck 8429b0563631STom Van Eyck *peer_len = inputs->peer_len; 8430b0563631STom Van Eyck 8431b0563631STom Van Eyck return PSA_SUCCESS; 8432b0563631STom Van Eyck } 8433b0563631STom Van Eyck 8434b0563631STom Van Eyck psa_status_t psa_crypto_driver_pake_get_peer( 8435b0563631STom Van Eyck const psa_crypto_driver_pake_inputs_t *inputs, 8436b0563631STom Van Eyck uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length) 8437b0563631STom Van Eyck { 8438b0563631STom Van Eyck if (inputs->peer_len == 0) { 8439b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8440b0563631STom Van Eyck } 8441b0563631STom Van Eyck 8442b0563631STom Van Eyck if (peer_id_size < inputs->peer_len) { 8443b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 8444b0563631STom Van Eyck } 8445b0563631STom Van Eyck 8446b0563631STom Van Eyck memcpy(peer_id, inputs->peer, inputs->peer_len); 8447b0563631STom Van Eyck *peer_id_length = inputs->peer_len; 8448b0563631STom Van Eyck 8449b0563631STom Van Eyck return PSA_SUCCESS; 8450b0563631STom Van Eyck } 8451b0563631STom Van Eyck 8452b0563631STom Van Eyck psa_status_t psa_crypto_driver_pake_get_cipher_suite( 8453b0563631STom Van Eyck const psa_crypto_driver_pake_inputs_t *inputs, 8454b0563631STom Van Eyck psa_pake_cipher_suite_t *cipher_suite) 8455b0563631STom Van Eyck { 8456b0563631STom Van Eyck if (inputs->cipher_suite.algorithm == PSA_ALG_NONE) { 8457b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8458b0563631STom Van Eyck } 8459b0563631STom Van Eyck 8460b0563631STom Van Eyck *cipher_suite = inputs->cipher_suite; 8461b0563631STom Van Eyck 8462b0563631STom Van Eyck return PSA_SUCCESS; 8463b0563631STom Van Eyck } 8464b0563631STom Van Eyck 8465b0563631STom Van Eyck psa_status_t psa_pake_setup( 8466b0563631STom Van Eyck psa_pake_operation_t *operation, 8467b0563631STom Van Eyck const psa_pake_cipher_suite_t *cipher_suite) 8468b0563631STom Van Eyck { 8469b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 8470b0563631STom Van Eyck 8471b0563631STom Van Eyck if (operation->stage != PSA_PAKE_OPERATION_STAGE_SETUP) { 8472b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8473b0563631STom Van Eyck goto exit; 8474b0563631STom Van Eyck } 8475b0563631STom Van Eyck 8476b0563631STom Van Eyck if (PSA_ALG_IS_PAKE(cipher_suite->algorithm) == 0 || 8477b0563631STom Van Eyck PSA_ALG_IS_HASH(cipher_suite->hash) == 0) { 8478b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 8479b0563631STom Van Eyck goto exit; 8480b0563631STom Van Eyck } 8481b0563631STom Van Eyck 8482b0563631STom Van Eyck memset(&operation->data.inputs, 0, sizeof(operation->data.inputs)); 8483b0563631STom Van Eyck 8484b0563631STom Van Eyck operation->alg = cipher_suite->algorithm; 8485b0563631STom Van Eyck operation->primitive = PSA_PAKE_PRIMITIVE(cipher_suite->type, 8486b0563631STom Van Eyck cipher_suite->family, cipher_suite->bits); 8487b0563631STom Van Eyck operation->data.inputs.cipher_suite = *cipher_suite; 8488b0563631STom Van Eyck 8489b0563631STom Van Eyck #if defined(PSA_WANT_ALG_JPAKE) 8490b0563631STom Van Eyck if (operation->alg == PSA_ALG_JPAKE) { 8491b0563631STom Van Eyck psa_jpake_computation_stage_t *computation_stage = 8492b0563631STom Van Eyck &operation->computation_stage.jpake; 8493b0563631STom Van Eyck 8494b0563631STom Van Eyck memset(computation_stage, 0, sizeof(*computation_stage)); 8495b0563631STom Van Eyck computation_stage->step = PSA_PAKE_STEP_KEY_SHARE; 8496b0563631STom Van Eyck } else 8497b0563631STom Van Eyck #endif /* PSA_WANT_ALG_JPAKE */ 8498b0563631STom Van Eyck { 8499b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 8500b0563631STom Van Eyck goto exit; 8501b0563631STom Van Eyck } 8502b0563631STom Van Eyck 8503b0563631STom Van Eyck operation->stage = PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS; 8504b0563631STom Van Eyck 8505b0563631STom Van Eyck return PSA_SUCCESS; 8506b0563631STom Van Eyck exit: 8507b0563631STom Van Eyck psa_pake_abort(operation); 8508b0563631STom Van Eyck return status; 8509b0563631STom Van Eyck } 8510b0563631STom Van Eyck 8511b0563631STom Van Eyck psa_status_t psa_pake_set_password_key( 8512b0563631STom Van Eyck psa_pake_operation_t *operation, 8513b0563631STom Van Eyck mbedtls_svc_key_id_t password) 8514b0563631STom Van Eyck { 8515b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 8516b0563631STom Van Eyck psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; 8517b0563631STom Van Eyck psa_key_slot_t *slot = NULL; 8518b0563631STom Van Eyck psa_key_type_t type; 8519b0563631STom Van Eyck 8520b0563631STom Van Eyck if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { 8521b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8522b0563631STom Van Eyck goto exit; 8523b0563631STom Van Eyck } 8524b0563631STom Van Eyck 8525b0563631STom Van Eyck status = psa_get_and_lock_key_slot_with_policy(password, &slot, 8526b0563631STom Van Eyck PSA_KEY_USAGE_DERIVE, 8527b0563631STom Van Eyck operation->alg); 8528b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8529b0563631STom Van Eyck goto exit; 8530b0563631STom Van Eyck } 8531b0563631STom Van Eyck 8532b0563631STom Van Eyck type = psa_get_key_type(&slot->attr); 8533b0563631STom Van Eyck 8534b0563631STom Van Eyck if (type != PSA_KEY_TYPE_PASSWORD && 8535b0563631STom Van Eyck type != PSA_KEY_TYPE_PASSWORD_HASH) { 8536b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 8537b0563631STom Van Eyck goto exit; 8538b0563631STom Van Eyck } 8539b0563631STom Van Eyck 8540b0563631STom Van Eyck operation->data.inputs.password = mbedtls_calloc(1, slot->key.bytes); 8541b0563631STom Van Eyck if (operation->data.inputs.password == NULL) { 8542b0563631STom Van Eyck status = PSA_ERROR_INSUFFICIENT_MEMORY; 8543b0563631STom Van Eyck goto exit; 8544b0563631STom Van Eyck } 8545b0563631STom Van Eyck 8546b0563631STom Van Eyck memcpy(operation->data.inputs.password, slot->key.data, slot->key.bytes); 8547b0563631STom Van Eyck operation->data.inputs.password_len = slot->key.bytes; 8548b0563631STom Van Eyck operation->data.inputs.attributes = slot->attr; 8549b0563631STom Van Eyck 8550b0563631STom Van Eyck exit: 8551b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8552b0563631STom Van Eyck psa_pake_abort(operation); 8553b0563631STom Van Eyck } 8554b0563631STom Van Eyck unlock_status = psa_unregister_read_under_mutex(slot); 8555b0563631STom Van Eyck return (status == PSA_SUCCESS) ? unlock_status : status; 8556b0563631STom Van Eyck } 8557b0563631STom Van Eyck 8558b0563631STom Van Eyck psa_status_t psa_pake_set_user( 8559b0563631STom Van Eyck psa_pake_operation_t *operation, 8560b0563631STom Van Eyck const uint8_t *user_id_external, 8561b0563631STom Van Eyck size_t user_id_len) 8562b0563631STom Van Eyck { 8563b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 8564b0563631STom Van Eyck LOCAL_INPUT_DECLARE(user_id_external, user_id); 8565b0563631STom Van Eyck 8566b0563631STom Van Eyck if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { 8567b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8568b0563631STom Van Eyck goto exit; 8569b0563631STom Van Eyck } 8570b0563631STom Van Eyck 8571b0563631STom Van Eyck if (user_id_len == 0) { 8572b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 8573b0563631STom Van Eyck goto exit; 8574b0563631STom Van Eyck } 8575b0563631STom Van Eyck 8576b0563631STom Van Eyck if (operation->data.inputs.user_len != 0) { 8577b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8578b0563631STom Van Eyck goto exit; 8579b0563631STom Van Eyck } 8580b0563631STom Van Eyck 8581b0563631STom Van Eyck operation->data.inputs.user = mbedtls_calloc(1, user_id_len); 8582b0563631STom Van Eyck if (operation->data.inputs.user == NULL) { 8583b0563631STom Van Eyck status = PSA_ERROR_INSUFFICIENT_MEMORY; 8584b0563631STom Van Eyck goto exit; 8585b0563631STom Van Eyck } 8586b0563631STom Van Eyck 8587b0563631STom Van Eyck LOCAL_INPUT_ALLOC(user_id_external, user_id_len, user_id); 8588b0563631STom Van Eyck 8589b0563631STom Van Eyck memcpy(operation->data.inputs.user, user_id, user_id_len); 8590b0563631STom Van Eyck operation->data.inputs.user_len = user_id_len; 8591b0563631STom Van Eyck 8592b0563631STom Van Eyck status = PSA_SUCCESS; 8593b0563631STom Van Eyck 8594b0563631STom Van Eyck exit: 8595b0563631STom Van Eyck LOCAL_INPUT_FREE(user_id_external, user_id); 8596b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8597b0563631STom Van Eyck psa_pake_abort(operation); 8598b0563631STom Van Eyck } 8599b0563631STom Van Eyck return status; 8600b0563631STom Van Eyck } 8601b0563631STom Van Eyck 8602b0563631STom Van Eyck psa_status_t psa_pake_set_peer( 8603b0563631STom Van Eyck psa_pake_operation_t *operation, 8604b0563631STom Van Eyck const uint8_t *peer_id_external, 8605b0563631STom Van Eyck size_t peer_id_len) 8606b0563631STom Van Eyck { 8607b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 8608b0563631STom Van Eyck LOCAL_INPUT_DECLARE(peer_id_external, peer_id); 8609b0563631STom Van Eyck 8610b0563631STom Van Eyck if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { 8611b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8612b0563631STom Van Eyck goto exit; 8613b0563631STom Van Eyck } 8614b0563631STom Van Eyck 8615b0563631STom Van Eyck if (peer_id_len == 0) { 8616b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 8617b0563631STom Van Eyck goto exit; 8618b0563631STom Van Eyck } 8619b0563631STom Van Eyck 8620b0563631STom Van Eyck if (operation->data.inputs.peer_len != 0) { 8621b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8622b0563631STom Van Eyck goto exit; 8623b0563631STom Van Eyck } 8624b0563631STom Van Eyck 8625b0563631STom Van Eyck operation->data.inputs.peer = mbedtls_calloc(1, peer_id_len); 8626b0563631STom Van Eyck if (operation->data.inputs.peer == NULL) { 8627b0563631STom Van Eyck status = PSA_ERROR_INSUFFICIENT_MEMORY; 8628b0563631STom Van Eyck goto exit; 8629b0563631STom Van Eyck } 8630b0563631STom Van Eyck 8631b0563631STom Van Eyck LOCAL_INPUT_ALLOC(peer_id_external, peer_id_len, peer_id); 8632b0563631STom Van Eyck 8633b0563631STom Van Eyck memcpy(operation->data.inputs.peer, peer_id, peer_id_len); 8634b0563631STom Van Eyck operation->data.inputs.peer_len = peer_id_len; 8635b0563631STom Van Eyck 8636b0563631STom Van Eyck status = PSA_SUCCESS; 8637b0563631STom Van Eyck 8638b0563631STom Van Eyck exit: 8639b0563631STom Van Eyck LOCAL_INPUT_FREE(peer_id_external, peer_id); 8640b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8641b0563631STom Van Eyck psa_pake_abort(operation); 8642b0563631STom Van Eyck } 8643b0563631STom Van Eyck return status; 8644b0563631STom Van Eyck } 8645b0563631STom Van Eyck 8646b0563631STom Van Eyck psa_status_t psa_pake_set_role( 8647b0563631STom Van Eyck psa_pake_operation_t *operation, 8648b0563631STom Van Eyck psa_pake_role_t role) 8649b0563631STom Van Eyck { 8650b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 8651b0563631STom Van Eyck 8652b0563631STom Van Eyck if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { 8653b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8654b0563631STom Van Eyck goto exit; 8655b0563631STom Van Eyck } 8656b0563631STom Van Eyck 8657b0563631STom Van Eyck switch (operation->alg) { 8658b0563631STom Van Eyck #if defined(PSA_WANT_ALG_JPAKE) 8659b0563631STom Van Eyck case PSA_ALG_JPAKE: 8660b0563631STom Van Eyck if (role == PSA_PAKE_ROLE_NONE) { 8661b0563631STom Van Eyck return PSA_SUCCESS; 8662b0563631STom Van Eyck } 8663b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 8664b0563631STom Van Eyck break; 8665b0563631STom Van Eyck #endif 8666b0563631STom Van Eyck default: 8667b0563631STom Van Eyck (void) role; 8668b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 8669b0563631STom Van Eyck goto exit; 8670b0563631STom Van Eyck } 8671b0563631STom Van Eyck exit: 8672b0563631STom Van Eyck psa_pake_abort(operation); 8673b0563631STom Van Eyck return status; 8674b0563631STom Van Eyck } 8675b0563631STom Van Eyck 8676b0563631STom Van Eyck /* Auxiliary function to convert core computation stage to single driver step. */ 8677b0563631STom Van Eyck #if defined(PSA_WANT_ALG_JPAKE) 8678b0563631STom Van Eyck static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_step( 8679b0563631STom Van Eyck psa_jpake_computation_stage_t *stage) 8680b0563631STom Van Eyck { 8681b0563631STom Van Eyck psa_crypto_driver_pake_step_t key_share_step; 8682b0563631STom Van Eyck if (stage->round == PSA_JPAKE_FIRST) { 8683b0563631STom Van Eyck int is_x1; 8684b0563631STom Van Eyck 8685b0563631STom Van Eyck if (stage->io_mode == PSA_JPAKE_OUTPUT) { 8686b0563631STom Van Eyck is_x1 = (stage->outputs < 1); 8687b0563631STom Van Eyck } else { 8688b0563631STom Van Eyck is_x1 = (stage->inputs < 1); 8689b0563631STom Van Eyck } 8690b0563631STom Van Eyck 8691b0563631STom Van Eyck key_share_step = is_x1 ? 8692b0563631STom Van Eyck PSA_JPAKE_X1_STEP_KEY_SHARE : 8693b0563631STom Van Eyck PSA_JPAKE_X2_STEP_KEY_SHARE; 8694b0563631STom Van Eyck } else if (stage->round == PSA_JPAKE_SECOND) { 8695b0563631STom Van Eyck key_share_step = (stage->io_mode == PSA_JPAKE_OUTPUT) ? 8696b0563631STom Van Eyck PSA_JPAKE_X2S_STEP_KEY_SHARE : 8697b0563631STom Van Eyck PSA_JPAKE_X4S_STEP_KEY_SHARE; 8698b0563631STom Van Eyck } else { 8699b0563631STom Van Eyck return PSA_JPAKE_STEP_INVALID; 8700b0563631STom Van Eyck } 8701b0563631STom Van Eyck return (psa_crypto_driver_pake_step_t) (key_share_step + stage->step - PSA_PAKE_STEP_KEY_SHARE); 8702b0563631STom Van Eyck } 8703b0563631STom Van Eyck #endif /* PSA_WANT_ALG_JPAKE */ 8704b0563631STom Van Eyck 8705b0563631STom Van Eyck static psa_status_t psa_pake_complete_inputs( 8706b0563631STom Van Eyck psa_pake_operation_t *operation) 8707b0563631STom Van Eyck { 8708b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 8709b0563631STom Van Eyck /* Create copy of the inputs on stack as inputs share memory 8710b0563631STom Van Eyck with the driver context which will be setup by the driver. */ 8711b0563631STom Van Eyck psa_crypto_driver_pake_inputs_t inputs = operation->data.inputs; 8712b0563631STom Van Eyck 8713b0563631STom Van Eyck if (inputs.password_len == 0) { 8714b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8715b0563631STom Van Eyck } 8716b0563631STom Van Eyck 8717b0563631STom Van Eyck if (operation->alg == PSA_ALG_JPAKE) { 8718b0563631STom Van Eyck if (inputs.user_len == 0 || inputs.peer_len == 0) { 8719b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8720b0563631STom Van Eyck } 8721b0563631STom Van Eyck } 8722b0563631STom Van Eyck 8723b0563631STom Van Eyck /* Clear driver context */ 8724b0563631STom Van Eyck mbedtls_platform_zeroize(&operation->data, sizeof(operation->data)); 8725b0563631STom Van Eyck 8726b0563631STom Van Eyck status = psa_driver_wrapper_pake_setup(operation, &inputs); 8727b0563631STom Van Eyck 8728b0563631STom Van Eyck /* Driver is responsible for creating its own copy of the password. */ 8729b0563631STom Van Eyck mbedtls_zeroize_and_free(inputs.password, inputs.password_len); 8730b0563631STom Van Eyck 8731b0563631STom Van Eyck /* User and peer are translated to role. */ 8732b0563631STom Van Eyck mbedtls_free(inputs.user); 8733b0563631STom Van Eyck mbedtls_free(inputs.peer); 8734b0563631STom Van Eyck 8735b0563631STom Van Eyck if (status == PSA_SUCCESS) { 8736b0563631STom Van Eyck #if defined(PSA_WANT_ALG_JPAKE) 8737b0563631STom Van Eyck if (operation->alg == PSA_ALG_JPAKE) { 8738b0563631STom Van Eyck operation->stage = PSA_PAKE_OPERATION_STAGE_COMPUTATION; 8739b0563631STom Van Eyck } else 8740b0563631STom Van Eyck #endif /* PSA_WANT_ALG_JPAKE */ 8741b0563631STom Van Eyck { 8742b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 8743b0563631STom Van Eyck } 8744b0563631STom Van Eyck } 8745b0563631STom Van Eyck return status; 8746b0563631STom Van Eyck } 8747b0563631STom Van Eyck 8748b0563631STom Van Eyck #if defined(PSA_WANT_ALG_JPAKE) 8749b0563631STom Van Eyck static psa_status_t psa_jpake_prologue( 8750b0563631STom Van Eyck psa_pake_operation_t *operation, 8751b0563631STom Van Eyck psa_pake_step_t step, 8752b0563631STom Van Eyck psa_jpake_io_mode_t io_mode) 8753b0563631STom Van Eyck { 8754b0563631STom Van Eyck if (step != PSA_PAKE_STEP_KEY_SHARE && 8755b0563631STom Van Eyck step != PSA_PAKE_STEP_ZK_PUBLIC && 8756b0563631STom Van Eyck step != PSA_PAKE_STEP_ZK_PROOF) { 8757b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 8758b0563631STom Van Eyck } 8759b0563631STom Van Eyck 8760b0563631STom Van Eyck psa_jpake_computation_stage_t *computation_stage = 8761b0563631STom Van Eyck &operation->computation_stage.jpake; 8762b0563631STom Van Eyck 8763b0563631STom Van Eyck if (computation_stage->round != PSA_JPAKE_FIRST && 8764b0563631STom Van Eyck computation_stage->round != PSA_JPAKE_SECOND) { 8765b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8766b0563631STom Van Eyck } 8767b0563631STom Van Eyck 8768b0563631STom Van Eyck /* Check that the step we are given is the one we were expecting */ 8769b0563631STom Van Eyck if (step != computation_stage->step) { 8770b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8771b0563631STom Van Eyck } 8772b0563631STom Van Eyck 8773b0563631STom Van Eyck if (step == PSA_PAKE_STEP_KEY_SHARE && 8774b0563631STom Van Eyck computation_stage->inputs == 0 && 8775b0563631STom Van Eyck computation_stage->outputs == 0) { 8776b0563631STom Van Eyck /* Start of the round, so function decides whether we are inputting 8777b0563631STom Van Eyck * or outputting */ 8778b0563631STom Van Eyck computation_stage->io_mode = io_mode; 8779b0563631STom Van Eyck } else if (computation_stage->io_mode != io_mode) { 8780b0563631STom Van Eyck /* Middle of the round so the mode we are in must match the function 8781b0563631STom Van Eyck * called by the user */ 8782b0563631STom Van Eyck return PSA_ERROR_BAD_STATE; 8783b0563631STom Van Eyck } 8784b0563631STom Van Eyck 8785b0563631STom Van Eyck return PSA_SUCCESS; 8786b0563631STom Van Eyck } 8787b0563631STom Van Eyck 8788b0563631STom Van Eyck static psa_status_t psa_jpake_epilogue( 8789b0563631STom Van Eyck psa_pake_operation_t *operation, 8790b0563631STom Van Eyck psa_jpake_io_mode_t io_mode) 8791b0563631STom Van Eyck { 8792b0563631STom Van Eyck psa_jpake_computation_stage_t *stage = 8793b0563631STom Van Eyck &operation->computation_stage.jpake; 8794b0563631STom Van Eyck 8795b0563631STom Van Eyck if (stage->step == PSA_PAKE_STEP_ZK_PROOF) { 8796b0563631STom Van Eyck /* End of an input/output */ 8797b0563631STom Van Eyck if (io_mode == PSA_JPAKE_INPUT) { 8798b0563631STom Van Eyck stage->inputs++; 8799b0563631STom Van Eyck if (stage->inputs == PSA_JPAKE_EXPECTED_INPUTS(stage->round)) { 8800b0563631STom Van Eyck stage->io_mode = PSA_JPAKE_OUTPUT; 8801b0563631STom Van Eyck } 8802b0563631STom Van Eyck } 8803b0563631STom Van Eyck if (io_mode == PSA_JPAKE_OUTPUT) { 8804b0563631STom Van Eyck stage->outputs++; 8805b0563631STom Van Eyck if (stage->outputs == PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { 8806b0563631STom Van Eyck stage->io_mode = PSA_JPAKE_INPUT; 8807b0563631STom Van Eyck } 8808b0563631STom Van Eyck } 8809b0563631STom Van Eyck if (stage->inputs == PSA_JPAKE_EXPECTED_INPUTS(stage->round) && 8810b0563631STom Van Eyck stage->outputs == PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { 8811b0563631STom Van Eyck /* End of a round, move to the next round */ 8812b0563631STom Van Eyck stage->inputs = 0; 8813b0563631STom Van Eyck stage->outputs = 0; 8814b0563631STom Van Eyck stage->round++; 8815b0563631STom Van Eyck } 8816b0563631STom Van Eyck stage->step = PSA_PAKE_STEP_KEY_SHARE; 8817b0563631STom Van Eyck } else { 8818b0563631STom Van Eyck stage->step++; 8819b0563631STom Van Eyck } 8820b0563631STom Van Eyck return PSA_SUCCESS; 8821b0563631STom Van Eyck } 8822b0563631STom Van Eyck 8823b0563631STom Van Eyck #endif /* PSA_WANT_ALG_JPAKE */ 8824b0563631STom Van Eyck 8825b0563631STom Van Eyck psa_status_t psa_pake_output( 8826b0563631STom Van Eyck psa_pake_operation_t *operation, 8827b0563631STom Van Eyck psa_pake_step_t step, 8828b0563631STom Van Eyck uint8_t *output_external, 8829b0563631STom Van Eyck size_t output_size, 8830b0563631STom Van Eyck size_t *output_length) 8831b0563631STom Van Eyck { 8832b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 8833b0563631STom Van Eyck psa_crypto_driver_pake_step_t driver_step = PSA_JPAKE_STEP_INVALID; 8834b0563631STom Van Eyck LOCAL_OUTPUT_DECLARE(output_external, output); 8835b0563631STom Van Eyck *output_length = 0; 8836b0563631STom Van Eyck 8837b0563631STom Van Eyck if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { 8838b0563631STom Van Eyck status = psa_pake_complete_inputs(operation); 8839b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8840b0563631STom Van Eyck goto exit; 8841b0563631STom Van Eyck } 8842b0563631STom Van Eyck } 8843b0563631STom Van Eyck 8844b0563631STom Van Eyck if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) { 8845b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8846b0563631STom Van Eyck goto exit; 8847b0563631STom Van Eyck } 8848b0563631STom Van Eyck 8849b0563631STom Van Eyck if (output_size == 0) { 8850b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 8851b0563631STom Van Eyck goto exit; 8852b0563631STom Van Eyck } 8853b0563631STom Van Eyck 8854b0563631STom Van Eyck switch (operation->alg) { 8855b0563631STom Van Eyck #if defined(PSA_WANT_ALG_JPAKE) 8856b0563631STom Van Eyck case PSA_ALG_JPAKE: 8857b0563631STom Van Eyck status = psa_jpake_prologue(operation, step, PSA_JPAKE_OUTPUT); 8858b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8859b0563631STom Van Eyck goto exit; 8860b0563631STom Van Eyck } 8861b0563631STom Van Eyck driver_step = convert_jpake_computation_stage_to_driver_step( 8862b0563631STom Van Eyck &operation->computation_stage.jpake); 8863b0563631STom Van Eyck break; 8864b0563631STom Van Eyck #endif /* PSA_WANT_ALG_JPAKE */ 8865b0563631STom Van Eyck default: 8866b0563631STom Van Eyck (void) step; 8867b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 8868b0563631STom Van Eyck goto exit; 8869b0563631STom Van Eyck } 8870b0563631STom Van Eyck 8871b0563631STom Van Eyck LOCAL_OUTPUT_ALLOC(output_external, output_size, output); 8872b0563631STom Van Eyck 8873b0563631STom Van Eyck status = psa_driver_wrapper_pake_output(operation, driver_step, 8874b0563631STom Van Eyck output, output_size, output_length); 8875b0563631STom Van Eyck 8876b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8877b0563631STom Van Eyck goto exit; 8878b0563631STom Van Eyck } 8879b0563631STom Van Eyck 8880b0563631STom Van Eyck switch (operation->alg) { 8881b0563631STom Van Eyck #if defined(PSA_WANT_ALG_JPAKE) 8882b0563631STom Van Eyck case PSA_ALG_JPAKE: 8883b0563631STom Van Eyck status = psa_jpake_epilogue(operation, PSA_JPAKE_OUTPUT); 8884b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8885b0563631STom Van Eyck goto exit; 8886b0563631STom Van Eyck } 8887b0563631STom Van Eyck break; 8888b0563631STom Van Eyck #endif /* PSA_WANT_ALG_JPAKE */ 8889b0563631STom Van Eyck default: 8890b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 8891b0563631STom Van Eyck goto exit; 8892b0563631STom Van Eyck } 8893b0563631STom Van Eyck 8894b0563631STom Van Eyck exit: 8895b0563631STom Van Eyck LOCAL_OUTPUT_FREE(output_external, output); 8896b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8897b0563631STom Van Eyck psa_pake_abort(operation); 8898b0563631STom Van Eyck } 8899b0563631STom Van Eyck return status; 8900b0563631STom Van Eyck } 8901b0563631STom Van Eyck 8902b0563631STom Van Eyck psa_status_t psa_pake_input( 8903b0563631STom Van Eyck psa_pake_operation_t *operation, 8904b0563631STom Van Eyck psa_pake_step_t step, 8905b0563631STom Van Eyck const uint8_t *input_external, 8906b0563631STom Van Eyck size_t input_length) 8907b0563631STom Van Eyck { 8908b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 8909b0563631STom Van Eyck psa_crypto_driver_pake_step_t driver_step = PSA_JPAKE_STEP_INVALID; 8910b0563631STom Van Eyck const size_t max_input_length = (size_t) PSA_PAKE_INPUT_SIZE(operation->alg, 8911b0563631STom Van Eyck operation->primitive, 8912b0563631STom Van Eyck step); 8913b0563631STom Van Eyck LOCAL_INPUT_DECLARE(input_external, input); 8914b0563631STom Van Eyck 8915b0563631STom Van Eyck if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { 8916b0563631STom Van Eyck status = psa_pake_complete_inputs(operation); 8917b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8918b0563631STom Van Eyck goto exit; 8919b0563631STom Van Eyck } 8920b0563631STom Van Eyck } 8921b0563631STom Van Eyck 8922b0563631STom Van Eyck if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) { 8923b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8924b0563631STom Van Eyck goto exit; 8925b0563631STom Van Eyck } 8926b0563631STom Van Eyck 8927b0563631STom Van Eyck if (input_length == 0 || input_length > max_input_length) { 8928b0563631STom Van Eyck status = PSA_ERROR_INVALID_ARGUMENT; 8929b0563631STom Van Eyck goto exit; 8930b0563631STom Van Eyck } 8931b0563631STom Van Eyck 8932b0563631STom Van Eyck switch (operation->alg) { 8933b0563631STom Van Eyck #if defined(PSA_WANT_ALG_JPAKE) 8934b0563631STom Van Eyck case PSA_ALG_JPAKE: 8935b0563631STom Van Eyck status = psa_jpake_prologue(operation, step, PSA_JPAKE_INPUT); 8936b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8937b0563631STom Van Eyck goto exit; 8938b0563631STom Van Eyck } 8939b0563631STom Van Eyck driver_step = convert_jpake_computation_stage_to_driver_step( 8940b0563631STom Van Eyck &operation->computation_stage.jpake); 8941b0563631STom Van Eyck break; 8942b0563631STom Van Eyck #endif /* PSA_WANT_ALG_JPAKE */ 8943b0563631STom Van Eyck default: 8944b0563631STom Van Eyck (void) step; 8945b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 8946b0563631STom Van Eyck goto exit; 8947b0563631STom Van Eyck } 8948b0563631STom Van Eyck 8949b0563631STom Van Eyck LOCAL_INPUT_ALLOC(input_external, input_length, input); 8950b0563631STom Van Eyck status = psa_driver_wrapper_pake_input(operation, driver_step, 8951b0563631STom Van Eyck input, input_length); 8952b0563631STom Van Eyck 8953b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8954b0563631STom Van Eyck goto exit; 8955b0563631STom Van Eyck } 8956b0563631STom Van Eyck 8957b0563631STom Van Eyck switch (operation->alg) { 8958b0563631STom Van Eyck #if defined(PSA_WANT_ALG_JPAKE) 8959b0563631STom Van Eyck case PSA_ALG_JPAKE: 8960b0563631STom Van Eyck status = psa_jpake_epilogue(operation, PSA_JPAKE_INPUT); 8961b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8962b0563631STom Van Eyck goto exit; 8963b0563631STom Van Eyck } 8964b0563631STom Van Eyck break; 8965b0563631STom Van Eyck #endif /* PSA_WANT_ALG_JPAKE */ 8966b0563631STom Van Eyck default: 8967b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 8968b0563631STom Van Eyck goto exit; 8969b0563631STom Van Eyck } 8970b0563631STom Van Eyck 8971b0563631STom Van Eyck exit: 8972b0563631STom Van Eyck LOCAL_INPUT_FREE(input_external, input); 8973b0563631STom Van Eyck if (status != PSA_SUCCESS) { 8974b0563631STom Van Eyck psa_pake_abort(operation); 8975b0563631STom Van Eyck } 8976b0563631STom Van Eyck return status; 8977b0563631STom Van Eyck } 8978b0563631STom Van Eyck 8979b0563631STom Van Eyck psa_status_t psa_pake_get_implicit_key( 8980b0563631STom Van Eyck psa_pake_operation_t *operation, 8981b0563631STom Van Eyck psa_key_derivation_operation_t *output) 8982b0563631STom Van Eyck { 8983b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 8984b0563631STom Van Eyck psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; 8985b0563631STom Van Eyck uint8_t shared_key[MBEDTLS_PSA_JPAKE_BUFFER_SIZE]; 8986b0563631STom Van Eyck size_t shared_key_len = 0; 8987b0563631STom Van Eyck 8988b0563631STom Van Eyck if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) { 8989b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8990b0563631STom Van Eyck goto exit; 8991b0563631STom Van Eyck } 8992b0563631STom Van Eyck 8993b0563631STom Van Eyck #if defined(PSA_WANT_ALG_JPAKE) 8994b0563631STom Van Eyck if (operation->alg == PSA_ALG_JPAKE) { 8995b0563631STom Van Eyck psa_jpake_computation_stage_t *computation_stage = 8996b0563631STom Van Eyck &operation->computation_stage.jpake; 8997b0563631STom Van Eyck if (computation_stage->round != PSA_JPAKE_FINISHED) { 8998b0563631STom Van Eyck status = PSA_ERROR_BAD_STATE; 8999b0563631STom Van Eyck goto exit; 9000b0563631STom Van Eyck } 9001b0563631STom Van Eyck } else 9002b0563631STom Van Eyck #endif /* PSA_WANT_ALG_JPAKE */ 9003b0563631STom Van Eyck { 9004b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 9005b0563631STom Van Eyck goto exit; 9006b0563631STom Van Eyck } 9007b0563631STom Van Eyck 9008b0563631STom Van Eyck status = psa_driver_wrapper_pake_get_implicit_key(operation, 9009b0563631STom Van Eyck shared_key, 9010b0563631STom Van Eyck sizeof(shared_key), 9011b0563631STom Van Eyck &shared_key_len); 9012b0563631STom Van Eyck 9013b0563631STom Van Eyck if (status != PSA_SUCCESS) { 9014b0563631STom Van Eyck goto exit; 9015b0563631STom Van Eyck } 9016b0563631STom Van Eyck 9017b0563631STom Van Eyck status = psa_key_derivation_input_bytes(output, 9018b0563631STom Van Eyck PSA_KEY_DERIVATION_INPUT_SECRET, 9019b0563631STom Van Eyck shared_key, 9020b0563631STom Van Eyck shared_key_len); 9021b0563631STom Van Eyck 9022b0563631STom Van Eyck mbedtls_platform_zeroize(shared_key, sizeof(shared_key)); 9023b0563631STom Van Eyck exit: 9024b0563631STom Van Eyck abort_status = psa_pake_abort(operation); 9025b0563631STom Van Eyck return status == PSA_SUCCESS ? abort_status : status; 9026b0563631STom Van Eyck } 9027b0563631STom Van Eyck 9028b0563631STom Van Eyck psa_status_t psa_pake_abort( 9029b0563631STom Van Eyck psa_pake_operation_t *operation) 9030b0563631STom Van Eyck { 9031b0563631STom Van Eyck psa_status_t status = PSA_SUCCESS; 9032b0563631STom Van Eyck 9033b0563631STom Van Eyck if (operation->stage == PSA_PAKE_OPERATION_STAGE_COMPUTATION) { 9034b0563631STom Van Eyck status = psa_driver_wrapper_pake_abort(operation); 9035b0563631STom Van Eyck } 9036b0563631STom Van Eyck 9037b0563631STom Van Eyck if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { 9038b0563631STom Van Eyck if (operation->data.inputs.password != NULL) { 9039b0563631STom Van Eyck mbedtls_zeroize_and_free(operation->data.inputs.password, 9040b0563631STom Van Eyck operation->data.inputs.password_len); 9041b0563631STom Van Eyck } 9042b0563631STom Van Eyck if (operation->data.inputs.user != NULL) { 9043b0563631STom Van Eyck mbedtls_free(operation->data.inputs.user); 9044b0563631STom Van Eyck } 9045b0563631STom Van Eyck if (operation->data.inputs.peer != NULL) { 9046b0563631STom Van Eyck mbedtls_free(operation->data.inputs.peer); 9047b0563631STom Van Eyck } 9048b0563631STom Van Eyck } 9049b0563631STom Van Eyck memset(operation, 0, sizeof(psa_pake_operation_t)); 9050b0563631STom Van Eyck 9051b0563631STom Van Eyck return status; 9052b0563631STom Van Eyck } 9053b0563631STom Van Eyck #endif /* PSA_WANT_ALG_SOME_PAKE */ 9054b0563631STom Van Eyck 9055b0563631STom Van Eyck /* Memory copying test hooks. These are called before input copy, after input 9056b0563631STom Van Eyck * copy, before output copy and after output copy, respectively. 9057b0563631STom Van Eyck * They are used by memory-poisoning tests to temporarily unpoison buffers 9058b0563631STom Van Eyck * while they are copied. */ 9059b0563631STom Van Eyck #if defined(MBEDTLS_TEST_HOOKS) 9060b0563631STom Van Eyck void (*psa_input_pre_copy_hook)(const uint8_t *input, size_t input_len) = NULL; 9061b0563631STom Van Eyck void (*psa_input_post_copy_hook)(const uint8_t *input, size_t input_len) = NULL; 9062b0563631STom Van Eyck void (*psa_output_pre_copy_hook)(const uint8_t *output, size_t output_len) = NULL; 9063b0563631STom Van Eyck void (*psa_output_post_copy_hook)(const uint8_t *output, size_t output_len) = NULL; 9064b0563631STom Van Eyck #endif 9065b0563631STom Van Eyck 9066b0563631STom Van Eyck /** Copy from an input buffer to a local copy. 9067b0563631STom Van Eyck * 9068b0563631STom Van Eyck * \param[in] input Pointer to input buffer. 9069b0563631STom Van Eyck * \param[in] input_len Length of the input buffer. 9070b0563631STom Van Eyck * \param[out] input_copy Pointer to a local copy in which to store the input data. 9071b0563631STom Van Eyck * \param[out] input_copy_len Length of the local copy buffer. 9072b0563631STom Van Eyck * \return #PSA_SUCCESS, if the buffer was successfully 9073b0563631STom Van Eyck * copied. 9074b0563631STom Van Eyck * \return #PSA_ERROR_CORRUPTION_DETECTED, if the local 9075b0563631STom Van Eyck * copy is too small to hold contents of the 9076b0563631STom Van Eyck * input buffer. 9077b0563631STom Van Eyck */ 9078b0563631STom Van Eyck MBEDTLS_STATIC_TESTABLE 9079b0563631STom Van Eyck psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, 9080b0563631STom Van Eyck uint8_t *input_copy, size_t input_copy_len) 9081b0563631STom Van Eyck { 9082b0563631STom Van Eyck if (input_len > input_copy_len) { 9083b0563631STom Van Eyck return PSA_ERROR_CORRUPTION_DETECTED; 9084b0563631STom Van Eyck } 9085b0563631STom Van Eyck 9086b0563631STom Van Eyck #if defined(MBEDTLS_TEST_HOOKS) 9087b0563631STom Van Eyck if (psa_input_pre_copy_hook != NULL) { 9088b0563631STom Van Eyck psa_input_pre_copy_hook(input, input_len); 9089b0563631STom Van Eyck } 9090b0563631STom Van Eyck #endif 9091b0563631STom Van Eyck 9092b0563631STom Van Eyck if (input_len > 0) { 9093b0563631STom Van Eyck memcpy(input_copy, input, input_len); 9094b0563631STom Van Eyck } 9095b0563631STom Van Eyck 9096b0563631STom Van Eyck #if defined(MBEDTLS_TEST_HOOKS) 9097b0563631STom Van Eyck if (psa_input_post_copy_hook != NULL) { 9098b0563631STom Van Eyck psa_input_post_copy_hook(input, input_len); 9099b0563631STom Van Eyck } 9100b0563631STom Van Eyck #endif 9101b0563631STom Van Eyck 9102b0563631STom Van Eyck return PSA_SUCCESS; 9103b0563631STom Van Eyck } 9104b0563631STom Van Eyck 9105b0563631STom Van Eyck /** Copy from a local output buffer into a user-supplied one. 9106b0563631STom Van Eyck * 9107b0563631STom Van Eyck * \param[in] output_copy Pointer to a local buffer containing the output. 9108b0563631STom Van Eyck * \param[in] output_copy_len Length of the local buffer. 9109b0563631STom Van Eyck * \param[out] output Pointer to user-supplied output buffer. 9110b0563631STom Van Eyck * \param[out] output_len Length of the user-supplied output buffer. 9111b0563631STom Van Eyck * \return #PSA_SUCCESS, if the buffer was successfully 9112b0563631STom Van Eyck * copied. 9113b0563631STom Van Eyck * \return #PSA_ERROR_BUFFER_TOO_SMALL, if the 9114b0563631STom Van Eyck * user-supplied output buffer is too small to 9115b0563631STom Van Eyck * hold the contents of the local buffer. 9116b0563631STom Van Eyck */ 9117b0563631STom Van Eyck MBEDTLS_STATIC_TESTABLE 9118b0563631STom Van Eyck psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, 9119b0563631STom Van Eyck uint8_t *output, size_t output_len) 9120b0563631STom Van Eyck { 9121b0563631STom Van Eyck if (output_len < output_copy_len) { 9122b0563631STom Van Eyck return PSA_ERROR_BUFFER_TOO_SMALL; 9123b0563631STom Van Eyck } 9124b0563631STom Van Eyck 9125b0563631STom Van Eyck #if defined(MBEDTLS_TEST_HOOKS) 9126b0563631STom Van Eyck if (psa_output_pre_copy_hook != NULL) { 9127b0563631STom Van Eyck psa_output_pre_copy_hook(output, output_len); 9128b0563631STom Van Eyck } 9129b0563631STom Van Eyck #endif 9130b0563631STom Van Eyck 9131b0563631STom Van Eyck if (output_copy_len > 0) { 9132b0563631STom Van Eyck memcpy(output, output_copy, output_copy_len); 9133b0563631STom Van Eyck } 9134b0563631STom Van Eyck 9135b0563631STom Van Eyck #if defined(MBEDTLS_TEST_HOOKS) 9136b0563631STom Van Eyck if (psa_output_post_copy_hook != NULL) { 9137b0563631STom Van Eyck psa_output_post_copy_hook(output, output_len); 9138b0563631STom Van Eyck } 9139b0563631STom Van Eyck #endif 9140b0563631STom Van Eyck 9141b0563631STom Van Eyck return PSA_SUCCESS; 9142b0563631STom Van Eyck } 9143b0563631STom Van Eyck 9144b0563631STom Van Eyck psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len, 9145b0563631STom Van Eyck psa_crypto_local_input_t *local_input) 9146b0563631STom Van Eyck { 9147b0563631STom Van Eyck psa_status_t status; 9148b0563631STom Van Eyck 9149b0563631STom Van Eyck *local_input = PSA_CRYPTO_LOCAL_INPUT_INIT; 9150b0563631STom Van Eyck 9151b0563631STom Van Eyck if (input_len == 0) { 9152b0563631STom Van Eyck return PSA_SUCCESS; 9153b0563631STom Van Eyck } 9154b0563631STom Van Eyck 9155b0563631STom Van Eyck local_input->buffer = mbedtls_calloc(input_len, 1); 9156b0563631STom Van Eyck if (local_input->buffer == NULL) { 9157b0563631STom Van Eyck /* Since we dealt with the zero-length case above, we know that 9158b0563631STom Van Eyck * a NULL return value means a failure of allocation. */ 9159b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 9160b0563631STom Van Eyck } 9161b0563631STom Van Eyck /* From now on, we must free local_input->buffer on error. */ 9162b0563631STom Van Eyck 9163b0563631STom Van Eyck local_input->length = input_len; 9164b0563631STom Van Eyck 9165b0563631STom Van Eyck status = psa_crypto_copy_input(input, input_len, 9166b0563631STom Van Eyck local_input->buffer, local_input->length); 9167b0563631STom Van Eyck if (status != PSA_SUCCESS) { 9168b0563631STom Van Eyck goto error; 9169b0563631STom Van Eyck } 9170b0563631STom Van Eyck 9171b0563631STom Van Eyck return PSA_SUCCESS; 9172b0563631STom Van Eyck 9173b0563631STom Van Eyck error: 9174b0563631STom Van Eyck mbedtls_free(local_input->buffer); 9175b0563631STom Van Eyck local_input->buffer = NULL; 9176b0563631STom Van Eyck local_input->length = 0; 9177b0563631STom Van Eyck return status; 9178b0563631STom Van Eyck } 9179b0563631STom Van Eyck 9180b0563631STom Van Eyck void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input) 9181b0563631STom Van Eyck { 9182b0563631STom Van Eyck mbedtls_free(local_input->buffer); 9183b0563631STom Van Eyck local_input->buffer = NULL; 9184b0563631STom Van Eyck local_input->length = 0; 9185b0563631STom Van Eyck } 9186b0563631STom Van Eyck 9187b0563631STom Van Eyck psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len, 9188b0563631STom Van Eyck psa_crypto_local_output_t *local_output) 9189b0563631STom Van Eyck { 9190b0563631STom Van Eyck *local_output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; 9191b0563631STom Van Eyck 9192b0563631STom Van Eyck if (output_len == 0) { 9193b0563631STom Van Eyck return PSA_SUCCESS; 9194b0563631STom Van Eyck } 9195b0563631STom Van Eyck local_output->buffer = mbedtls_calloc(output_len, 1); 9196b0563631STom Van Eyck if (local_output->buffer == NULL) { 9197b0563631STom Van Eyck /* Since we dealt with the zero-length case above, we know that 9198b0563631STom Van Eyck * a NULL return value means a failure of allocation. */ 9199b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 9200b0563631STom Van Eyck } 9201b0563631STom Van Eyck local_output->length = output_len; 9202b0563631STom Van Eyck local_output->original = output; 9203b0563631STom Van Eyck 9204b0563631STom Van Eyck return PSA_SUCCESS; 9205b0563631STom Van Eyck } 9206b0563631STom Van Eyck 9207b0563631STom Van Eyck psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output) 9208b0563631STom Van Eyck { 9209b0563631STom Van Eyck psa_status_t status; 9210b0563631STom Van Eyck 9211b0563631STom Van Eyck if (local_output->buffer == NULL) { 9212b0563631STom Van Eyck local_output->length = 0; 9213b0563631STom Van Eyck return PSA_SUCCESS; 9214b0563631STom Van Eyck } 9215b0563631STom Van Eyck if (local_output->original == NULL) { 9216b0563631STom Van Eyck /* We have an internal copy but nothing to copy back to. */ 9217b0563631STom Van Eyck return PSA_ERROR_CORRUPTION_DETECTED; 9218b0563631STom Van Eyck } 9219b0563631STom Van Eyck 9220b0563631STom Van Eyck status = psa_crypto_copy_output(local_output->buffer, local_output->length, 9221b0563631STom Van Eyck local_output->original, local_output->length); 9222b0563631STom Van Eyck if (status != PSA_SUCCESS) { 9223b0563631STom Van Eyck return status; 9224b0563631STom Van Eyck } 9225b0563631STom Van Eyck 9226b0563631STom Van Eyck mbedtls_free(local_output->buffer); 9227b0563631STom Van Eyck local_output->buffer = NULL; 9228b0563631STom Van Eyck local_output->length = 0; 9229b0563631STom Van Eyck 9230b0563631STom Van Eyck return PSA_SUCCESS; 9231b0563631STom Van Eyck } 9232b0563631STom Van Eyck 9233b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_C */ 9234