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