diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt index 8e32e9212d3..f0b07fdb1cd 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt @@ -18,7 +18,6 @@ if("TFM_V8M" IN_LIST MBED_TARGET_LABELS) INTERFACE TARGET_TFM_V8M/src/cmsis_nvic_virtual.c TARGET_TFM_V8M/src/tfm_mbed_boot.c - TARGET_TFM_V8M/src/tfm_ns_interface.c TARGET_TFM_V8M/src/tfm_psa_ns_api.c ) endif() diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_psa_ns_api.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_psa_ns_api.c index 9a677a2cd3c..751216dd0b3 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_psa_ns_api.c +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_psa_ns_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. + * Copyright (c) 2018-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -8,6 +8,7 @@ #include "psa/client.h" #include "tfm_ns_interface.h" #include "tfm_api.h" +#include "tfm_psa_call_param.h" /**** API functions ****/ @@ -47,23 +48,17 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, psa_outvec *out_vec, size_t out_len) { - /* FixMe: sanity check can be added to offload some NS thread checks from - * TFM secure API - */ - - /* Due to v8M restrictions, TF-M NS API needs to add another layer of - * serialization in order for NS to pass arguments to S - */ - const struct tfm_control_parameter_t ctrl_param = { - .type = type, - .in_len = in_len, - .out_len = out_len, - }; + if ((type > INT16_MAX) || + (type < INT16_MIN) || + (in_len > UINT8_MAX) || + (out_len > UINT8_MAX)) { + return PSA_ERROR_PROGRAMMER_ERROR; + } return tfm_ns_interface_dispatch( (veneer_fn)tfm_psa_call_veneer, (uint32_t)handle, - (uint32_t)&ctrl_param, + PARAM_PACK(type, in_len, out_len), (uint32_t)in_vec, (uint32_t)out_vec); } diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/VERSION.txt b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/VERSION.txt index 662f8752319..0d8074c8546 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/VERSION.txt +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/VERSION.txt @@ -1 +1 @@ -TF-Mv1.3.0 +TF-Mv1.4.0 diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/client.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/client.h index 8fd2d13674c..7aee1e5e6a3 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/client.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/client.h @@ -17,6 +17,10 @@ extern "C" { #endif +#ifndef IOVEC_LEN +#define IOVEC_LEN(arr) ((uint32_t)(sizeof(arr)/sizeof(arr[0]))) +#endif + /*********************** PSA Client Macros and Types *************************/ /** @@ -126,6 +130,14 @@ psa_handle_t psa_connect(uint32_t sid, uint32_t version); /** * \brief Call an RoT Service on an established connection. * + * \note FF-M 1.0 proposes 6 parameters for psa_call but the secure gateway ABI + * support at most 4 parameters. TF-M chooses to encode 'in_len', + * 'out_len', and 'type' into a 32-bit integer to improve efficiency. + * Compared with struct-based encoding, this method saves extra memory + * check and memory copy operation. The disadvantage is that the 'type' + * range has to be reduced into a 16-bit integer. So with this encoding, + * the valid range for 'type' is 0-32767. + * * \param[in] handle A handle to an established connection. * \param[in] type The request type. * Must be zero( \ref PSA_IPC_CALL) or positive. diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto.h index e9d3c66d466..5ccc5e7889d 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto.h @@ -78,10 +78,14 @@ extern "C" { * * \retval #PSA_SUCCESS * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT */ psa_status_t psa_crypto_init(void); @@ -91,18 +95,6 @@ psa_status_t psa_crypto_init(void); * @{ */ -/** \def PSA_KEY_ATTRIBUTES_INIT - * - * This macro returns a suitable initializer for a key attribute structure - * of type #psa_key_attributes_t. - */ -#ifdef __DOXYGEN_ONLY__ -/* This is an example definition for documentation purposes. - * Implementations should define a suitable value in `crypto_struct.h`. - */ -#define PSA_KEY_ATTRIBUTES_INIT {0} -#endif - /** Return an initial value for a key attributes structure. */ static psa_key_attributes_t psa_key_attributes_init(void); @@ -228,6 +220,14 @@ static psa_key_usage_t psa_get_key_usage_flags( * - An algorithm value permits this particular algorithm. * - An algorithm wildcard built from #PSA_ALG_ANY_HASH allows the specified * signature scheme with any hash algorithm. + * - An algorithm built from #PSA_ALG_AT_LEAST_THIS_LENGTH_MAC allows + * any MAC algorithm from the same base class (e.g. CMAC) which + * generates/verifies a MAC length greater than or equal to the length + * encoded in the wildcard algorithm. + * - An algorithm built from #PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG + * allows any AEAD algorithm from the same base class (e.g. CCM) which + * generates/verifies a tag length greater than or equal to the length + * encoded in the wildcard algorithm. * * This function overwrites any algorithm policy * previously set in \p attributes. @@ -336,6 +336,8 @@ static size_t psa_get_key_bits(const psa_key_attributes_t *attributes); * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_DATA_INVALID * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -469,6 +471,8 @@ psa_status_t psa_purge_key(psa_key_id_t key); * \retval #PSA_ERROR_INSUFFICIENT_STORAGE * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_BAD_STATE @@ -508,6 +512,10 @@ psa_status_t psa_copy_key(psa_key_id_t source_key, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * There was an failure in communication with the cryptoprocessor. * The key material may still be present in the cryptoprocessor. + * \retval #PSA_ERROR_DATA_INVALID + * This error is typically a result of either storage corruption on a + * cleartext storage backend, or an attempt to read data that was + * written by an incompatible version of the library. * \retval #PSA_ERROR_STORAGE_FAILURE * The storage is corrupted. Implementations shall make a best effort * to erase key material even in this stage, however applications @@ -593,6 +601,8 @@ psa_status_t psa_destroy_key(psa_key_id_t key); * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_INSUFFICIENT_STORAGE * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_DATA_INVALID * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED @@ -655,6 +665,8 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes, * For Weierstrass curves, this is the content of the `privateKey` field of * the `ECPrivateKey` format defined by RFC 5915. For Montgomery curves, * the format is defined by RFC 7748, and output is masked according to ยง5. + * For twisted Edwards curves, the private key is as defined by RFC 8032 + * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448). * - For Diffie-Hellman key exchange key pairs (key types for which * #PSA_KEY_TYPE_IS_DH_KEY_PAIR is true), the * format is the representation of the private key `x` as a big-endian byte @@ -681,7 +693,7 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes, * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p data buffer is too small. You can determine a * sufficient buffer size by calling - * #PSA_KEY_EXPORT_MAX_SIZE(\c type, \c bits) + * #PSA_EXPORT_KEY_OUTPUT_SIZE(\c type, \c bits) * where \c type is the key type * and \c bits is the key size in bits. * \retval #PSA_ERROR_COMMUNICATION_FAILURE @@ -720,7 +732,12 @@ psa_status_t psa_export_key(psa_key_id_t key, * modulus INTEGER, -- n * publicExponent INTEGER } -- e * ``` - * - For elliptic curve public keys (key types for which + * - For elliptic curve keys on a twisted Edwards curve (key types for which + * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true and #PSA_KEY_TYPE_ECC_GET_FAMILY + * returns #PSA_ECC_FAMILY_TWISTED_EDWARDS), the public key is as defined + * by RFC 8032 + * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448). + * - For other elliptic curve public keys (key types for which * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true), the format is the uncompressed * representation defined by SEC1 §2.3.3 as the content of an ECPoint. * Let `m` be the bit size associated with the curve, i.e. the bit size of @@ -751,7 +768,7 @@ psa_status_t psa_export_key(psa_key_id_t key, * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p data buffer is too small. You can determine a * sufficient buffer size by calling - * #PSA_KEY_EXPORT_MAX_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits) + * #PSA_EXPORT_KEY_OUTPUT_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits) * where \c type is the key type * and \c bits is the key size in bits. * \retval #PSA_ERROR_COMMUNICATION_FAILURE @@ -790,7 +807,7 @@ psa_status_t psa_export_public_key(psa_key_id_t key, * \param hash_size Size of the \p hash buffer in bytes. * \param[out] hash_length On success, the number of bytes * that make up the hash value. This is always - * #PSA_HASH_SIZE(\p alg). + * #PSA_HASH_LENGTH(\p alg). * * \retval #PSA_SUCCESS * Success. @@ -877,22 +894,10 @@ psa_status_t psa_hash_compare(psa_algorithm_t alg, * \endcode * * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure except - * as directed by the documentation of a specific implementation. */ + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ typedef struct psa_hash_operation_s psa_hash_operation_t; -/** \def PSA_HASH_OPERATION_INIT - * - * This macro returns a suitable initializer for a hash operation object - * of type #psa_hash_operation_t. - */ -#ifdef __DOXYGEN_ONLY__ -/* This is an example definition for documentation purposes. - * Implementations should define a suitable value in `crypto_struct.h`. - */ -#define PSA_HASH_OPERATION_INIT {0} -#endif - /** Return an initial value for a hash operation object. */ static psa_hash_operation_t psa_hash_operation_init(void); @@ -1000,7 +1005,7 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation, * \param hash_size Size of the \p hash buffer in bytes. * \param[out] hash_length On success, the number of bytes * that make up the hash value. This is always - * #PSA_HASH_SIZE(\c alg) where \c alg is the + * #PSA_HASH_LENGTH(\c alg) where \c alg is the * hash algorithm that is calculated. * * \retval #PSA_SUCCESS @@ -1009,7 +1014,7 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation, * The operation state is not valid (it must be active). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p hash buffer is too small. You can determine a - * sufficient buffer size by calling #PSA_HASH_SIZE(\c alg) + * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg) * where \c alg is the hash algorithm that is calculated. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE @@ -1246,23 +1251,12 @@ psa_status_t psa_mac_verify(psa_key_id_t key, * operation = psa_mac_operation_init(); * \endcode * + * * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure except - * as directed by the documentation of a specific implementation. */ + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ typedef struct psa_mac_operation_s psa_mac_operation_t; -/** \def PSA_MAC_OPERATION_INIT - * - * This macro returns a suitable initializer for a MAC operation object of type - * #psa_mac_operation_t. - */ -#ifdef __DOXYGEN_ONLY__ -/* This is an example definition for documentation purposes. - * Implementations should define a suitable value in `crypto_struct.h`. - */ -#define PSA_MAC_OPERATION_INIT {0} -#endif - /** Return an initial value for a MAC operation object. */ static psa_mac_operation_t psa_mac_operation_init(void); @@ -1447,7 +1441,7 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation, * \param mac_size Size of the \p mac buffer in bytes. * \param[out] mac_length On success, the number of bytes * that make up the MAC value. This is always - * #PSA_MAC_FINAL_SIZE(\c key_type, \c key_bits, \c alg) + * #PSA_MAC_LENGTH(\c key_type, \c key_bits, \c alg) * where \c key_type and \c key_bits are the type and * bit-size respectively of the key and \c alg is the * MAC algorithm that is calculated. @@ -1459,7 +1453,7 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation, * operation). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p mac buffer is too small. You can determine a - * sufficient buffer size by calling PSA_MAC_FINAL_SIZE(). + * sufficient buffer size by calling PSA_MAC_LENGTH(). * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE @@ -1671,22 +1665,10 @@ psa_status_t psa_cipher_decrypt(psa_key_id_t key, * \endcode * * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure except - * as directed by the documentation of a specific implementation. */ + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ typedef struct psa_cipher_operation_s psa_cipher_operation_t; -/** \def PSA_CIPHER_OPERATION_INIT - * - * This macro returns a suitable initializer for a cipher operation object of - * type #psa_cipher_operation_t. - */ -#ifdef __DOXYGEN_ONLY__ -/* This is an example definition for documentation purposes. - * Implementations should define a suitable value in `crypto_struct.h`. - */ -#define PSA_CIPHER_OPERATION_INIT {0} -#endif - /** Return an initial value for a cipher operation object. */ static psa_cipher_operation_t psa_cipher_operation_init(void); @@ -2052,9 +2034,16 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); * authentication tag is appended to the * encrypted data. * \param ciphertext_size Size of the \p ciphertext buffer in bytes. - * This must be at least - * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\p alg, - * \p plaintext_length). + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, + * \p alg, \p plaintext_length) where + * \c key_type is the type of \p key. + * - #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p + * plaintext_length) evaluates to the maximum + * ciphertext size of any supported AEAD + * encryption. * \param[out] ciphertext_length On success, the size of the output * in the \p ciphertext buffer. * @@ -2068,7 +2057,11 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); * \p alg is not supported or is not an AEAD algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p ciphertext_size is too small + * \p ciphertext_size is too small. + * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, \p alg, + * \p plaintext_length) or + * #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length) can be used to + * determine the required buffer size. * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED @@ -2112,9 +2105,16 @@ psa_status_t psa_aead_encrypt(psa_key_id_t key, * \param ciphertext_length Size of \p ciphertext in bytes. * \param[out] plaintext Output buffer for the decrypted data. * \param plaintext_size Size of the \p plaintext buffer in bytes. - * This must be at least - * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\p alg, - * \p ciphertext_length). + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, + * \p alg, \p ciphertext_length) where + * \c key_type is the type of \p key. + * - #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p + * ciphertext_length) evaluates to the maximum + * plaintext size of any supported AEAD + * decryption. * \param[out] plaintext_length On success, the size of the output * in the \p plaintext buffer. * @@ -2130,7 +2130,11 @@ psa_status_t psa_aead_encrypt(psa_key_id_t key, * \p alg is not supported or is not an AEAD algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p plaintext_size or \p nonce_length is too small + * \p plaintext_size is too small. + * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, \p alg, + * \p ciphertext_length) or + * #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length) can be used + * to determine the required buffer size. * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED @@ -2178,22 +2182,10 @@ psa_status_t psa_aead_decrypt(psa_key_id_t key, * \endcode * * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure except - * as directed by the documentation of a specific implementation. */ + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ typedef struct psa_aead_operation_s psa_aead_operation_t; -/** \def PSA_AEAD_OPERATION_INIT - * - * This macro returns a suitable initializer for an AEAD operation object of - * type #psa_aead_operation_t. - */ -#ifdef __DOXYGEN_ONLY__ -/* This is an example definition for documentation purposes. - * Implementations should define a suitable value in `crypto_struct.h`. - */ -#define PSA_AEAD_OPERATION_INIT {0} -#endif - /** Return an initial value for an AEAD operation object. */ static psa_aead_operation_t psa_aead_operation_init(void); @@ -2551,10 +2543,18 @@ psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, * \param input_length Size of the \p input buffer in bytes. * \param[out] output Buffer where the output is to be written. * \param output_size Size of the \p output buffer in bytes. - * This must be at least - * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c alg, - * \p input_length) where \c alg is the - * algorithm that is being calculated. + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, + * \c alg, \p input_length) where + * \c key_type is the type of key and \c alg is + * the algorithm that were used to set up the + * operation. + * - #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p + * input_length) evaluates to the maximum + * output size of any supported AEAD + * algorithm. * \param[out] output_length On success, the number of bytes * that make up the returned output. * @@ -2565,9 +2565,9 @@ psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, * set, and have lengths set if required by the algorithm). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. - * You can determine a sufficient buffer size by calling - * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c alg, \p input_length) - * where \c alg is the algorithm that is being calculated. + * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, \c alg, \p input_length) or + * #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length) can be used to + * determine the required buffer size. * \retval #PSA_ERROR_INVALID_ARGUMENT * The total length of input to psa_aead_update_ad() so far is * less than the additional data length that was previously @@ -2604,9 +2604,7 @@ psa_status_t psa_aead_update(psa_aead_operation_t *operation, * This function has two output buffers: * - \p ciphertext contains trailing ciphertext that was buffered from * preceding calls to psa_aead_update(). - * - \p tag contains the authentication tag. Its length is always - * #PSA_AEAD_TAG_LENGTH(\c alg) where \c alg is the AEAD algorithm - * that the operation performs. + * - \p tag contains the authentication tag. * * When this function returns successfuly, the operation becomes inactive. * If this function returns an error status, the operation enters an error @@ -2616,18 +2614,32 @@ psa_status_t psa_aead_update(psa_aead_operation_t *operation, * \param[out] ciphertext Buffer where the last part of the ciphertext * is to be written. * \param ciphertext_size Size of the \p ciphertext buffer in bytes. - * This must be at least - * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c alg) where - * \c alg is the algorithm that is being - * calculated. + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, + * \c alg) where \c key_type is the type of key + * and \c alg is the algorithm that were used to + * set up the operation. + * - #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE evaluates to + * the maximum output size of any supported AEAD + * algorithm. * \param[out] ciphertext_length On success, the number of bytes of * returned ciphertext. * \param[out] tag Buffer where the authentication tag is * to be written. * \param tag_size Size of the \p tag buffer in bytes. - * This must be at least - * #PSA_AEAD_TAG_LENGTH(\c alg) where \c alg is - * the algorithm that is being calculated. + * This must be appropriate for the selected + * algorithm and key: + * - The exact tag size is #PSA_AEAD_TAG_LENGTH(\c + * key_type, \c key_bits, \c alg) where + * \c key_type and \c key_bits are the type and + * bit-size of the key, and \c alg is the + * algorithm that were used in the call to + * psa_aead_encrypt_setup(). + * - #PSA_AEAD_TAG_MAX_SIZE evaluates to the + * maximum tag size of any supported AEAD + * algorithm. * \param[out] tag_length On success, the number of bytes * that make up the returned tag. * @@ -2638,11 +2650,11 @@ psa_status_t psa_aead_update(psa_aead_operation_t *operation, * operation with a nonce set). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p ciphertext or \p tag buffer is too small. - * You can determine a sufficient buffer size for \p ciphertext by - * calling #PSA_AEAD_FINISH_OUTPUT_SIZE(\c alg) - * where \c alg is the algorithm that is being calculated. - * You can determine a sufficient buffer size for \p tag by - * calling #PSA_AEAD_TAG_LENGTH(\c alg). + * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, \c alg) or + * #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE can be used to determine the + * required \p ciphertext buffer size. #PSA_AEAD_TAG_LENGTH(\c key_type, + * \c key_bits, \c alg) or #PSA_AEAD_TAG_MAX_SIZE can be used to + * determine the required \p tag buffer size. * \retval #PSA_ERROR_INVALID_ARGUMENT * The total length of input to psa_aead_update_ad() so far is * less than the additional data length that was previously @@ -2701,10 +2713,15 @@ psa_status_t psa_aead_finish(psa_aead_operation_t *operation, * that could not be processed until the end * of the input. * \param plaintext_size Size of the \p plaintext buffer in bytes. - * This must be at least - * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c alg) where - * \c alg is the algorithm that is being - * calculated. + * This must be appropriate for the selected algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, + * \c alg) where \c key_type is the type of key + * and \c alg is the algorithm that were used to + * set up the operation. + * - #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE evaluates to + * the maximum output size of any supported AEAD + * algorithm. * \param[out] plaintext_length On success, the number of bytes of * returned plaintext. * \param[in] tag Buffer containing the authentication tag. @@ -2720,9 +2737,9 @@ psa_status_t psa_aead_finish(psa_aead_operation_t *operation, * operation with a nonce set). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p plaintext buffer is too small. - * You can determine a sufficient buffer size for \p plaintext by - * calling #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c alg) - * where \c alg is the algorithm that is being calculated. + * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, \c alg) or + * #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE can be used to determine the + * required buffer size. * \retval #PSA_ERROR_INVALID_ARGUMENT * The total length of input to psa_aead_update_ad() so far is * less than the additional data length that was previously @@ -2781,12 +2798,130 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation); * @{ */ +/** + * \brief Sign a message with a private key. For hash-and-sign algorithms, + * this includes the hashing step. + * + * \note To perform a multi-part hash-and-sign signature algorithm, first use + * a multi-part hash operation and then pass the resulting hash to + * psa_sign_hash(). PSA_ALG_GET_HASH(\p alg) can be used to determine the + * hash algorithm to use. + * + * \param[in] key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. The key must + * allow the usage #PSA_KEY_USAGE_SIGN_MESSAGE. + * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg) + * is true), that is compatible with the type of + * \p key. + * \param[in] input The input message to sign. + * \param[in] input_length Size of the \p input buffer in bytes. + * \param[out] signature Buffer where the signature is to be written. + * \param[in] signature_size Size of the \p signature buffer in bytes. This + * must be appropriate for the selected + * algorithm and key: + * - The required signature size is + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and + * bit-size respectively of key. + * - #PSA_SIGNATURE_MAX_SIZE evaluates to the + * maximum signature size of any supported + * signature algorithm. + * \param[out] signature_length On success, the number of bytes that make up + * the returned signature value. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, + * or it does not permit the requested algorithm. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p signature buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_sign_message( psa_key_id_t key, + psa_algorithm_t alg, + const uint8_t * input, + size_t input_length, + uint8_t * signature, + size_t signature_size, + size_t * signature_length ); + +/** \brief Verify the signature of a message with a public key, using + * a hash-and-sign verification algorithm. + * + * \note To perform a multi-part hash-and-sign signature verification + * algorithm, first use a multi-part hash operation to hash the message + * and then pass the resulting hash to psa_verify_hash(). + * PSA_ALG_GET_HASH(\p alg) can be used to determine the hash algorithm + * to use. + * + * \param[in] key Identifier of the key to use for the operation. + * It must be a public key or an asymmetric key + * pair. The key must allow the usage + * #PSA_KEY_USAGE_VERIFY_MESSAGE. + * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg) + * is true), that is compatible with the type of + * \p key. + * \param[in] input The message whose signature is to be verified. + * \param[in] input_length Size of the \p input buffer in bytes. + * \param[out] signature Buffer containing the signature to verify. + * \param[in] signature_length Size of the \p signature buffer in bytes. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, + * or it does not permit the requested algorithm. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculation was performed successfully, but the passed signature + * is not a valid signature. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_verify_message( psa_key_id_t key, + psa_algorithm_t alg, + const uint8_t * input, + size_t input_length, + const uint8_t * signature, + size_t signature_length ); + /** * \brief Sign a hash or short message with a private key. * * Note that to perform a hash-and-sign signature algorithm, you must * first calculate the hash by calling psa_hash_setup(), psa_hash_update() - * and psa_hash_finish(). Then pass the resulting hash as the \p hash + * and psa_hash_finish(), or alternatively by calling psa_hash_compute(). + * Then pass the resulting hash as the \p hash * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) * to determine the hash algorithm to use. * @@ -2833,11 +2968,12 @@ psa_status_t psa_sign_hash(psa_key_id_t key, size_t *signature_length); /** - * \brief Verify the signature a hash or short message using a public key. + * \brief Verify the signature of a hash or short message using a public key. * * Note that to perform a hash-and-sign signature algorithm, you must * first calculate the hash by calling psa_hash_setup(), psa_hash_update() - * and psa_hash_finish(). Then pass the resulting hash as the \p hash + * and psa_hash_finish(), or alternatively by calling psa_hash_compute(). + * Then pass the resulting hash as the \p hash * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) * to determine the hash algorithm to use. * @@ -3033,23 +3169,11 @@ psa_status_t psa_asymmetric_decrypt(psa_key_id_t key, * \endcode * * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure except - * as directed by the documentation of a specific implementation. + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ typedef struct psa_key_derivation_s psa_key_derivation_operation_t; -/** \def PSA_KEY_DERIVATION_OPERATION_INIT - * - * This macro returns a suitable initializer for a key derivation operation - * object of type #psa_key_derivation_operation_t. - */ -#ifdef __DOXYGEN_ONLY__ -/* This is an example definition for documentation purposes. - * Implementations should define a suitable value in `crypto_struct.h`. - */ -#define PSA_KEY_DERIVATION_OPERATION_INIT {0} -#endif - /** Return an initial value for a key derivation operation object. */ static psa_key_derivation_operation_t psa_key_derivation_operation_init(void); @@ -3227,6 +3351,50 @@ psa_status_t psa_key_derivation_input_bytes( const uint8_t *data, size_t data_length); +/** Provide a numeric input for key derivation or key agreement. + * + * Which inputs are required and in what order depends on the algorithm. + * However, when an algorithm requires a particular order, numeric inputs + * usually come first as they tend to be configuration parameters. + * Refer to the documentation of each key derivation or key agreement + * algorithm for information. + * + * This function is used for inputs which are fixed-size non-negative + * integers. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to use. + * It must have been set up with + * psa_key_derivation_setup() and must not + * have produced any output yet. + * \param step Which step the input data is for. + * \param[in] value The value of the numeric input. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step is not compatible with the operation's algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step does not allow numeric inputs. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid for this input \p step. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_input_integer( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + uint64_t value); + /** Provide an input for key derivation in the form of a key. * * Which inputs are required and in what order depends on the algorithm. @@ -3251,12 +3419,29 @@ psa_status_t psa_key_derivation_input_bytes( * \param step Which step the input data is for. * \param key Identifier of the key. It must have an * appropriate type for step and must allow the - * usage #PSA_KEY_USAGE_DERIVE. + * usage #PSA_KEY_USAGE_DERIVE or + * #PSA_KEY_USAGE_VERIFY_DERIVATION (see note) + * and the algorithm used by the operation. + * + * \note Once all inputs steps are completed, the operations will allow: + * - psa_key_derivation_output_bytes() if each input was either a direct input + * or a key with #PSA_KEY_USAGE_DERIVE set; + * - psa_key_derivation_output_key() if the input for step + * #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD + * was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was + * either a direct input or a key with #PSA_KEY_USAGE_DERIVE set; + * - psa_key_derivation_verify_bytes() if each input was either a direct input + * or a key with #PSA_KEY_USAGE_VERIFY_DERIVATION set; + * - psa_key_derivation_verify_key() under the same conditions as + * psa_key_derivation_verify_bytes(). * * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED + * The key allows neither #PSA_KEY_USAGE_DERIVE nor + * #PSA_KEY_USAGE_VERIFY_DERIVATION, or it doesn't allow this + * algorithm. * \retval #PSA_ERROR_INVALID_ARGUMENT * \c step is not compatible with the operation's algorithm. * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -3369,6 +3554,9 @@ psa_status_t psa_key_derivation_key_agreement( * \param output_length Number of bytes to output. * * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_NOT_PERMITTED + * One of the inputs was a key whose policy didn't allow + * #PSA_KEY_USAGE_DERIVE. * \retval #PSA_ERROR_INSUFFICIENT_DATA * The operation's capacity was less than * \p output_length bytes. Note that in this case, @@ -3411,7 +3599,8 @@ psa_status_t psa_key_derivation_output_bytes( * state and must be aborted by calling psa_key_derivation_abort(). * * How much output is produced and consumed from the operation, and how - * the key is derived, depends on the key type: + * the key is derived, depends on the key type and on the key size + * (denoted \c bits below): * * - For key types for which the key is an arbitrary sequence of bytes * of a given size, this function is functionally equivalent to @@ -3421,14 +3610,14 @@ psa_status_t psa_key_derivation_output_bytes( * if the implementation provides an isolation boundary then * the key material is not exposed outside the isolation boundary. * As a consequence, for these key types, this function always consumes - * exactly (\p bits / 8) bytes from the operation. + * exactly (\c bits / 8) bytes from the operation. * The following key types defined in this specification follow this scheme: * * - #PSA_KEY_TYPE_AES; - * - #PSA_KEY_TYPE_ARC4; * - #PSA_KEY_TYPE_CAMELLIA; * - #PSA_KEY_TYPE_DERIVE; - * - #PSA_KEY_TYPE_HMAC. + * - #PSA_KEY_TYPE_HMAC; + * - #PSA_KEY_TYPE_PASSWORD_HASH. * * - For ECC keys on a Montgomery elliptic curve * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a @@ -3442,8 +3631,8 @@ psa_status_t psa_key_derivation_output_bytes( * string and process it as specified in RFC 7748 §5. * * - For key types for which the key is represented by a single sequence of - * \p bits bits with constraints as to which bit sequences are acceptable, - * this function draws a byte string of length (\p bits / 8) bytes rounded + * \c bits bits with constraints as to which bit sequences are acceptable, + * this function draws a byte string of length (\c bits / 8) bytes rounded * up to the nearest whole number of bytes. If the resulting byte string * is acceptable, it becomes the key, otherwise the drawn bytes are discarded. * This process is repeated until an acceptable byte string is drawn. @@ -3490,6 +3679,10 @@ psa_status_t psa_key_derivation_output_bytes( * on the derived key based on the attributes and strength of the secret key. * * \param[in] attributes The attributes for the new key. + * If the key type to be created is + * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in + * the policy must be the same as in the current + * operation. * \param[in,out] operation The key derivation operation object to read from. * \param[out] key On success, an identifier for the newly created * key. For persistent keys, this is the key @@ -3514,8 +3707,10 @@ psa_status_t psa_key_derivation_output_bytes( * \retval #PSA_ERROR_INVALID_ARGUMENT * The provided key attributes are not valid for the operation. * \retval #PSA_ERROR_NOT_PERMITTED - * The #PSA_KEY_DERIVATION_INPUT_SECRET input was not provided through - * a key. + * The #PSA_KEY_DERIVATION_INPUT_SECRET or + * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a + * key; or one of the inputs was a key whose policy didn't allow + * #PSA_KEY_USAGE_DERIVE. * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active and completed * all required input steps). @@ -3524,6 +3719,8 @@ psa_status_t psa_key_derivation_output_bytes( * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). @@ -3535,6 +3732,129 @@ psa_status_t psa_key_derivation_output_key( psa_key_derivation_operation_t *operation, psa_key_id_t *key); +/** Compare output data from a key derivation operation to an expected value. + * + * This function calculates output bytes from a key derivation algorithm and + * compares those bytes to an expected value in constant time. + * If you view the key derivation's output as a stream of bytes, this + * function destructively reads the expected number of bytes from the + * stream before comparing them. + * The operation's capacity decreases by the number of bytes read. + * + * This is functionally equivalent to the following code: + * \code + * psa_key_derivation_output_bytes(operation, tmp, output_length); + * if (memcmp(output, tmp, output_length) != 0) + * return PSA_ERROR_INVALID_SIGNATURE; + * \endcode + * except (1) it works even if the key's policy does not allow outputting the + * bytes, and (2) the comparison will be done in constant time. + * + * If this function returns an error status other than + * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE, + * the operation enters an error state and must be aborted by calling + * psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to read from. + * \param[in] expected_output Buffer containing the expected derivation output. + * \param output_length Length ot the expected output; this is also the + * number of bytes that will be read. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The output was read successfully, but it differs from the expected + * output. + * \retval #PSA_ERROR_NOT_PERMITTED + * One of the inputs was a key whose policy didn't allow + * #PSA_KEY_USAGE_VERIFY_DERIVATION. + * \retval #PSA_ERROR_INSUFFICIENT_DATA + * The operation's capacity was less than + * \p output_length bytes. Note that in this case, + * the operation's capacity is set to 0, thus + * subsequent calls to this function will not + * succeed, even with a smaller expected output. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_verify_bytes( + psa_key_derivation_operation_t *operation, + const uint8_t *expected_output, + size_t output_length); + +/** Compare output data from a key derivation operation to an expected value + * stored in a key object. + * + * This function calculates output bytes from a key derivation algorithm and + * compares those bytes to an expected value, provided as key of type + * #PSA_KEY_TYPE_PASSWORD_HASH. + * If you view the key derivation's output as a stream of bytes, this + * function destructively reads the number of bytes corresponding the the + * length of the expected value from the stream before comparing them. + * The operation's capacity decreases by the number of bytes read. + * + * This is functionally equivalent to exporting the key and calling + * psa_key_derivation_verify_bytes() on the result, except that it + * works even if the key cannot be exported. + * + * If this function returns an error status other than + * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE, + * the operation enters an error state and must be aborted by calling + * psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to read from. + * \param[in] expected A key of type #PSA_KEY_TYPE_PASSWORD_HASH + * containing the expected output. Its policy must + * include the #PSA_KEY_USAGE_VERIFY_DERIVATION flag + * and the permitted algorithm must match the + * operation. The value of this key was likely + * computed by a previous call to + * psa_key_derivation_output_key(). + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The output was read successfully, but if differs from the expected + * output. + * \retval #PSA_ERROR_INVALID_HANDLE + * The key passed as the expected value does not exist. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key passed as the expected value has an invalid type. + * \retval #PSA_ERROR_NOT_PERMITTED + * The key passed as the expected value does not allow this usage or + * this algorithm; or one of the inputs was a key whose policy didn't + * allow #PSA_KEY_USAGE_VERIFY_DERIVATION. + * \retval #PSA_ERROR_INSUFFICIENT_DATA + * The operation's capacity was less than + * the length of the expected value. In this case, + * the operation's capacity is set to 0, thus + * subsequent calls to this function will not + * succeed, even with a smaller expected output. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_verify_key( + psa_key_derivation_operation_t *operation, + psa_key_id_t expected); + /** Abort a key derivation operation. * * Aborting an operation frees all associated resources except for the \c @@ -3689,6 +4009,8 @@ psa_status_t psa_generate_random(uint8_t *output, * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_client_struct.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_client_struct.h index 98f7bfe678a..bf95c9821e5 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_client_struct.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_client_struct.h @@ -31,12 +31,12 @@ extern "C" { * data structure internally. */ struct psa_client_key_attributes_s { + uint16_t type; + uint16_t bits; uint32_t lifetime; psa_key_id_t id; - uint32_t alg; uint32_t usage; - size_t bits; - uint16_t type; + uint32_t alg; }; #define PSA_CLIENT_KEY_ATTRIBUTES_INIT {0, 0, 0, 0, 0, 0} diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_compat.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_compat.h index 8ca1f6a6879..9a7de899f1e 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_compat.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_compat.h @@ -43,197 +43,6 @@ static inline int psa_key_handle_is_null(psa_key_handle_t handle) return(handle == 0); } -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - -/* - * Mechanism for declaring deprecated values - */ -#if defined(MBEDTLS_DEPRECATED_WARNING) && !defined(MBEDTLS_PSA_DEPRECATED) -#define MBEDTLS_PSA_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_PSA_DEPRECATED -#endif - -typedef MBEDTLS_PSA_DEPRECATED size_t mbedtls_deprecated_size_t; -typedef MBEDTLS_PSA_DEPRECATED psa_status_t mbedtls_deprecated_psa_status_t; -typedef MBEDTLS_PSA_DEPRECATED psa_key_usage_t mbedtls_deprecated_psa_key_usage_t; -typedef MBEDTLS_PSA_DEPRECATED psa_ecc_family_t mbedtls_deprecated_psa_ecc_family_t; -typedef MBEDTLS_PSA_DEPRECATED psa_dh_family_t mbedtls_deprecated_psa_dh_family_t; -typedef MBEDTLS_PSA_DEPRECATED psa_ecc_family_t psa_ecc_curve_t; -typedef MBEDTLS_PSA_DEPRECATED psa_dh_family_t psa_dh_group_t; -typedef MBEDTLS_PSA_DEPRECATED psa_algorithm_t mbedtls_deprecated_psa_algorithm_t; - -#define PSA_KEY_TYPE_GET_CURVE PSA_KEY_TYPE_ECC_GET_FAMILY -#define PSA_KEY_TYPE_GET_GROUP PSA_KEY_TYPE_DH_GET_FAMILY - -#define MBEDTLS_DEPRECATED_CONSTANT( type, value ) \ - ( (mbedtls_deprecated_##type) ( value ) ) - -/* - * Deprecated PSA Crypto error code definitions (PSA Crypto API <= 1.0 beta2) - */ -#define PSA_ERROR_UNKNOWN_ERROR \ - MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_GENERIC_ERROR ) -#define PSA_ERROR_OCCUPIED_SLOT \ - MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_ALREADY_EXISTS ) -#define PSA_ERROR_EMPTY_SLOT \ - MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_DOES_NOT_EXIST ) -#define PSA_ERROR_INSUFFICIENT_CAPACITY \ - MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_INSUFFICIENT_DATA ) -#define PSA_ERROR_TAMPERING_DETECTED \ - MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_CORRUPTION_DETECTED ) - -/* - * Deprecated PSA Crypto numerical encodings (PSA Crypto API <= 1.0 beta3) - */ -#define PSA_KEY_USAGE_SIGN \ - MBEDTLS_DEPRECATED_CONSTANT( psa_key_usage_t, PSA_KEY_USAGE_SIGN_HASH ) -#define PSA_KEY_USAGE_VERIFY \ - MBEDTLS_DEPRECATED_CONSTANT( psa_key_usage_t, PSA_KEY_USAGE_VERIFY_HASH ) - -/* - * Deprecated PSA Crypto size calculation macros (PSA Crypto API <= 1.0 beta3) - */ -#define PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE \ - MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_SIGNATURE_MAX_SIZE ) -#define PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type, key_bits, alg ) \ - MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_SIGN_OUTPUT_SIZE( key_type, key_bits, alg ) ) - -/* - * Deprecated PSA Crypto function names (PSA Crypto API <= 1.0 beta3) - */ -MBEDTLS_PSA_DEPRECATED psa_status_t psa_asymmetric_sign( psa_key_handle_t key, - psa_algorithm_t alg, - const uint8_t *hash, - size_t hash_length, - uint8_t *signature, - size_t signature_size, - size_t *signature_length ); - -MBEDTLS_PSA_DEPRECATED psa_status_t psa_asymmetric_verify( psa_key_handle_t key, - psa_algorithm_t alg, - const uint8_t *hash, - size_t hash_length, - const uint8_t *signature, - size_t signature_length ); - - -/* - * Size-specific elliptic curve families. - */ -#define PSA_ECC_CURVE_SECP160K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_K1 ) -#define PSA_ECC_CURVE_SECP192K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_K1 ) -#define PSA_ECC_CURVE_SECP224K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_K1 ) -#define PSA_ECC_CURVE_SECP256K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_K1 ) -#define PSA_ECC_CURVE_SECP160R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) -#define PSA_ECC_CURVE_SECP192R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) -#define PSA_ECC_CURVE_SECP224R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) -#define PSA_ECC_CURVE_SECP256R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) -#define PSA_ECC_CURVE_SECP384R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) -#define PSA_ECC_CURVE_SECP521R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) -#define PSA_ECC_CURVE_SECP160R2 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R2 ) -#define PSA_ECC_CURVE_SECT163K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) -#define PSA_ECC_CURVE_SECT233K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) -#define PSA_ECC_CURVE_SECT239K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) -#define PSA_ECC_CURVE_SECT283K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) -#define PSA_ECC_CURVE_SECT409K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) -#define PSA_ECC_CURVE_SECT571K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) -#define PSA_ECC_CURVE_SECT163R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) -#define PSA_ECC_CURVE_SECT193R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) -#define PSA_ECC_CURVE_SECT233R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) -#define PSA_ECC_CURVE_SECT283R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) -#define PSA_ECC_CURVE_SECT409R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) -#define PSA_ECC_CURVE_SECT571R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) -#define PSA_ECC_CURVE_SECT163R2 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R2 ) -#define PSA_ECC_CURVE_SECT193R2 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R2 ) -#define PSA_ECC_CURVE_BRAINPOOL_P256R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_BRAINPOOL_P_R1 ) -#define PSA_ECC_CURVE_BRAINPOOL_P384R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_BRAINPOOL_P_R1 ) -#define PSA_ECC_CURVE_BRAINPOOL_P512R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_BRAINPOOL_P_R1 ) -#define PSA_ECC_CURVE_CURVE25519 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_MONTGOMERY ) -#define PSA_ECC_CURVE_CURVE448 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_MONTGOMERY ) - -/* - * Curves that changed name due to PSA specification. - */ -#define PSA_ECC_CURVE_SECP_K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_K1 ) -#define PSA_ECC_CURVE_SECP_R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) -#define PSA_ECC_CURVE_SECP_R2 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R2 ) -#define PSA_ECC_CURVE_SECT_K1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) -#define PSA_ECC_CURVE_SECT_R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) -#define PSA_ECC_CURVE_SECT_R2 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R2 ) -#define PSA_ECC_CURVE_BRAINPOOL_P_R1 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_BRAINPOOL_P_R1 ) -#define PSA_ECC_CURVE_MONTGOMERY \ - MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_MONTGOMERY ) - -/* - * Finite-field Diffie-Hellman families. - */ -#define PSA_DH_GROUP_FFDHE2048 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) -#define PSA_DH_GROUP_FFDHE3072 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) -#define PSA_DH_GROUP_FFDHE4096 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) -#define PSA_DH_GROUP_FFDHE6144 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) -#define PSA_DH_GROUP_FFDHE8192 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) - -/* - * Diffie-Hellman families that changed name due to PSA specification. - */ -#define PSA_DH_GROUP_RFC7919 \ - MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) -#define PSA_DH_GROUP_CUSTOM \ - MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_CUSTOM ) - -/* - * Deprecated PSA Crypto stream cipher algorithms (PSA Crypto API <= 1.0 beta3) - */ -#define PSA_ALG_ARC4 \ - MBEDTLS_DEPRECATED_CONSTANT(psa_algorithm_t, PSA_ALG_STREAM_CIPHER) -#define PSA_ALG_CHACHA20 \ - MBEDTLS_DEPRECATED_CONSTANT(psa_algorithm_t, PSA_ALG_STREAM_CIPHER) - -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - /** Open a handle to an existing persistent key. * * Open a handle to a persistent key. A key is persistent if it was created @@ -287,6 +96,8 @@ MBEDTLS_PSA_DEPRECATED psa_status_t psa_asymmetric_verify( psa_key_handle_t key, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_sizes.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_sizes.h index 4d13e412af6..1e282e26c1a 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_sizes.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_sizes.h @@ -47,13 +47,9 @@ * * \return The hash size for the specified hash algorithm. * If the hash algorithm is not recognized, return 0. - * An implementation may return either 0 or the correct size - * for a hash algorithm that it recognizes, but does not support. */ -#define PSA_HASH_SIZE(alg) \ - ( \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 16 : \ +#define PSA_HASH_LENGTH(alg) \ + ( \ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16 : \ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 : \ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20 : \ @@ -73,23 +69,26 @@ * * Maximum size of a hash. * - * This macro must expand to a compile-time constant integer. This value - * should be the maximum size of a hash supported by the implementation, - * in bytes, and must be no smaller than this maximum. + * This macro expands to a compile-time constant integer. This value + * is the maximum size of a hash in bytes. */ /* Note: for HMAC-SHA-3, the block size is 144 bytes for HMAC-SHA3-226, * 136 bytes for HMAC-SHA3-256, 104 bytes for SHA3-384, 72 bytes for * HMAC-SHA3-512. */ +#if defined(MBEDTLS_SHA512_C) #define PSA_HASH_MAX_SIZE 64 #define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128 +#else +#define PSA_HASH_MAX_SIZE 32 +#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64 +#endif /** \def PSA_MAC_MAX_SIZE * * Maximum size of a MAC. * - * This macro must expand to a compile-time constant integer. This value - * should be the maximum size of a MAC supported by the implementation, - * in bytes, and must be no smaller than this maximum. + * This macro expands to a compile-time constant integer. This value + * is the maximum size of a MAC in bytes. */ /* All non-HMAC MACs have a maximum size that's smaller than the * minimum possible value of PSA_HASH_MAX_SIZE in this implementation. */ @@ -98,25 +97,37 @@ */ #define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE -/** The tag size for an AEAD algorithm, in bytes. +/** The length of a tag for an AEAD algorithm, in bytes. * + * This macro can be used to allocate a buffer of sufficient size to store the + * tag output from psa_aead_finish(). + * + * See also #PSA_AEAD_TAG_MAX_SIZE. + * + * \param key_type The type of the AEAD key. + * \param key_bits The size of the AEAD key in bits. * \param alg An AEAD algorithm * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). * - * \return The tag size for the specified algorithm. + * \return The tag length for the specified algorithm and key. * If the AEAD algorithm does not have an identified * tag that can be distinguished from the rest of * the ciphertext, return 0. - * If the AEAD algorithm is not recognized, return 0. - * An implementation may return either 0 or a - * correct size for an AEAD algorithm that it - * recognizes, but does not support. - */ -#define PSA_AEAD_TAG_LENGTH(alg) \ - (PSA_ALG_IS_AEAD(alg) ? \ - (((alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> PSA_AEAD_TAG_LENGTH_OFFSET) : \ - 0) + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ + PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \ + ((void) (key_bits), 0)) + +/** The maximum tag size for all supported AEAD algorithms, in bytes. + * + * See also #PSA_AEAD_TAG_LENGTH(\p key_type, \p key_bits, \p alg). + */ +#define PSA_AEAD_TAG_MAX_SIZE 16 /* The maximum size of an RSA key on this implementation, in bits. * This is a vendor-specific macro. @@ -136,10 +147,11 @@ /* The maximum size of an ECC key on this implementation, in bits */ #define PSA_VENDOR_ECC_MAX_CURVE_BITS 521 -/** \def PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN +/** This macro returns the maximum supported length of the PSK for the + * TLS-1.2 PSK-to-MS key derivation + * (#PSA_ALG_TLS12_PSK_TO_MS(\c hash_alg)). * - * This macro returns the maximum length of the PSK supported - * by the TLS-1.2 PSK-to-MS key derivation. + * The maximum supported length does not depend on the chosen hash algorithm. * * Quoting RFC 4279, Sect 5.3: * TLS implementations supporting these ciphersuites MUST support @@ -148,17 +160,21 @@ * keys is RECOMMENDED. * * Therefore, no implementation should define a value smaller than 64 - * for #PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN. + * for #PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE. */ -#define PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN 128 +#define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE 128 -/** The maximum size of a block cipher supported by the implementation. */ -#define PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE 16 +/** The maximum size of a block cipher. */ +#define PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE 16 /** The size of the output of psa_mac_sign_finish(), in bytes. * * This is also the MAC size that psa_mac_verify_finish() expects. * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * * \param key_type The type of the MAC key. * \param key_bits The size of the MAC key in bits. * \param alg A MAC algorithm (\c PSA_ALG_XXX value such that @@ -172,10 +188,10 @@ * \return Unspecified if the key parameters are not consistent * with the algorithm. */ -#define PSA_MAC_FINAL_SIZE(key_type, key_bits, alg) \ - ((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \ - PSA_ALG_IS_HMAC(alg) ? PSA_HASH_SIZE(PSA_ALG_HMAC_GET_HASH(alg)) : \ - PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \ +#define PSA_MAC_LENGTH(key_type, key_bits, alg) \ + ((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \ + PSA_ALG_IS_HMAC(alg) ? PSA_HASH_LENGTH(PSA_ALG_HMAC_GET_HASH(alg)) : \ + PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ ((void)(key_type), (void)(key_bits), 0)) /** The maximum size of the output of psa_aead_encrypt(), in bytes. @@ -185,6 +201,14 @@ * insufficient buffer size. Depending on the algorithm, the actual size of * the ciphertext may be smaller. * + * See also #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is + * compatible with algorithm \p alg. * \param alg An AEAD algorithm * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). @@ -192,16 +216,37 @@ * * \return The AEAD ciphertext size for the specified * algorithm. - * If the AEAD algorithm is not recognized, return 0. - * An implementation may return either 0 or a - * correct size for an AEAD algorithm that it - * recognizes, but does not support. - */ -#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) \ - (PSA_AEAD_TAG_LENGTH(alg) != 0 ? \ - (plaintext_length) + PSA_AEAD_TAG_LENGTH(alg) : \ + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, plaintext_length) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ + (plaintext_length) + PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \ 0) +/** A sufficient output buffer size for psa_aead_encrypt(), for any of the + * supported key types and AEAD algorithms. + * + * If the size of the ciphertext buffer is at least this large, it is guaranteed + * that psa_aead_encrypt() will not fail due to an insufficient buffer size. + * + * \note This macro returns a compile-time constant if its arguments are + * compile-time constants. + * + * See also #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\p key_type, \p alg, + * \p plaintext_length). + * + * \param plaintext_length Size of the plaintext in bytes. + * + * \return A sufficient output buffer size for any of the + * supported key types and AEAD algorithms. + * + */ +#define PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(plaintext_length) \ + ((plaintext_length) + PSA_AEAD_TAG_MAX_SIZE) + + /** The maximum size of the output of psa_aead_decrypt(), in bytes. * * If the size of the plaintext buffer is at least this large, it is @@ -209,6 +254,14 @@ * insufficient buffer size. Depending on the algorithm, the actual size of * the plaintext may be smaller. * + * See also #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is + * compatible with algorithm \p alg. * \param alg An AEAD algorithm * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). @@ -216,16 +269,84 @@ * * \return The AEAD ciphertext size for the specified * algorithm. - * If the AEAD algorithm is not recognized, return 0. - * An implementation may return either 0 or a - * correct size for an AEAD algorithm that it - * recognizes, but does not support. - */ -#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \ - (PSA_AEAD_TAG_LENGTH(alg) != 0 ? \ - (ciphertext_length) - PSA_AEAD_TAG_LENGTH(alg) : \ + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, ciphertext_length) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ + (ciphertext_length) > PSA_ALG_AEAD_GET_TAG_LENGTH(alg) ? \ + (ciphertext_length) - PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \ 0) +/** A sufficient output buffer size for psa_aead_decrypt(), for any of the + * supported key types and AEAD algorithms. + * + * If the size of the plaintext buffer is at least this large, it is guaranteed + * that psa_aead_decrypt() will not fail due to an insufficient buffer size. + * + * \note This macro returns a compile-time constant if its arguments are + * compile-time constants. + * + * See also #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\p key_type, \p alg, + * \p ciphertext_length). + * + * \param ciphertext_length Size of the ciphertext in bytes. + * + * \return A sufficient output buffer size for any of the + * supported key types and AEAD algorithms. + * + */ +#define PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(ciphertext_length) \ + (ciphertext_length) + +/** The default nonce size for an AEAD algorithm, in bytes. + * + * This macro can be used to allocate a buffer of sufficient size to + * store the nonce output from #psa_aead_generate_nonce(). + * + * See also #PSA_AEAD_NONCE_MAX_SIZE. + * + * \note This is not the maximum size of nonce supported as input to + * #psa_aead_set_nonce(), #psa_aead_encrypt() or #psa_aead_decrypt(), + * just the default size that is generated by #psa_aead_generate_nonce(). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is compatible with + * algorithm \p alg. + * + * \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \return The default nonce size for the specified key type and algorithm. + * If the key type or AEAD algorithm is not recognized, + * or the parameters are incompatible, return 0. + */ +#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \ + (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) == 16 ? \ + MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CCM) ? 13 : \ + MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_GCM) ? 12 : \ + 0 : \ + (key_type) == PSA_KEY_TYPE_CHACHA20 && \ + MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CHACHA20_POLY1305) ? 12 : \ + 0) + +/** The maximum default nonce size among all supported pairs of key types and + * AEAD algorithms, in bytes. + * + * This is equal to or greater than any value that #PSA_AEAD_NONCE_LENGTH() + * may return. + * + * \note This is not the maximum size of nonce supported as input to + * #psa_aead_set_nonce(), #psa_aead_encrypt() or #psa_aead_decrypt(), + * just the largest size that may be generated by + * #psa_aead_generate_nonce(). + */ +#define PSA_AEAD_NONCE_MAX_SIZE 13 + /** A sufficient output buffer size for psa_aead_update(). * * If the size of the output buffer is at least this large, it is @@ -233,6 +354,14 @@ * insufficient buffer size. The actual size of the output may be smaller * in any given call. * + * See also #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is + * compatible with algorithm \p alg. * \param alg An AEAD algorithm * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). @@ -240,19 +369,33 @@ * * \return A sufficient output buffer size for the specified * algorithm. - * If the AEAD algorithm is not recognized, return 0. - * An implementation may return either 0 or a - * correct size for an AEAD algorithm that it - * recognizes, but does not support. + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. */ /* For all the AEAD modes defined in this specification, it is possible * to emit output without delay. However, hardware may not always be * capable of this. So for modes based on a block cipher, allow the * implementation to delay the output until it has a full block. */ -#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \ - (PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ - PSA_ROUND_UP_TO_MULTIPLE(PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE, (input_length)) : \ - (input_length)) +#define PSA_AEAD_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ + PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ + PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), (input_length)) : \ + (input_length) : \ + 0) + +/** A sufficient output buffer size for psa_aead_update(), for any of the + * supported key types and AEAD algorithms. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_aead_update() will not fail due to an insufficient buffer size. + * + * See also #PSA_AEAD_UPDATE_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). + * + * \param input_length Size of the input in bytes. + */ +#define PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(input_length) \ + (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length))) /** A sufficient ciphertext buffer size for psa_aead_finish(). * @@ -261,22 +404,33 @@ * insufficient ciphertext buffer size. The actual size of the output may * be smaller in any given call. * + * See also #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE. + * + * \param key_type A symmetric key type that is + compatible with algorithm \p alg. * \param alg An AEAD algorithm * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). * * \return A sufficient ciphertext buffer size for the * specified algorithm. - * If the AEAD algorithm is not recognized, return 0. - * An implementation may return either 0 or a - * correct size for an AEAD algorithm that it - * recognizes, but does not support. - */ -#define PSA_AEAD_FINISH_OUTPUT_SIZE(alg) \ - (PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ - PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \ + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_AEAD_FINISH_OUTPUT_SIZE(key_type, alg) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ + PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ + PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ 0) +/** A sufficient ciphertext buffer size for psa_aead_finish(), for any of the + * supported key types and AEAD algorithms. + * + * See also #PSA_AEAD_FINISH_OUTPUT_SIZE(\p key_type, \p alg). + */ +#define PSA_AEAD_FINISH_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) + /** A sufficient plaintext buffer size for psa_aead_verify(). * * If the size of the plaintext buffer is at least this large, it is @@ -284,25 +438,36 @@ * insufficient plaintext buffer size. The actual size of the output may * be smaller in any given call. * + * See also #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE. + * + * \param key_type A symmetric key type that is + * compatible with algorithm \p alg. * \param alg An AEAD algorithm * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). * * \return A sufficient plaintext buffer size for the * specified algorithm. - * If the AEAD algorithm is not recognized, return 0. - * An implementation may return either 0 or a - * correct size for an AEAD algorithm that it - * recognizes, but does not support. - */ -#define PSA_AEAD_VERIFY_OUTPUT_SIZE(alg) \ - (PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ - PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \ + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_AEAD_VERIFY_OUTPUT_SIZE(key_type, alg) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ + PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ + PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ 0) +/** A sufficient plaintext buffer size for psa_aead_verify(), for any of the + * supported key types and AEAD algorithms. + * + * See also #PSA_AEAD_VERIFY_OUTPUT_SIZE(\p key_type, \p alg). + */ +#define PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) + #define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \ (PSA_ALG_IS_RSA_OAEP(alg) ? \ - 2 * PSA_HASH_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \ + 2 * PSA_HASH_LENGTH(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \ 11 /*PKCS#1v1.5*/) /** @@ -336,9 +501,8 @@ * a buffer size in bytes that guarantees that * psa_sign_hash() will not fail with * #PSA_ERROR_BUFFER_TOO_SMALL. - * If the parameters are a valid combination that is not supported - * by the implementation, this macro shall return either a - * sensible size or 0. + * If the parameters are a valid combination that is not supported, + * return either a sensible size or 0. * If the parameters are not valid, the * return value is unspecified. */ @@ -354,9 +518,8 @@ * * Maximum size of an asymmetric signature. * - * This macro must expand to a compile-time constant integer. This value - * should be the maximum size of a signature supported by the implementation, - * in bytes, and must be no smaller than this maximum. + * This macro expands to a compile-time constant integer. This value + * is the maximum size of a signature in bytes. */ #define PSA_SIGNATURE_MAX_SIZE \ (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) > PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE ? \ @@ -383,9 +546,8 @@ * a buffer size in bytes that guarantees that * psa_asymmetric_encrypt() will not fail with * #PSA_ERROR_BUFFER_TOO_SMALL. - * If the parameters are a valid combination that is not supported - * by the implementation, this macro shall return either a - * sensible size or 0. + * If the parameters are a valid combination that is not supported, + * return either a sensible size or 0. * If the parameters are not valid, the * return value is unspecified. */ @@ -394,6 +556,15 @@ ((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \ 0) +/** A sufficient output buffer size for psa_asymmetric_encrypt(), for any + * supported asymmetric encryption. + * + * See also #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg). + */ +/* This macro assumes that RSA is the only supported asymmetric encryption. */ +#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE \ + (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS)) + /** Sufficient output buffer size for psa_asymmetric_decrypt(). * * This macro returns a sufficient buffer size for a plaintext produced using @@ -414,9 +585,8 @@ * a buffer size in bytes that guarantees that * psa_asymmetric_decrypt() will not fail with * #PSA_ERROR_BUFFER_TOO_SMALL. - * If the parameters are a valid combination that is not supported - * by the implementation, this macro shall return either a - * sensible size or 0. + * If the parameters are a valid combination that is not supported, + * return either a sensible size or 0. * If the parameters are not valid, the * return value is unspecified. */ @@ -425,6 +595,16 @@ PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) : \ 0) +/** A sufficient output buffer size for psa_asymmetric_decrypt(), for any + * supported asymmetric decryption. + * + * This macro assumes that RSA is the only supported asymmetric encryption. + * + * See also #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg). + */ +#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE \ + (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS)) + /* Maximum size of the ASN.1 encoding of an INTEGER with the specified * number of bits. * @@ -535,12 +715,13 @@ #define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \ (PSA_BITS_TO_BYTES(key_bits)) -/** Sufficient output buffer size for psa_export_key() or psa_export_public_key(). +/** Sufficient output buffer size for psa_export_key() or + * psa_export_public_key(). * * This macro returns a compile-time constant if its arguments are * compile-time constants. * - * \warning This function may call its arguments multiple times or + * \warning This macro may evaluate its arguments multiple times or * zero times, so you should not pass arguments that contain * side effects. * @@ -553,7 +734,7 @@ * if (status != PSA_SUCCESS) handle_error(...); * psa_key_type_t key_type = psa_get_key_type(&attributes); * size_t key_bits = psa_get_key_bits(&attributes); - * size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits); + * size_t buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits); * psa_reset_key_attributes(&attributes); * uint8_t *buffer = malloc(buffer_size); * if (buffer == NULL) handle_error(...); @@ -562,18 +743,46 @@ * if (status != PSA_SUCCESS) handle_error(...); * \endcode * - * For psa_export_public_key(), calculate the buffer size from the - * public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR - * to convert a key pair type to the corresponding public key type. + * \param key_type A supported key type. + * \param key_bits The size of the key in bits. + * + * \return If the parameters are valid and supported, return + * a buffer size in bytes that guarantees that + * psa_export_key() or psa_export_public_key() will not fail with + * #PSA_ERROR_BUFFER_TOO_SMALL. + * If the parameters are a valid combination that is not supported, + * return either a sensible size or 0. + * If the parameters are not valid, the return value is unspecified. + */ +#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \ + (key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \ + (key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + (key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \ + (key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \ + PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + 0) + +/** Sufficient output buffer size for psa_export_public_key(). + * + * This macro returns a compile-time constant if its arguments are + * compile-time constants. + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * The following code illustrates how to allocate enough memory to export + * a public key by querying the key type and size at runtime. * \code{c} * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; * psa_status_t status; * status = psa_get_key_attributes(key, &attributes); * if (status != PSA_SUCCESS) handle_error(...); * psa_key_type_t key_type = psa_get_key_type(&attributes); - * psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); * size_t key_bits = psa_get_key_bits(&attributes); - * size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(public_key_type, key_bits); + * size_t buffer_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits); * psa_reset_key_attributes(&attributes); * uint8_t *buffer = malloc(buffer_size); * if (buffer == NULL) handle_error(...); @@ -582,73 +791,96 @@ * if (status != PSA_SUCCESS) handle_error(...); * \endcode * - * \param key_type A supported key type. - * \param key_bits The size of the key in bits. - * - * \return If the parameters are valid and supported, return - * a buffer size in bytes that guarantees that - * psa_sign_hash() will not fail with - * #PSA_ERROR_BUFFER_TOO_SMALL. - * If the parameters are a valid combination that is not supported - * by the implementation, this macro shall return either a - * sensible size or 0. - * If the parameters are not valid, the - * return value is unspecified. + * \param key_type A public key or key pair key type. + * \param key_bits The size of the key in bits. + * + * \return If the parameters are valid and supported, return + * a buffer size in bytes that guarantees that + * psa_export_public_key() will not fail with + * #PSA_ERROR_BUFFER_TOO_SMALL. + * If the parameters are a valid combination that is not + * supported, return either a sensible size or 0. + * If the parameters are not valid, + * the return value is unspecified. + * + * If the parameters are valid and supported, + * return the same result as + * #PSA_EXPORT_KEY_OUTPUT_SIZE( + * \p #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\p key_type), + * \p key_bits). */ -#define PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits) \ - (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \ - (key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \ - (key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ - (key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \ - (key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ - PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \ - PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ +#define PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_IS_RSA(key_type) ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ 0) -/** The default nonce size for an AEAD algorithm, in bytes. +/** Sufficient buffer size for exporting any asymmetric key pair. * - * This macro can be used to allocate a buffer of sufficient size to - * store the nonce output from #psa_aead_generate_nonce(). + * This macro expands to a compile-time constant integer. This value is + * a sufficient buffer size when calling psa_export_key() to export any + * asymmetric key pair, regardless of the exact key type and key size. * - * See also #PSA_AEAD_NONCE_MAX_SIZE. + * See also #PSA_EXPORT_KEY_OUTPUT_SIZE(\p key_type, \p key_bits). + */ +#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ + (PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \ + PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) ? \ + PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) : \ + PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)) + +/** Sufficient buffer size for exporting any asymmetric public key. * - * \note This is not the maximum size of nonce supported as input to #psa_aead_set_nonce(), - * #psa_aead_encrypt() or #psa_aead_decrypt(), just the default size that is generated by - * #psa_aead_generate_nonce(). + * This macro expands to a compile-time constant integer. This value is + * a sufficient buffer size when calling psa_export_key() or + * psa_export_public_key() to export any asymmetric public key, + * regardless of the exact key type and key size. + * + * See also #PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(\p key_type, \p key_bits). + */ +#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ + (PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) ? \ + PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) : \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)) + +/** Sufficient output buffer size for psa_raw_key_agreement(). + * + * This macro returns a compile-time constant if its arguments are + * compile-time constants. * * \warning This macro may evaluate its arguments multiple times or * zero times, so you should not pass arguments that contain * side effects. * - * \param key_type A symmetric key type that is compatible with algorithm \p alg. + * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE. * - * \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param key_type A supported key type. + * \param key_bits The size of the key in bits. * - * \return The default nonce size for the specified key type and algorithm. - * If the key type or AEAD algorithm is not recognized, - * or the parameters are incompatible, return 0. - * An implementation can return either 0 or a correct size for a key type - * and AEAD algorithm that it recognizes, but does not support. + * \return If the parameters are valid and supported, return + * a buffer size in bytes that guarantees that + * psa_raw_key_agreement() will not fail with + * #PSA_ERROR_BUFFER_TOO_SMALL. + * If the parameters are a valid combination that + * is not supported, return either a sensible size or 0. + * If the parameters are not valid, + * the return value is unspecified. */ -#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \ - (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) == 16 && \ - (PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CCM || \ - PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_GCM) ? 12 : \ - (key_type) == PSA_KEY_TYPE_CHACHA20 && \ - PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CHACHA20_POLY1305 ? 12 : \ +/* FFDH is not yet supported in PSA. */ +#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? \ + PSA_BITS_TO_BYTES(key_bits) : \ 0) -/** The maximum default nonce size among all supported pairs of key types and - * AEAD algorithms, in bytes. +/** Maximum size of the output from psa_raw_key_agreement(). * - * This is equal to or greater than any value that #PSA_AEAD_NONCE_LENGTH() may return. + * This macro expands to a compile-time constant integer. This value is the + * maximum size of the output any raw key agreement algorithm, in bytes. * - * \note This is not the maximum size of nonce supported as input to #psa_aead_set_nonce(), - * #psa_aead_encrypt() or #psa_aead_decrypt(), just the largest size that may be generated by - * #psa_aead_generate_nonce(). + * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits). */ -#define PSA_AEAD_NONCE_MAX_SIZE 12 +#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \ + (PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)) /** The default IV size for a cipher algorithm, in bytes. * @@ -674,17 +906,15 @@ * If the algorithm does not use an IV, return 0. * If the key type or cipher algorithm is not recognized, * or the parameters are incompatible, return 0. - * An implementation can return either 0 or a correct size for a key type - * and cipher algorithm that it recognizes, but does not support. */ #define PSA_CIPHER_IV_LENGTH(key_type, alg) \ - (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) > 1 && \ + (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1 && \ ((alg) == PSA_ALG_CTR || \ (alg) == PSA_ALG_CFB || \ (alg) == PSA_ALG_OFB || \ (alg) == PSA_ALG_XTS || \ (alg) == PSA_ALG_CBC_NO_PADDING || \ - (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \ + (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ (key_type) == PSA_KEY_TYPE_CHACHA20 && \ (alg) == PSA_ALG_STREAM_CIPHER ? 12 : \ 0) @@ -695,4 +925,163 @@ */ #define PSA_CIPHER_IV_MAX_SIZE 16 +/** The maximum size of the output of psa_cipher_encrypt(), in bytes. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_encrypt() will not fail due to an insufficient buffer size. + * Depending on the algorithm, the actual size of the output might be smaller. + * + * See also #PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(\p input_length). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is compatible with algorithm + * alg. + * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \param input_length Size of the input in bytes. + * + * \return A sufficient output size for the specified key type and + * algorithm. If the key type or cipher algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ + (alg == PSA_ALG_CBC_PKCS7 ? \ + PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \ + (input_length) + 1) + \ + PSA_CIPHER_IV_LENGTH((key_type), (alg)) : \ + (PSA_ALG_IS_CIPHER(alg) ? \ + (input_length) + PSA_CIPHER_IV_LENGTH((key_type), (alg)) : \ + 0)) + +/** A sufficient output buffer size for psa_cipher_encrypt(), for any of the + * supported key types and cipher algorithms. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_encrypt() will not fail due to an insufficient buffer size. + * + * See also #PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). + * + * \param input_length Size of the input in bytes. + * + */ +#define PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(input_length) \ + (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, \ + (input_length) + 1) + \ + PSA_CIPHER_IV_MAX_SIZE) + +/** The maximum size of the output of psa_cipher_decrypt(), in bytes. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_decrypt() will not fail due to an insufficient buffer size. + * Depending on the algorithm, the actual size of the output might be smaller. + * + * See also #PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(\p input_length). + * + * \param key_type A symmetric key type that is compatible with algorithm + * alg. + * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \param input_length Size of the input in bytes. + * + * \return A sufficient output size for the specified key type and + * algorithm. If the key type or cipher algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_CIPHER_DECRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ + (PSA_ALG_IS_CIPHER(alg) && \ + ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ + (input_length) : \ + 0) + +/** A sufficient output buffer size for psa_cipher_decrypt(), for any of the + * supported key types and cipher algorithms. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_decrypt() will not fail due to an insufficient buffer size. + * + * See also #PSA_CIPHER_DECRYPT_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). + * + * \param input_length Size of the input in bytes. + */ +#define PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(input_length) \ + (input_length) + +/** A sufficient output buffer size for psa_cipher_update(). + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_update() will not fail due to an insufficient buffer size. + * The actual size of the output might be smaller in any given call. + * + * See also #PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(\p input_length). + * + * \param key_type A symmetric key type that is compatible with algorithm + * alg. + * \param alg A cipher algorithm (PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \param input_length Size of the input in bytes. + * + * \return A sufficient output size for the specified key type and + * algorithm. If the key type or cipher algorithm is not + * recognized, or the parameters are incompatible, return 0. + */ +#define PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ + (PSA_ALG_IS_CIPHER(alg) ? \ + (((alg) == PSA_ALG_CBC_PKCS7 || \ + (alg) == PSA_ALG_CBC_NO_PADDING || \ + (alg) == PSA_ALG_ECB_NO_PADDING) ? \ + PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \ + input_length) : \ + (input_length)) : \ + 0) + +/** A sufficient output buffer size for psa_cipher_update(), for any of the + * supported key types and cipher algorithms. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_update() will not fail due to an insufficient buffer size. + * + * See also #PSA_CIPHER_UPDATE_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). + * + * \param input_length Size of the input in bytes. + */ +#define PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(input_length) \ + (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, input_length)) + +/** A sufficient ciphertext buffer size for psa_cipher_finish(). + * + * If the size of the ciphertext buffer is at least this large, it is + * guaranteed that psa_cipher_finish() will not fail due to an insufficient + * ciphertext buffer size. The actual size of the output might be smaller in + * any given call. + * + * See also #PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE(). + * + * \param key_type A symmetric key type that is compatible with algorithm + * alg. + * \param alg A cipher algorithm (PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \return A sufficient output size for the specified key type and + * algorithm. If the key type or cipher algorithm is not + * recognized, or the parameters are incompatible, return 0. + */ +#define PSA_CIPHER_FINISH_OUTPUT_SIZE(key_type, alg) \ + (PSA_ALG_IS_CIPHER(alg) ? \ + (alg == PSA_ALG_CBC_PKCS7 ? \ + PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ + 0) : \ + 0) + +/** A sufficient ciphertext buffer size for psa_cipher_finish(), for any of the + * supported key types and cipher algorithms. + * + * See also #PSA_CIPHER_FINISH_OUTPUT_SIZE(\p key_type, \p alg). + */ +#define PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE \ + (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) + #endif /* PSA_CRYPTO_SIZES_H */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_types.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_types.h index bf51a2fa4e9..0588d51d8da 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_types.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_types.h @@ -103,14 +103,14 @@ typedef uint32_t psa_algorithm_t; * whether the key is _volatile_ or _persistent_. * See ::psa_key_persistence_t for more information. * - Bits 8-31 (#PSA_KEY_LIFETIME_GET_LOCATION(\c lifetime)): - * location indicator. This value indicates where the key is stored - * and where operations on the key are performed. + * location indicator. This value indicates which part of the system + * has access to the key material and can perform operations using the key. * See ::psa_key_location_t for more information. * * Volatile keys are automatically destroyed when the application instance * terminates or on a power reset of the device. Persistent keys are * preserved until the application explicitly destroys them or until an - * implementation-specific device management event occurs (for example, + * integration-specific device management event occurs (for example, * a factory reset). * * Persistent keys have a key identifier of type #psa_key_id_t. @@ -119,12 +119,10 @@ typedef uint32_t psa_algorithm_t; * The application can call psa_open_key() to open a persistent key that * it created previously. * - * This specification defines two basic lifetime values: - * - Keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE are volatile. - * All implementations should support this lifetime. - * - Keys with the lifetime #PSA_KEY_LIFETIME_PERSISTENT are persistent. - * All implementations that have access to persistent storage with - * appropriate security guarantees should support this lifetime. + * The default lifetime of a key is #PSA_KEY_LIFETIME_VOLATILE. The lifetime + * #PSA_KEY_LIFETIME_PERSISTENT is supported if persistent storage is + * available. Other lifetime values may be supported depending on the + * library configuration. */ typedef uint32_t psa_key_lifetime_t; @@ -137,35 +135,21 @@ typedef uint32_t psa_key_lifetime_t; * actually affect persistent keys at different levels is outside the * scope of the PSA Cryptography specification. * - * This specification defines the following values of persistence levels: + * The PSA Cryptography specification defines the following values of + * persistence levels: * - \c 0 = #PSA_KEY_PERSISTENCE_VOLATILE: volatile key. * A volatile key is automatically destroyed by the implementation when * the application instance terminates. In particular, a volatile key * is automatically destroyed on a power reset of the device. * - \c 1 = #PSA_KEY_PERSISTENCE_DEFAULT: * persistent key with a default lifetime. - * Implementations should support this value if they support persistent - * keys at all. - * Applications should use this value if they have no specific needs that - * are only met by implementation-specific features. - * - \c 2-127: persistent key with a PSA-specified lifetime. - * The PSA Cryptography specification does not define the meaning of these - * values, but other PSA specifications may do so. - * - \c 128-254: persistent key with a vendor-specified lifetime. - * No PSA specification will define the meaning of these values, so - * implementations may choose the meaning freely. - * As a guideline, higher persistence levels should cause a key to survive - * more management events than lower levels. + * - \c 2-254: currently not supported by Mbed TLS. * - \c 255 = #PSA_KEY_PERSISTENCE_READ_ONLY: * read-only or write-once key. * A key with this persistence level cannot be destroyed. - * Implementations that support such keys may either allow their creation - * through the PSA Cryptography API, preferably only to applications with - * the appropriate privilege, or only expose keys created through - * implementation-specific means such as a factory ROM engraving process. - * Note that keys that are read-only due to policy restrictions - * rather than due to physical limitations should not have this - * persistence levels. + * Mbed TLS does not currently offer a way to create such keys, but + * integrations of Mbed TLS can use it for built-in keys that the + * application cannot modify (for example, a hardware unique key (HUK)). * * \note Key persistence levels are 8-bit values. Key management * interfaces operate on lifetimes (type ::psa_key_lifetime_t) which @@ -175,28 +159,30 @@ typedef uint8_t psa_key_persistence_t; /** Encoding of key location indicators. * - * If an implementation of this API can make calls to external + * If an integration of Mbed TLS can make calls to external * cryptoprocessors such as secure elements, the location of a key * indicates which secure element performs the operations on the key. - * If an implementation offers multiple physical locations for persistent - * storage, the location indicator reflects at which physical location - * the key is stored. + * Depending on the design of the secure element, the key + * material may be stored either in the secure element, or + * in wrapped (encrypted) form alongside the key metadata in the + * primary local storage. * - * This specification defines the following values of location indicators: + * The PSA Cryptography API specification defines the following values of + * location indicators: * - \c 0: primary local storage. - * All implementations should support this value. + * This location is always available. * The primary local storage is typically the same storage area that * contains the key metadata. * - \c 1: primary secure element. - * Implementations should support this value if there is a secure element - * attached to the operating environment. + * Integrations of Mbed TLS should support this value if there is a secure + * element attached to the operating environment. * As a guideline, secure elements may provide higher resistance against * side channel and physical attacks than the primary local storage, but may * have restrictions on supported key types, sizes, policies and operations * and may have different performance characteristics. * - \c 2-0x7fffff: other locations defined by a PSA specification. * The PSA Cryptography API does not currently assign any meaning to these - * locations, but future versions of this specification or other PSA + * locations, but future versions of that specification or other PSA * specifications may do so. * - \c 0x800000-0xffffff: vendor-defined locations. * No PSA specification will assign a meaning to locations in this range. @@ -211,7 +197,7 @@ typedef uint32_t psa_key_location_t; * * - Applications may freely choose key identifiers in the range * #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX. - * - Implementations may define additional key identifiers in the range + * - The implementation may define additional key identifiers in the range * #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX. * - 0 is reserved as an invalid key identifier. * - Key identifiers outside these ranges are reserved for future use. @@ -243,23 +229,18 @@ typedef uint32_t psa_key_usage_t; * - The key's policy, comprising usage flags and a specification of * the permitted algorithm(s). * - Information about the key itself: the key type and its size. - * - Implementations may define additional attributes. + * - Additional implementation-defined attributes. * * The actual key material is not considered an attribute of a key. * Key attributes do not contain information that is generally considered * highly confidential. * - * An attribute structure can be a simple data structure where each function + * An attribute structure works like a simple data structure where each function * `psa_set_key_xxx` sets a field and the corresponding function * `psa_get_key_xxx` retrieves the value of the corresponding field. - * However, implementations may report values that are equivalent to the - * original one, but have a different encoding. For example, an - * implementation may use a more compact representation for types where - * many bit-patterns are invalid or not supported, and store all values - * that it does not support as a special marker value. In such an - * implementation, after setting an invalid value, the corresponding - * get function returns an invalid value which may not be the one that - * was originally stored. + * However, a future version of the library may report values that are + * equivalent to the original one, but have a different encoding. Invalid + * values may be mapped to different, also invalid values. * * An attribute structure may contain references to auxiliary resources, * for example pointers to allocated memory or indirect references to diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_values.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_values.h index f813280e0f6..78f9e8ec9ee 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_values.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/crypto_values.h @@ -264,6 +264,46 @@ */ #define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136) +/** Stored data has been corrupted. + * + * This error indicates that some persistent storage has suffered corruption. + * It does not indicate the following situations, which have specific error + * codes: + * + * - A corruption of volatile memory - use #PSA_ERROR_CORRUPTION_DETECTED. + * - A communication error between the cryptoprocessor and its external + * storage - use #PSA_ERROR_COMMUNICATION_FAILURE. + * - When the storage is in a valid state but is full - use + * #PSA_ERROR_INSUFFICIENT_STORAGE. + * - When the storage fails for other reasons - use + * #PSA_ERROR_STORAGE_FAILURE. + * - When the stored data is not valid - use #PSA_ERROR_DATA_INVALID. + * + * \note A storage corruption does not indicate that any data that was + * previously read is invalid. However this previously read data might no + * longer be readable from storage. + * + * When a storage failure occurs, it is no longer possible to ensure the + * global integrity of the keystore. + */ +#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152) + +/** Data read from storage is not valid for the implementation. + * + * This error indicates that some data read from storage does not have a valid + * format. It does not indicate the following situations, which have specific + * error codes: + * + * - When the storage or stored data is corrupted - use #PSA_ERROR_DATA_CORRUPT + * - When the storage fails for other reasons - use #PSA_ERROR_STORAGE_FAILURE + * - An invalid argument to the API - use #PSA_ERROR_INVALID_ARGUMENT + * + * This error is typically a result of either storage corruption on a + * cleartext storage backend, or an attempt to read data that was + * written by an incompatible version of the library. + */ +#define PSA_ERROR_DATA_INVALID ((psa_status_t)-153) + /**@}*/ /** \defgroup crypto_types Key and algorithm types @@ -357,17 +397,61 @@ * used for. * * HMAC keys should generally have the same size as the underlying hash. - * This size can be calculated with #PSA_HASH_SIZE(\c alg) where + * This size can be calculated with #PSA_HASH_LENGTH(\c alg) where * \c alg is the HMAC algorithm or the underlying hash algorithm. */ #define PSA_KEY_TYPE_HMAC ((psa_key_type_t)0x1100) /** A secret for key derivation. + * + * This key type is for high-entropy secrets only. For low-entropy secrets, + * #PSA_KEY_TYPE_PASSWORD should be used instead. + * + * These keys can be used as the #PSA_KEY_DERIVATION_INPUT_SECRET or + * #PSA_KEY_DERIVATION_INPUT_PASSWORD input of key derivation algorithms. * * The key policy determines which key derivation algorithm the key * can be used for. */ #define PSA_KEY_TYPE_DERIVE ((psa_key_type_t)0x1200) +/** A low-entropy secret for password hashing or key derivation. + * + * This key type is suitable for passwords and passphrases which are typically + * intended to be memorizable by humans, and have a low entropy relative to + * their size. It can be used for randomly generated or derived keys with + * maximum or near-maximum entropy, but #PSA_KEY_TYPE_DERIVE is more suitable + * for such keys. It is not suitable for passwords with extremely low entropy, + * such as numerical PINs. + * + * These keys can be used as the #PSA_KEY_DERIVATION_INPUT_PASSWORD input of + * key derivation algorithms. Algorithms that accept such an input were + * designed to accept low-entropy secret and are known as password hashing or + * key stretching algorithms. + * + * These keys cannot be used as the #PSA_KEY_DERIVATION_INPUT_SECRET input of + * key derivation algorithms, as the algorithms that take such an input expect + * it to be high-entropy. + * + * The key policy determines which key derivation algorithm the key can be + * used for, among the permissible subset defined above. + */ +#define PSA_KEY_TYPE_PASSWORD ((psa_key_type_t)0x1203) + +/** A secret value that can be used to verify a password hash. + * + * The key policy determines which key derivation algorithm the key + * can be used for, among the same permissible subset as for + * #PSA_KEY_TYPE_PASSWORD. + */ +#define PSA_KEY_TYPE_PASSWORD_HASH ((psa_key_type_t)0x1205) + +/** A secret value that can be used in when computing a password hash. + * + * The key policy determines which key derivation algorithm the key + * can be used for, among the subset of algorithms that can use pepper. + */ +#define PSA_KEY_TYPE_PEPPER ((psa_key_type_t)0x1206) + /** Key for a cipher, AEAD or MAC algorithm based on the AES block cipher. * * The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or @@ -377,8 +461,8 @@ /** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES). * - * The size of the key can be 8 bytes (single DES), 16 bytes (2-key 3DES) or - * 24 bytes (3-key 3DES). + * The size of the key can be 64 bits (single DES), 128 bits (2-key 3DES) or + * 192 bits (3-key 3DES). * * Note that single DES and 2-key 3DES are weak and strongly * deprecated and should only be used to decrypt legacy data. 3-key 3DES @@ -390,12 +474,6 @@ * Camellia block cipher. */ #define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t)0x2403) -/** Key for the RC4 stream cipher. - * - * Note that RC4 is weak and deprecated and should only be used in - * legacy protocols. */ -#define PSA_KEY_TYPE_ARC4 ((psa_key_type_t)0x2002) - /** Key for the ChaCha20 stream cipher or the Chacha20-Poly1305 AEAD algorithm. * * ChaCha20 and the ChaCha20_Poly1305 construction are defined in RFC 7539. @@ -405,9 +483,15 @@ */ #define PSA_KEY_TYPE_CHACHA20 ((psa_key_type_t)0x2004) -/** RSA public key. */ +/** RSA public key. + * + * The size of an RSA key is the bit size of the modulus. + */ #define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x4001) -/** RSA key pair (private and public key). */ +/** RSA key pair (private and public key). + * + * The size of an RSA key is the bit size of the modulus. + */ #define PSA_KEY_TYPE_RSA_KEY_PAIR ((psa_key_type_t)0x7001) /** Whether a key type is an RSA key (pair or public-only). */ #define PSA_KEY_TYPE_IS_RSA(type) \ @@ -417,6 +501,10 @@ #define PSA_KEY_TYPE_ECC_KEY_PAIR_BASE ((psa_key_type_t)0x7100) #define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x00ff) /** Elliptic curve key pair. + * + * The size of an elliptic curve key is the bit size associated with the curve, + * i.e. the bit size of *q* for a curve over a field *Fq*. + * See the documentation of `PSA_ECC_FAMILY_xxx` curve families for details. * * \param curve A value of type ::psa_ecc_family_t that * identifies the ECC curve to be used. @@ -424,6 +512,10 @@ #define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \ (PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (curve)) /** Elliptic curve public key. + * + * The size of an elliptic curve public key is the same as the corresponding + * private key (see #PSA_KEY_TYPE_ECC_KEY_PAIR and the documentation of + * `PSA_ECC_FAMILY_xxx` curve families). * * \param curve A value of type ::psa_ecc_family_t that * identifies the ECC curve to be used. @@ -523,6 +615,22 @@ */ #define PSA_ECC_FAMILY_MONTGOMERY ((psa_ecc_family_t) 0x41) +/** The twisted Edwards curves Ed25519 and Ed448. + * + * These curves are suitable for EdDSA (#PSA_ALG_PURE_EDDSA for both curves, + * #PSA_ALG_ED25519PH for the 255-bit curve, + * #PSA_ALG_ED448PH for the 448-bit curve). + * + * This family comprises the following twisted Edwards curves: + * - 255-bit: Edwards25519, the twisted Edwards curve birationally equivalent + * to Curve25519. + * Bernstein et al., _Twisted Edwards curves_, Africacrypt 2008. + * - 448-bit: Edwards448, the twisted Edwards curve birationally equivalent + * to Curve448. + * Hamburg, _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015. + */ +#define PSA_ECC_FAMILY_TWISTED_EDWARDS ((psa_ecc_family_t) 0x42) + #define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t)0x4200) #define PSA_KEY_TYPE_DH_KEY_PAIR_BASE ((psa_key_type_t)0x7200) #define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t)0x00ff) @@ -588,9 +696,9 @@ * * \warning This macro may evaluate its argument multiple times. */ -#define PSA_BLOCK_CIPHER_BLOCK_SIZE(type) \ +#define PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) \ (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ - 1u << PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) : \ + 1u << PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) : \ 0u) /** Vendor-defined algorithm flag. @@ -710,11 +818,25 @@ #define PSA_ALG_IS_KEY_DERIVATION(alg) \ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION) +/** Whether the specified algorithm is a key stretching / password hashing + * algorithm. + * + * A key stretching / password hashing algorithm is a key derivation algorithm + * that is suitable for use with a low-entropy secret such as a password. + * Equivalently, it's a key derivation algorithm that uses a + * #PSA_KEY_DERIVATION_INPUT_PASSWORD input step. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a key stretching / password hashing algorithm, 0 + * otherwise. This macro may return either 0 or 1 if \p alg is not a + * supported algorithm identifier. + */ +#define PSA_ALG_IS_KEY_DERIVATION_STRETCHING(alg) \ + (PSA_ALG_IS_KEY_DERIVATION(alg) && \ + (alg) & PSA_ALG_KEY_DERIVATION_STRETCHING_FLAG) + #define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff) -/** MD2 */ -#define PSA_ALG_MD2 ((psa_algorithm_t)0x02000001) -/** MD4 */ -#define PSA_ALG_MD4 ((psa_algorithm_t)0x02000002) /** MD5 */ #define PSA_ALG_MD5 ((psa_algorithm_t)0x02000003) /** PSA_ALG_RIPEMD160 */ @@ -741,6 +863,13 @@ #define PSA_ALG_SHA3_384 ((psa_algorithm_t)0x02000012) /** SHA3-512 */ #define PSA_ALG_SHA3_512 ((psa_algorithm_t)0x02000013) +/** The first 512 bits (64 bytes) of the SHAKE256 output. + * + * This is the prehashing for Ed448ph (see #PSA_ALG_ED448PH). For other + * scenarios where a hash function based on SHA3/SHAKE is desired, SHA3-512 + * has the same output size and a (theoretically) higher security strength. + */ +#define PSA_ALG_SHAKE256_512 ((psa_algorithm_t)0x02000015) /** In a hash-and-sign algorithm policy, allow any hash algorithm. * @@ -820,6 +949,14 @@ #define PSA_ALG_MAC_TRUNCATION_MASK ((psa_algorithm_t)0x003f0000) #define PSA_MAC_TRUNCATION_OFFSET 16 +/* In the encoding of a MAC algorithm, the bit corresponding to + * #PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG encodes the fact that the algorithm + * is a wildcard algorithm. A key with such wildcard algorithm as permitted + * algorithm policy can be used with any algorithm corresponding to the + * same base class and having a (potentially truncated) MAC length greater or + * equal than the one encoded in #PSA_ALG_MAC_TRUNCATION_MASK. */ +#define PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ((psa_algorithm_t)0x00008000) + /** Macro to build a truncated MAC algorithm. * * A truncated MAC algorithm is identical to the corresponding MAC @@ -838,7 +975,7 @@ * for policy comparison purposes. * * \param mac_alg A MAC algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg) + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) * is true). This may be a truncated or untruncated * MAC algorithm. * \param mac_length Desired length of the truncated MAC in bytes. @@ -849,43 +986,73 @@ * * \return The corresponding MAC algorithm with the specified * length. - * \return Unspecified if \p alg is not a supported + * \return Unspecified if \p mac_alg is not a supported * MAC algorithm or if \p mac_length is too small or * too large for the specified MAC algorithm. */ -#define PSA_ALG_TRUNCATED_MAC(mac_alg, mac_length) \ - (((mac_alg) & ~PSA_ALG_MAC_TRUNCATION_MASK) | \ +#define PSA_ALG_TRUNCATED_MAC(mac_alg, mac_length) \ + (((mac_alg) & ~(PSA_ALG_MAC_TRUNCATION_MASK | \ + PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG)) | \ ((mac_length) << PSA_MAC_TRUNCATION_OFFSET & PSA_ALG_MAC_TRUNCATION_MASK)) /** Macro to build the base MAC algorithm corresponding to a truncated * MAC algorithm. * * \param mac_alg A MAC algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg) + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) * is true). This may be a truncated or untruncated * MAC algorithm. * * \return The corresponding base MAC algorithm. - * \return Unspecified if \p alg is not a supported + * \return Unspecified if \p mac_alg is not a supported * MAC algorithm. */ -#define PSA_ALG_FULL_LENGTH_MAC(mac_alg) \ - ((mac_alg) & ~PSA_ALG_MAC_TRUNCATION_MASK) +#define PSA_ALG_FULL_LENGTH_MAC(mac_alg) \ + ((mac_alg) & ~(PSA_ALG_MAC_TRUNCATION_MASK | \ + PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG)) /** Length to which a MAC algorithm is truncated. * * \param mac_alg A MAC algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg) + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) * is true). * * \return Length of the truncated MAC in bytes. - * \return 0 if \p alg is a non-truncated MAC algorithm. - * \return Unspecified if \p alg is not a supported + * \return 0 if \p mac_alg is a non-truncated MAC algorithm. + * \return Unspecified if \p mac_alg is not a supported * MAC algorithm. */ #define PSA_MAC_TRUNCATED_LENGTH(mac_alg) \ (((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET) +/** Macro to build a MAC minimum-MAC-length wildcard algorithm. + * + * A minimum-MAC-length MAC wildcard algorithm permits all MAC algorithms + * sharing the same base algorithm, and where the (potentially truncated) MAC + * length of the specific algorithm is equal to or larger then the wildcard + * algorithm's minimum MAC length. + * + * \note When setting the minimum required MAC length to less than the + * smallest MAC length allowed by the base algorithm, this effectively + * becomes an 'any-MAC-length-allowed' policy for that base algorithm. + * + * \param mac_alg A MAC algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) + * is true). + * \param min_mac_length Desired minimum length of the message authentication + * code in bytes. This must be at most the untruncated + * length of the MAC and must be at least 1. + * + * \return The corresponding MAC wildcard algorithm with the + * specified minimum length. + * \return Unspecified if \p mac_alg is not a supported MAC + * algorithm or if \p min_mac_length is less than 1 or + * too large for the specified MAC algorithm. + */ +#define PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(mac_alg, min_mac_length) \ + ( PSA_ALG_TRUNCATED_MAC(mac_alg, min_mac_length) | \ + PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) + #define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x03c00000) /** The CBC-MAC construction over a block cipher * @@ -931,7 +1098,6 @@ * * The underlying stream cipher is determined by the key type. * - To use ChaCha20, use a key type of #PSA_KEY_TYPE_CHACHA20. - * - To use ARC4, use a key type of #PSA_KEY_TYPE_ARC4. */ #define PSA_ALG_STREAM_CIPHER ((psa_algorithm_t)0x04800100) @@ -1046,6 +1212,14 @@ #define PSA_ALG_AEAD_TAG_LENGTH_MASK ((psa_algorithm_t)0x003f0000) #define PSA_AEAD_TAG_LENGTH_OFFSET 16 +/* In the encoding of an AEAD algorithm, the bit corresponding to + * #PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG encodes the fact that the algorithm + * is a wildcard algorithm. A key with such wildcard algorithm as permitted + * algorithm policy can be used with any algorithm corresponding to the + * same base class and having a tag length greater than or equal to the one + * encoded in #PSA_ALG_AEAD_TAG_LENGTH_MASK. */ +#define PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ((psa_algorithm_t)0x00008000) + /** Macro to build a shortened AEAD algorithm. * * A shortened AEAD algorithm is similar to the corresponding AEAD @@ -1069,25 +1243,91 @@ ((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \ PSA_ALG_AEAD_TAG_LENGTH_MASK)) +/** Macro to build a shortened AEAD algorithm. + * + * A shortened AEAD algorithm is similar to the corresponding AEAD + * algorithm, but has an authentication tag that consists of fewer bytes. + * Depending on the algorithm, the tag length may affect the calculation + * of the ciphertext. + * + * \param aead_alg An AEAD algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p aead_alg) + * is true). + * \param tag_length Desired length of the authentication tag in bytes. + * + * \return The corresponding AEAD algorithm with the specified + * length. + * \return Unspecified if \p aead_alg is not a supported + * AEAD algorithm or if \p tag_length is not valid + * for the specified AEAD algorithm. + */ +#define PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, tag_length) \ + (((aead_alg) & ~(PSA_ALG_AEAD_TAG_LENGTH_MASK | \ + PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG)) | \ + ((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \ + PSA_ALG_AEAD_TAG_LENGTH_MASK)) + +/** Retrieve the tag length of a specified AEAD algorithm + * + * \param aead_alg An AEAD algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p aead_alg) + * is true). + * + * \return The tag length specified by the input algorithm. + * \return Unspecified if \p aead_alg is not a supported + * AEAD algorithm. + */ +#define PSA_ALG_AEAD_GET_TAG_LENGTH(aead_alg) \ + (((aead_alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> \ + PSA_AEAD_TAG_LENGTH_OFFSET ) + /** Calculate the corresponding AEAD algorithm with the default tag length. * * \param aead_alg An AEAD algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). + * #PSA_ALG_IS_AEAD(\p aead_alg) is true). * * \return The corresponding AEAD algorithm with the default * tag length for that algorithm. */ -#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(aead_alg) \ +#define PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(aead_alg) \ ( \ - PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_CCM) \ - PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_GCM) \ - PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_CHACHA20_POLY1305) \ + PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_CCM) \ + PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_GCM) \ + PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_CHACHA20_POLY1305) \ 0) -#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, ref) \ - PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, 0) == \ - PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \ +#define PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, ref) \ + PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, 0) == \ + PSA_ALG_AEAD_WITH_SHORTENED_TAG(ref, 0) ? \ ref : +/** Macro to build an AEAD minimum-tag-length wildcard algorithm. + * + * A minimum-tag-length AEAD wildcard algorithm permits all AEAD algorithms + * sharing the same base algorithm, and where the tag length of the specific + * algorithm is equal to or larger then the minimum tag length specified by the + * wildcard algorithm. + * + * \note When setting the minimum required tag length to less than the + * smallest tag length allowed by the base algorithm, this effectively + * becomes an 'any-tag-length-allowed' policy for that base algorithm. + * + * \param aead_alg An AEAD algorithm identifier (value of type + * #psa_algorithm_t such that + * #PSA_ALG_IS_AEAD(\p aead_alg) is true). + * \param min_tag_length Desired minimum length of the authentication tag in + * bytes. This must be at least 1 and at most the largest + * allowed tag length of the algorithm. + * + * \return The corresponding AEAD wildcard algorithm with the + * specified minimum length. + * \return Unspecified if \p aead_alg is not a supported + * AEAD algorithm or if \p min_tag_length is less than 1 + * or too large for the specified AEAD algorithm. + */ +#define PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(aead_alg, min_tag_length) \ + ( PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, min_tag_length) | \ + PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) + #define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x06000200) /** RSA PKCS#1 v1.5 signature with hashing. * @@ -1209,6 +1449,94 @@ #define PSA_ALG_IS_RANDOMIZED_ECDSA(alg) \ (PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) +/** Edwards-curve digital signature algorithm without prehashing (PureEdDSA), + * using standard parameters. + * + * Contexts are not supported in the current version of this specification + * because there is no suitable signature interface that can take the + * context as a parameter. A future version of this specification may add + * suitable functions and extend this algorithm to support contexts. + * + * PureEdDSA requires an elliptic curve key on a twisted Edwards curve. + * In this specification, the following curves are supported: + * - #PSA_ECC_FAMILY_TWISTED_EDWARDS, 255-bit: Ed25519 as specified + * in RFC 8032. + * The curve is Edwards25519. + * The hash function used internally is SHA-512. + * - #PSA_ECC_FAMILY_TWISTED_EDWARDS, 448-bit: Ed448 as specified + * in RFC 8032. + * The curve is Edwards448. + * The hash function used internally is the first 114 bytes of the + * SHAKE256 output. + * + * This algorithm can be used with psa_sign_message() and + * psa_verify_message(). Since there is no prehashing, it cannot be used + * with psa_sign_hash() or psa_verify_hash(). + * + * The signature format is the concatenation of R and S as defined by + * RFC 8032 ยง5.1.6 and ยง5.2.6 (a 64-byte string for Ed25519, a 114-byte + * string for Ed448). + */ +#define PSA_ALG_PURE_EDDSA ((psa_algorithm_t)0x06000800) + +#define PSA_ALG_HASH_EDDSA_BASE ((psa_algorithm_t)0x06000900) +#define PSA_ALG_IS_HASH_EDDSA(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HASH_EDDSA_BASE) + +/** Edwards-curve digital signature algorithm with prehashing (HashEdDSA), + * using SHA-512 and the Edwards25519 curve. + * + * See #PSA_ALG_PURE_EDDSA regarding context support and the signature format. + * + * This algorithm is Ed25519 as specified in RFC 8032. + * The curve is Edwards25519. + * The prehash is SHA-512. + * The hash function used internally is SHA-512. + * + * This is a hash-and-sign algorithm: to calculate a signature, + * you can either: + * - call psa_sign_message() on the message; + * - or calculate the SHA-512 hash of the message + * with psa_hash_compute() + * or with a multi-part hash operation started with psa_hash_setup(), + * using the hash algorithm #PSA_ALG_SHA_512, + * then sign the calculated hash with psa_sign_hash(). + * Verifying a signature is similar, using psa_verify_message() or + * psa_verify_hash() instead of the signature function. + */ +#define PSA_ALG_ED25519PH \ + (PSA_ALG_HASH_EDDSA_BASE | (PSA_ALG_SHA_512 & PSA_ALG_HASH_MASK)) + +/** Edwards-curve digital signature algorithm with prehashing (HashEdDSA), + * using SHAKE256 and the Edwards448 curve. + * + * See #PSA_ALG_PURE_EDDSA regarding context support and the signature format. + * + * This algorithm is Ed448 as specified in RFC 8032. + * The curve is Edwards448. + * The prehash is the first 64 bytes of the SHAKE256 output. + * The hash function used internally is the first 114 bytes of the + * SHAKE256 output. + * + * This is a hash-and-sign algorithm: to calculate a signature, + * you can either: + * - call psa_sign_message() on the message; + * - or calculate the first 64 bytes of the SHAKE256 output of the message + * with psa_hash_compute() + * or with a multi-part hash operation started with psa_hash_setup(), + * using the hash algorithm #PSA_ALG_SHAKE256_512, + * then sign the calculated hash with psa_sign_hash(). + * Verifying a signature is similar, using psa_verify_message() or + * psa_verify_hash() instead of the signature function. + */ +#define PSA_ALG_ED448PH \ + (PSA_ALG_HASH_EDDSA_BASE | (PSA_ALG_SHAKE256_512 & PSA_ALG_HASH_MASK)) + +/* Default definition, to be overridden if the library is extended with + * more hash-and-sign algorithms that we want to keep out of this header + * file. */ +#define PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg) 0 + /** Whether the specified algorithm is a hash-and-sign algorithm. * * Hash-and-sign algorithms are asymmetric (public-key) signature algorithms @@ -1224,7 +1552,22 @@ */ #define PSA_ALG_IS_HASH_AND_SIGN(alg) \ (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ - PSA_ALG_IS_ECDSA(alg)) + PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) || \ + PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg)) + +/** Whether the specified algorithm is a signature algorithm that can be used + * with psa_sign_message() and psa_verify_message(). + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if alg is a signature algorithm that can be used to sign a + * message. 0 if \p alg is a signature algorithm that can only be used + * to sign an already-calculated hash. 0 if \p alg is not a signature + * algorithm. This macro can return either 0 or 1 if \p alg is not a + * supported algorithm identifier. + */ +#define PSA_ALG_IS_SIGN_MESSAGE(alg) \ + (PSA_ALG_IS_HASH_AND_SIGN(alg) || (alg) == PSA_ALG_PURE_EDDSA ) /** Get the hash used by a hash-and-sign signature algorithm. * @@ -1406,6 +1749,67 @@ #define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg) \ (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) +/* This flag indicates whether the key derivation algorithm is suitable for + * use on low-entropy secrets such as password - these algorithms are also + * known as key stretching or password hashing schemes. These are also the + * algorithms that accepts inputs of type #PSA_KEY_DERIVATION_INPUT_PASSWORD. + * + * Those algorithms cannot be combined with a key agreement algorithm. + */ +#define PSA_ALG_KEY_DERIVATION_STRETCHING_FLAG ((psa_algorithm_t)0x00800000) + +#define PSA_ALG_PBKDF2_HMAC_BASE ((psa_algorithm_t)0x08800100) +/** Macro to build a PBKDF2-HMAC password hashing / key stretching algorithm. + * + * PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2). + * This macro specifies the PBKDF2 algorithm constructed using a PRF based on + * HMAC with the specified hash. + * For example, `PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA256)` specifies PBKDF2 + * using the PRF HMAC-SHA-256. + * + * This key derivation algorithm uses the following inputs, which must be + * provided in the following order: + * - #PSA_KEY_DERIVATION_INPUT_COST is the iteration count. + * This input step must be used exactly once. + * - #PSA_KEY_DERIVATION_INPUT_SALT is the salt. + * This input step must be used one or more times; if used several times, the + * inputs will be concatenated. This can be used to build the final salt + * from multiple sources, both public and secret (also known as pepper). + * - #PSA_KEY_DERIVATION_INPUT_PASSWORD is the password to be hashed. + * This input step must be used exactly once. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding PBKDF2-HMAC-XXX algorithm. + * \return Unspecified if \p hash_alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_PBKDF2_HMAC(hash_alg) \ + (PSA_ALG_PBKDF2_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) + +/** Whether the specified algorithm is a PBKDF2-HMAC algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \c alg is a PBKDF2-HMAC algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \c alg is not a supported + * key derivation algorithm identifier. + */ +#define PSA_ALG_IS_PBKDF2_HMAC(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_PBKDF2_HMAC_BASE) + +/** The PBKDF2-AES-CMAC-PRF-128 password hashing / key stretching algorithm. + * + * PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2). + * This macro specifies the PBKDF2 algorithm constructed using the + * AES-CMAC-PRF-128 PRF specified by RFC 4615. + * + * This key derivation algorithm uses the same inputs as + * #PSA_ALG_PBKDF2_HMAC() with the same constraints. + */ +#define PSA_ALG_PBKDF2_AES_CMAC_PRF_128 ((psa_algorithm_t)0x08800200) + #define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0xfe00ffff) #define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t)0xffff0000) @@ -1534,11 +1938,27 @@ * \return This macro may return either 0 or 1 if \c alg is not a supported * algorithm identifier. */ -#define PSA_ALG_IS_WILDCARD(alg) \ - (PSA_ALG_IS_HASH_AND_SIGN(alg) ? \ - PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH : \ +#define PSA_ALG_IS_WILDCARD(alg) \ + (PSA_ALG_IS_HASH_AND_SIGN(alg) ? \ + PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH : \ + PSA_ALG_IS_MAC(alg) ? \ + (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0 : \ + PSA_ALG_IS_AEAD(alg) ? \ + (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0 : \ (alg) == PSA_ALG_ANY_HASH) +/** Get the hash used by a composite algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return The underlying hash algorithm if alg is a composite algorithm that + * uses a hash algorithm. + * + * \return \c 0 if alg is not a composite algorithm that uses a hash. + */ +#define PSA_ALG_GET_HASH(alg) \ + (((alg) & 0x000000ff) == 0 ? ((psa_algorithm_t)0) : 0x02000000 | ((alg) & 0x000000ff)) + /**@}*/ /** \defgroup key_lifetimes Key lifetimes @@ -1562,13 +1982,12 @@ * * A persistent key remains in storage until it is explicitly destroyed or * until the corresponding storage area is wiped. This specification does - * not define any mechanism to wipe a storage area, but implementations may + * not define any mechanism to wipe a storage area, but integrations may * provide their own mechanism (for example to perform a factory reset, * to prepare for device refurbishment, or to uninstall an application). * * This lifetime value is the default storage area for the calling - * application. Implementations may offer other storage areas designated - * by other lifetime values as implementation-specific extensions. + * application. Integrations of Mbed TLS may support other persistent lifetimes. * See ::psa_key_lifetime_t for more information. */ #define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001) @@ -1617,6 +2036,27 @@ (PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) == \ PSA_KEY_PERSISTENCE_VOLATILE) +/** Whether a key lifetime indicates that the key is read-only. + * + * Read-only keys cannot be created or destroyed through the PSA Crypto API. + * They must be created through platform-specific means that bypass the API. + * + * Some platforms may offer ways to destroy read-only keys. For example, + * consider a platform with multiple levels of privilege, where a + * low-privilege application can use a key but is not allowed to destroy + * it, and the platform exposes the key to the application with a read-only + * lifetime. High-privilege code can destroy the key even though the + * application sees the key as read-only. + * + * \param lifetime The lifetime value to query (value of type + * ::psa_key_lifetime_t). + * + * \return \c 1 if the key is read-only, otherwise \c 0. + */ +#define PSA_KEY_LIFETIME_IS_READ_ONLY(lifetime) \ + (PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) == \ + PSA_KEY_PERSISTENCE_READ_ONLY) + /** Construct a lifetime from a persistence level and a location. * * \param persistence The persistence level @@ -1710,6 +2150,26 @@ */ #define PSA_KEY_USAGE_DECRYPT ((psa_key_usage_t)0x00000200) +/** Whether the key may be used to sign a message. + * + * This flag allows the key to be used for a MAC calculation operation or for + * an asymmetric message signature operation, if otherwise permitted by the + * keyโ€™s type and policy. + * + * For a key pair, this concerns the private key. + */ +#define PSA_KEY_USAGE_SIGN_MESSAGE ((psa_key_usage_t)0x00000400) + +/** Whether the key may be used to verify a message. + * + * This flag allows the key to be used for a MAC verification operation or for + * an asymmetric message signature verification operation, if otherwise + * permitted by the keyโ€™s type and policy. + * + * For a key pair, this concerns the public key. + */ +#define PSA_KEY_USAGE_VERIFY_MESSAGE ((psa_key_usage_t)0x00000800) + /** Whether the key may be used to sign a message. * * This flag allows the key to be used for a MAC calculation operation @@ -1730,10 +2190,35 @@ */ #define PSA_KEY_USAGE_VERIFY_HASH ((psa_key_usage_t)0x00002000) -/** Whether the key may be used to derive other keys. +/** Whether the key may be used to derive other keys or produce a password + * hash. + * + * This flag allows the key to be used for a key derivation operation or for + * a key agreement operation, if otherwise permitted by by the key's type and + * policy. + * + * If this flag is present on all keys used in calls to + * psa_key_derivation_input_key() for a key derivation operation, then it + * permits calling psa_key_derivation_output_bytes() or + * psa_key_derivation_output_key() at the end of the operation. */ #define PSA_KEY_USAGE_DERIVE ((psa_key_usage_t)0x00004000) +/** Whether the key may be used to verify the result of a key derivation, + * including password hashing. + * + * This flag allows the key to be used: + * + * This flag allows the key to be used in a key derivation operation, if + * otherwise permitted by by the key's type and policy. + * + * If this flag is present on all keys used in calls to + * psa_key_derivation_input_key() for a key derivation operation, then it + * permits calling psa_key_derivation_verify_bytes() or + * psa_key_derivation_verify_key() at the end of the operation. + */ +#define PSA_KEY_USAGE_VERIFY_DERIVATION ((psa_key_usage_t)0x00008000) + /**@}*/ /** \defgroup derivation Key derivation @@ -1750,10 +2235,31 @@ * The secret can also be a direct input (passed to * key_derivation_input_bytes()). In this case, the derivation operation * may not be used to derive keys: the operation will only allow - * psa_key_derivation_output_bytes(), not psa_key_derivation_output_key(). + * psa_key_derivation_output_bytes(), + * psa_key_derivation_verify_bytes(), or + * psa_key_derivation_verify_key(), but not + * psa_key_derivation_output_key(). */ #define PSA_KEY_DERIVATION_INPUT_SECRET ((psa_key_derivation_step_t)0x0101) +/** A low-entropy secret input for password hashing / key stretching. + * + * This is usually a key of type #PSA_KEY_TYPE_PASSWORD (passed to + * psa_key_derivation_input_key()) or a direct input (passed to + * psa_key_derivation_input_bytes()) that is a password or passphrase. It can + * also be high-entropy secret such as a key of type #PSA_KEY_TYPE_DERIVE or + * the shared secret resulting from a key agreement. + * + * The secret can also be a direct input (passed to + * key_derivation_input_bytes()). In this case, the derivation operation + * may not be used to derive keys: the operation will only allow + * psa_key_derivation_output_bytes(), + * psa_key_derivation_verify_bytes(), or + * psa_key_derivation_verify_key(), but not + * psa_key_derivation_output_key(). + */ +#define PSA_KEY_DERIVATION_INPUT_PASSWORD ((psa_key_derivation_step_t)0x0102) + /** A label for key derivation. * * This should be a direct input. @@ -1764,7 +2270,8 @@ /** A salt for key derivation. * * This should be a direct input. - * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. + * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA or + * #PSA_KEY_TYPE_PEPPER. */ #define PSA_KEY_DERIVATION_INPUT_SALT ((psa_key_derivation_step_t)0x0202) @@ -1782,6 +2289,35 @@ */ #define PSA_KEY_DERIVATION_INPUT_SEED ((psa_key_derivation_step_t)0x0204) +/** A cost parameter for password hashing / key stretching. + * + * This must be a direct input, passed to psa_key_derivation_input_integer(). + */ +#define PSA_KEY_DERIVATION_INPUT_COST ((psa_key_derivation_step_t)0x0205) + +/**@}*/ + +/** \defgroup helper_macros Helper macros + * @{ + */ + +/* Helper macros */ + +/** Check if two AEAD algorithm identifiers refer to the same AEAD algorithm + * regardless of the tag length they encode. + * + * \param aead_alg_1 An AEAD algorithm identifier. + * \param aead_alg_2 An AEAD algorithm identifier. + * + * \return 1 if both identifiers refer to the same AEAD algorithm, + * 0 otherwise. + * Unspecified if neither \p aead_alg_1 nor \p aead_alg_2 are + * a supported AEAD algorithm. + */ +#define MBEDTLS_PSA_ALG_AEAD_EQUAL(aead_alg_1, aead_alg_2) \ + (!(((aead_alg_1) ^ (aead_alg_2)) & \ + ~(PSA_ALG_AEAD_TAG_LENGTH_MASK | PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG))) + /**@}*/ #endif /* PSA_CRYPTO_VALUES_H */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/initial_attestation.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/initial_attestation.h index 50dd479c627..3e661e0944f 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/initial_attestation.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/initial_attestation.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, Arm Limited. All rights reserved. + * Copyright (c) 2018-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -201,26 +201,6 @@ psa_status_t psa_initial_attest_get_token_size(size_t challenge_size, size_t *token_size); -/** - * \brief Get the initial attestation public key. - * - * \param[out] public_key Pointer to the buffer where the public key - * will be stored. - * \param[in] key_buf_size Size of allocated buffer for key, in bytes. - * \param[out] public_key_len Size of public key in bytes. - * \param[out] public_key_curve Type of the elliptic curve which the key - * belongs to. - * - * \note Currently only the ECDSA P-256 over SHA-256 algorithm is supported. - * - * \return Returns error code as specified in \ref psa_status_t - */ -psa_status_t -tfm_initial_attest_get_public_key(uint8_t *public_key, - size_t public_key_buf_size, - size_t *public_key_len, - psa_ecc_family_t *elliptic_curve_type); - #ifdef __cplusplus } #endif diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/update.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/update.h index 65d7d2dd601..d7de5ac9d65 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/update.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa/update.h @@ -207,6 +207,8 @@ psa_status_t psa_fwu_request_reboot(void); /** * \brief Indicates to the implementation that the upgrade was successful. * + * \param[in] image_id The image_id of the image to query + * * \return A status indicating the success/failure of the operation * * \retval PSA_SUCCESS The image and its dependencies have @@ -217,7 +219,7 @@ psa_status_t psa_fwu_request_reboot(void); * \retval PSA_ERROR_NOT_PERMITTED The caller is not permitted to make * this call */ -psa_status_t psa_fwu_accept(void); +psa_status_t psa_fwu_accept(psa_image_id_t image_id); /** * \brief Stores a manifest object and associates it with a particular image ID. diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa_manifest/sid.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa_manifest/sid.h index b896486056b..847472f1315 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa_manifest/sid.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/psa_manifest/sid.h @@ -39,6 +39,7 @@ extern "C" { /******** TFM_SP_CRYPTO ********/ #define TFM_CRYPTO_SID (0x00000080U) #define TFM_CRYPTO_VERSION (1U) +#define TFM_CRYPTO_HANDLE (0x40000100U) /******** TFM_SP_PLATFORM ********/ #define TFM_SP_PLATFORM_SYSTEM_RESET_SID (0x00000040U) @@ -53,8 +54,6 @@ extern "C" { #define TFM_ATTEST_GET_TOKEN_VERSION (1U) #define TFM_ATTEST_GET_TOKEN_SIZE_SID (0x00000021U) #define TFM_ATTEST_GET_TOKEN_SIZE_VERSION (1U) -#define TFM_ATTEST_GET_PUBLIC_KEY_SID (0x00000022U) -#define TFM_ATTEST_GET_PUBLIC_KEY_VERSION (1U) /******** TFM_SP_CORE_TEST ********/ #define SPM_CORE_TEST_INIT_SUCCESS_SID (0x0000F020U) @@ -87,10 +86,6 @@ extern "C" { #define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_VERSION (1U) #define SPM_CORE_TEST_2_INVERT_SID (0x0000F043U) #define SPM_CORE_TEST_2_INVERT_VERSION (1U) -#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SID (0x0000F044U) -#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_VERSION (1U) -#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SID (0x0000F045U) -#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_VERSION (1U) /******** TFM_SP_SECURE_TEST_PARTITION ********/ #define TFM_SECURE_CLIENT_SFN_RUN_TESTS_SID (0x0000F000U) @@ -122,12 +117,6 @@ extern "C" { #define IPC_CLIENT_TEST_RETRIEVE_APP_MEM_SID (0x0000F065U) #define IPC_CLIENT_TEST_RETRIEVE_APP_MEM_VERSION (1U) -/******** TFM_IRQ_TEST_1 ********/ -#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SID (0x0000F0A0U) -#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_VERSION (1U) -#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SID (0x0000F0A1U) -#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_VERSION (1U) - /******** TFM_SP_PS_TEST ********/ #define TFM_PS_TEST_PREPARE_SID (0x0000F0C0U) #define TFM_PS_TEST_PREPARE_VERSION (1U) @@ -136,40 +125,6 @@ extern "C" { #define TFM_SECURE_CLIENT_2_SID (0x0000F0E0U) #define TFM_SECURE_CLIENT_2_VERSION (1U) -/******** TFM_SP_PSA_PROXY ********/ -#define TFM_CRYPTO_SID (0x00000080U) -#define TFM_CRYPTO_VERSION (1U) -#define TFM_ATTEST_GET_TOKEN_SID (0x00000020U) -#define TFM_ATTEST_GET_TOKEN_VERSION (1U) -#define TFM_ATTEST_GET_TOKEN_SIZE_SID (0x00000021U) -#define TFM_ATTEST_GET_TOKEN_SIZE_VERSION (1U) -#define TFM_ATTEST_GET_PUBLIC_KEY_SID (0x00000022U) -#define TFM_ATTEST_GET_PUBLIC_KEY_VERSION (1U) -#define TFM_ITS_SET_SID (0x00000070U) -#define TFM_ITS_SET_VERSION (1U) -#define TFM_ITS_GET_SID (0x00000071U) -#define TFM_ITS_GET_VERSION (1U) -#define TFM_ITS_GET_INFO_SID (0x00000072U) -#define TFM_ITS_GET_INFO_VERSION (1U) -#define TFM_ITS_REMOVE_SID (0x00000073U) -#define TFM_ITS_REMOVE_VERSION (1U) -#define TFM_SP_PLATFORM_SYSTEM_RESET_SID (0x00000040U) -#define TFM_SP_PLATFORM_SYSTEM_RESET_VERSION (1U) -#define TFM_SP_PLATFORM_IOCTL_SID (0x00000041U) -#define TFM_SP_PLATFORM_IOCTL_VERSION (1U) -#define TFM_SP_PLATFORM_NV_COUNTER_SID (0x00000042U) -#define TFM_SP_PLATFORM_NV_COUNTER_VERSION (1U) -#define TFM_PS_SET_SID (0x00000060U) -#define TFM_PS_SET_VERSION (1U) -#define TFM_PS_GET_SID (0x00000061U) -#define TFM_PS_GET_VERSION (1U) -#define TFM_PS_GET_INFO_SID (0x00000062U) -#define TFM_PS_GET_INFO_VERSION (1U) -#define TFM_PS_REMOVE_SID (0x00000063U) -#define TFM_PS_REMOVE_VERSION (1U) -#define TFM_PS_GET_SUPPORT_SID (0x00000064U) -#define TFM_PS_GET_SUPPORT_VERSION (1U) - /******** TFM_SP_FWU ********/ #define TFM_FWU_WRITE_SID (0x000000A0U) #define TFM_FWU_WRITE_VERSION (1U) @@ -187,13 +142,27 @@ extern "C" { /******** TFM_SP_FFM11 ********/ #define TFM_FFM11_SERVICE1_SID (0x0000F120U) #define TFM_FFM11_SERVICE1_VERSION (1U) -#define TFM_FFM11_SERVICE1_HANDLE (0x40000104U) +#define TFM_FFM11_SERVICE1_HANDLE (0x40000103U) #define TFM_FFM11_SERVICE2_SID (0x0000F121U) #define TFM_FFM11_SERVICE2_VERSION (1U) #define TFM_FFM11_SERVICE2_HANDLE (0x40000101U) #define TFM_FFM11_SERVICE3_SID (0x0000F122U) #define TFM_FFM11_SERVICE3_VERSION (1U) -#define TFM_FFM11_SERVICE3_HANDLE (0x40000103U) +#define TFM_FFM11_SERVICE3_HANDLE (0x40000102U) + +/******** TFM_SP_ATTEST_TEST ********/ +#define TFM_ATTEST_TEST_GET_PUBLIC_KEY_SID (0x0000F140U) +#define TFM_ATTEST_TEST_GET_PUBLIC_KEY_VERSION (1U) + +/******** TFM_SP_SLIH_TEST ********/ +#define TFM_SLIH_TEST_CASE_SID (0x0000F0A0U) +#define TFM_SLIH_TEST_CASE_VERSION (1U) +#define TFM_SLIH_TEST_CASE_HANDLE (0x40000104U) + +/******** TFM_SP_FLIH_TEST ********/ +#define TFM_FLIH_TEST_CASE_SID (0x0000F0B0U) +#define TFM_FLIH_TEST_CASE_VERSION (1U) +#define TFM_FLIH_TEST_CASE_HANDLE (0x40000105U) #ifdef __cplusplus } diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_api.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_api.h index fea18cd59af..1d4c9ee5a7b 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_api.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_api.h @@ -53,6 +53,7 @@ enum tfm_status_e TFM_ERROR_NOT_INITIALIZED, TFM_ERROR_NO_ACTIVE_PARTITION, TFM_ERROR_INVALID_EXC_MODE, + TFM_ERROR_NOT_IN_RANGE, TFM_SECURE_LOCK_FAILED, TFM_SECURE_UNLOCK_FAILED, TFM_ERROR_GENERIC = 0x1F, @@ -112,17 +113,17 @@ psa_handle_t tfm_psa_connect_veneer(uint32_t sid, uint32_t version); * \brief Call a secure function referenced by a connection handle. * * \param[in] handle Handle to connection. - * \param[in] ctrl_param Parameter structure, includes request type, - * in_num and out_num. + * \param[in] ctrl_param Parameters combined in uint32_t, + * includes request type, in_num and out_num. * \param[in] in_vec Array of input \ref psa_invec structures. * \param[in,out] out_vec Array of output \ref psa_outvec structures. * * \return Returns \ref psa_status_t status code. */ psa_status_t tfm_psa_call_veneer(psa_handle_t handle, - const struct tfm_control_parameter_t *ctrl_param, - const psa_invec *in_vec, - psa_outvec *out_vec); + uint32_t ctrl_param, + const psa_invec *in_vec, + psa_outvec *out_vec); /** * \brief Close connection to secure function referenced by a connection handle. diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_crypto_defs.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_crypto_defs.h index b4c771f2dff..5a860b8378b 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_crypto_defs.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_crypto_defs.h @@ -103,6 +103,8 @@ enum { TFM_CRYPTO_AEAD_FINISH_SID, TFM_CRYPTO_AEAD_VERIFY_SID, TFM_CRYPTO_AEAD_ABORT_SID, + TFM_CRYPTO_SIGN_MESSAGE_SID, + TFM_CRYPTO_VERIFY_MESSAGE_SID, TFM_CRYPTO_SIGN_HASH_SID, TFM_CRYPTO_VERIFY_HASH_SID, TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SID, diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_ns_interface.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_ns_interface.h index 1dd06925718..fa0cc31746c 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_ns_interface.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_ns_interface.h @@ -24,11 +24,14 @@ typedef int32_t (*veneer_fn) (uint32_t arg0, uint32_t arg1, * desired veneer function, to be called with the parameters * described from arg0 to arg3. * + * \note NSPE shall implement this dispatcher according to NS specific + * implementation and actual usage scenario. + * * \param[in] fn Function pointer to the veneer function desired - * \param[in] arg0 Argument 0 - * \param[in] arg1 Argument 1 - * \param[in] arg2 Argument 2 - * \param[in] arg3 Argument 3 + * \param[in] arg0 Argument 0 of fn + * \param[in] arg1 Argument 1 of fn + * \param[in] arg2 Argument 2 of fn + * \param[in] arg3 Argument 3 of fn * * \return Returns the same return value of the requested veneer function * @@ -40,17 +43,6 @@ int32_t tfm_ns_interface_dispatch(veneer_fn fn, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3); -/** - * \brief NS interface, Initialise the NS interface - * - * \details This function needs to be called from the NS world to - * properly initialise the NS interface towards TF-M. This - * function will initialise all the objects required for - * runtime dispatching of TF-M requests to services - * - * \return A value according to \ref enum tfm_status_e - */ -enum tfm_status_e tfm_ns_interface_init(void); #ifdef __cplusplus } #endif diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_psa_call_param.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_psa_call_param.h new file mode 100644 index 00000000000..ed51da7a608 --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/tfm_psa_call_param.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __TFM_PSA_CALL_PARAM_H__ +#define __TFM_PSA_CALL_PARAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define TYPE_OFFSET 16U +#define TYPE_MASK (0xFFFFUL << TYPE_OFFSET) +#define IN_LEN_OFFSET 8U +#define IN_LEN_MASK (0xFFUL << IN_LEN_OFFSET) +#define OUT_LEN_OFFSET 0U +#define OUT_LEN_MASK (0xFFUL << OUT_LEN_OFFSET) + +#define PARAM_PACK(type, in_len, out_len) \ + (((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK) | \ + ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK) | \ + ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK)) + +#ifdef __cplusplus +} +#endif + +#endif /* __TFM_PSA_CALL_PARAM_H__ */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_crypto_ipc_api.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_crypto_ipc_api.c index a89dd2b9ca7..9dfa4737ecf 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_crypto_ipc_api.c +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_crypto_ipc_api.c @@ -11,25 +11,14 @@ #include "psa_manifest/sid.h" #include "psa/client.h" -#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) - -#define PSA_CONNECT(service) \ - psa_handle_t ipc_handle; \ - ipc_handle = psa_connect(service##_SID, service##_VERSION); \ - if (!PSA_HANDLE_IS_VALID(ipc_handle)) { \ - return PSA_ERROR_GENERIC_ERROR; \ - } \ - -#define PSA_CLOSE() psa_close(ipc_handle) - #define API_DISPATCH(sfn_name, sfn_id) \ - psa_call(ipc_handle, PSA_IPC_CALL, \ - in_vec, ARRAY_SIZE(in_vec), \ - out_vec, ARRAY_SIZE(out_vec)) + psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, \ + in_vec, IOVEC_LEN(in_vec), \ + out_vec, IOVEC_LEN(out_vec)) #define API_DISPATCH_NO_OUTVEC(sfn_name, sfn_id) \ - psa_call(ipc_handle, PSA_IPC_CALL, \ - in_vec, ARRAY_SIZE(in_vec), \ + psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, \ + in_vec, IOVEC_LEN(in_vec), \ (psa_outvec *)NULL, 0) psa_status_t psa_crypto_init(void) @@ -55,13 +44,9 @@ psa_status_t psa_open_key(psa_key_id_t id, {.base = key, .len = sizeof(psa_key_id_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_open_key, TFM_CRYPTO_OPEN_KEY); - PSA_CLOSE(); - return status; } @@ -76,13 +61,9 @@ psa_status_t psa_close_key(psa_key_id_t key) {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH_NO_OUTVEC(tfm_crypto_close_key, TFM_CRYPTO_CLOSE_KEY);; - PSA_CLOSE(); - return status; } @@ -104,11 +85,8 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes, {.base = key, .len = sizeof(psa_key_id_t)} }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_import_key, TFM_CRYPTO_IMPORT_KEY); - PSA_CLOSE(); return status; } @@ -124,11 +102,8 @@ psa_status_t psa_destroy_key(psa_key_id_t key) {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH_NO_OUTVEC(tfm_crypto_destroy_key, TFM_CRYPTO_DESTROY_KEY); - PSA_CLOSE(); return status; } @@ -148,11 +123,8 @@ psa_status_t psa_get_key_attributes(psa_key_id_t key, {.base = attributes, .len = sizeof(psa_key_attributes_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_get_key_attributes, TFM_CRYPTO_GET_KEY_ATTRIBUTES); - PSA_CLOSE(); return status; } @@ -169,15 +141,8 @@ void psa_reset_key_attributes(psa_key_attributes_t *attributes) {.base = attributes, .len = sizeof(psa_key_attributes_t)}, }; - psa_handle_t ipc_handle; - ipc_handle = psa_connect(TFM_CRYPTO_SID, TFM_CRYPTO_VERSION); - if (!PSA_HANDLE_IS_VALID(ipc_handle)) { - return; - } - (void)API_DISPATCH(tfm_crypto_reset_key_attributes, - TFM_CRYPTO_RESET_KEY_ATTRIBUTES); - PSA_CLOSE(); + TFM_CRYPTO_RESET_KEY_ATTRIBUTES); return; } @@ -199,15 +164,11 @@ psa_status_t psa_export_key(psa_key_id_t key, {.base = data, .len = data_size} }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_export_key, TFM_CRYPTO_EXPORT_KEY); *data_length = out_vec[0].len; - PSA_CLOSE(); - return status; } @@ -229,15 +190,11 @@ psa_status_t psa_export_public_key(psa_key_id_t key, {.base = data, .len = data_size} }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_export_public_key, TFM_CRYPTO_EXPORT_PUBLIC_KEY); *data_length = out_vec[0].len; - PSA_CLOSE(); - return status; } @@ -252,13 +209,9 @@ psa_status_t psa_purge_key(psa_key_id_t key) {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH_NO_OUTVEC(tfm_crypto_purge_key, TFM_CRYPTO_PURGE_KEY); - PSA_CLOSE(); - return status; } @@ -282,13 +235,9 @@ psa_status_t psa_copy_key(psa_key_id_t source_key, {.base = target_key, .len = sizeof(psa_key_id_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_copy_key, TFM_CRYPTO_COPY_KEY); - PSA_CLOSE(); - return status; } @@ -311,15 +260,11 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, {.base = iv, .len = iv_size}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_cipher_generate_iv, TFM_CRYPTO_CIPHER_GENERATE_IV); *iv_length = out_vec[1].len; - PSA_CLOSE(); - return status; } @@ -341,13 +286,9 @@ psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_cipher_set_iv, TFM_CRYPTO_CIPHER_SET_IV); - PSA_CLOSE(); - return status; } @@ -370,13 +311,9 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_cipher_encrypt_setup, TFM_CRYPTO_CIPHER_ENCRYPT_SETUP); - PSA_CLOSE(); - return status; } @@ -399,13 +336,9 @@ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_cipher_decrypt_setup, TFM_CRYPTO_CIPHER_DECRYPT_SETUP); - PSA_CLOSE(); - return status; } @@ -431,15 +364,11 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, {.base = output, .len = output_size} }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_cipher_update, TFM_CRYPTO_CIPHER_UPDATE); *output_length = out_vec[1].len; - PSA_CLOSE(); - return status; } @@ -458,13 +387,9 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation) {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_cipher_abort, TFM_CRYPTO_CIPHER_ABORT); - PSA_CLOSE(); - return status; } @@ -487,15 +412,11 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, {.base = output, .len = output_size}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_cipher_finish, TFM_CRYPTO_CIPHER_FINISH); *output_length = out_vec[1].len; - PSA_CLOSE(); - return status; } @@ -516,13 +437,9 @@ psa_status_t psa_hash_setup(psa_hash_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_hash_setup, TFM_CRYPTO_HASH_SETUP); - PSA_CLOSE(); - return status; } @@ -544,13 +461,9 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_hash_update, TFM_CRYPTO_HASH_UPDATE); - PSA_CLOSE(); - return status; } @@ -573,15 +486,11 @@ psa_status_t psa_hash_finish(psa_hash_operation_t *operation, {.base = hash, .len = hash_size}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_hash_finish, TFM_CRYPTO_HASH_FINISH); *hash_length = out_vec[1].len; - PSA_CLOSE(); - return status; } @@ -603,13 +512,9 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_hash_verify, TFM_CRYPTO_HASH_VERIFY); - PSA_CLOSE(); - return status; } @@ -628,13 +533,9 @@ psa_status_t psa_hash_abort(psa_hash_operation_t *operation) {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_hash_abort, TFM_CRYPTO_HASH_ABORT); - PSA_CLOSE(); - return status; } @@ -658,13 +559,9 @@ psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, return PSA_ERROR_BAD_STATE; } - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_hash_clone, TFM_CRYPTO_HASH_CLONE); - PSA_CLOSE(); - return status; } @@ -690,15 +587,11 @@ psa_status_t psa_hash_compute(psa_algorithm_t alg, {.base = hash, .len = hash_size} }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_hash_compute, TFM_CRYPTO_HASH_COMPUTE); *hash_length = out_vec[0].len; - PSA_CLOSE(); - return status; } @@ -720,13 +613,9 @@ psa_status_t psa_hash_compare(psa_algorithm_t alg, {.base = hash, .len = hash_length}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH_NO_OUTVEC(tfm_crypto_hash_compare, TFM_CRYPTO_HASH_COMPARE); - PSA_CLOSE(); - return status; } @@ -749,13 +638,9 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_mac_sign_setup, TFM_CRYPTO_MAC_SIGN_SETUP); - PSA_CLOSE(); - return status; } @@ -778,13 +663,9 @@ psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_mac_verify_setup, TFM_CRYPTO_MAC_VERIFY_SETUP); - PSA_CLOSE(); - return status; } @@ -806,13 +687,9 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_mac_update, TFM_CRYPTO_MAC_UPDATE); - PSA_CLOSE(); - return status; } @@ -835,15 +712,11 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, {.base = mac, .len = mac_size}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_mac_sign_finish, TFM_CRYPTO_MAC_SIGN_FINISH); *mac_length = out_vec[1].len; - PSA_CLOSE(); - return status; } @@ -865,13 +738,9 @@ psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_mac_verify_finish, TFM_CRYPTO_MAC_VERIFY_FINISH); - PSA_CLOSE(); - return status; } @@ -890,13 +759,9 @@ psa_status_t psa_mac_abort(psa_mac_operation_t *operation) {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_mac_abort, TFM_CRYPTO_MAC_ABORT); - PSA_CLOSE(); - return status; } @@ -945,19 +810,15 @@ psa_status_t psa_aead_encrypt(psa_key_id_t key, } } - PSA_CONNECT(TFM_CRYPTO); - - size_t in_len = ARRAY_SIZE(in_vec); + size_t in_len = IOVEC_LEN(in_vec); if (additional_data == NULL) { in_len--; } - status = psa_call(ipc_handle, PSA_IPC_CALL, in_vec, in_len, - out_vec, ARRAY_SIZE(out_vec)); + status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len, + out_vec, IOVEC_LEN(out_vec)); *ciphertext_length = out_vec[0].len; - PSA_CLOSE(); - return status; } @@ -1006,31 +867,75 @@ psa_status_t psa_aead_decrypt(psa_key_id_t key, } } - PSA_CONNECT(TFM_CRYPTO); - - size_t in_len = ARRAY_SIZE(in_vec); + size_t in_len = IOVEC_LEN(in_vec); if (additional_data == NULL) { in_len--; } - status = psa_call(ipc_handle, PSA_IPC_CALL, in_vec, in_len, - out_vec, ARRAY_SIZE(out_vec)); + status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len, + out_vec, IOVEC_LEN(out_vec)); *plaintext_length = out_vec[0].len; - PSA_CLOSE(); + return status; +} + +psa_status_t psa_sign_message(psa_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length) +{ + psa_status_t status; + struct tfm_crypto_pack_iovec iov = { + .sfn_id = TFM_CRYPTO_SIGN_MESSAGE_SID, + .key_id = key, + .alg = alg, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = input, .len = input_length}, + }; + psa_outvec out_vec[] = { + {.base = signature, .len = signature_size}, + }; + + status = API_DISPATCH(tfm_crypto_sign_message, + TFM_CRYPTO_SIGN_MESSAGE); + + if (status == PSA_SUCCESS) { + *signature_length = out_vec[0].len; + } return status; } -psa_status_t psa_asymmetric_sign(psa_key_id_t key, - psa_algorithm_t alg, - const uint8_t *hash, - size_t hash_length, - uint8_t *signature, - size_t signature_size, - size_t *signature_length) +psa_status_t psa_verify_message(psa_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *signature, + size_t signature_length) { - return psa_sign_hash(key, alg, hash, hash_length, signature, signature_size, signature_length); + psa_status_t status; + struct tfm_crypto_pack_iovec iov = { + .sfn_id = TFM_CRYPTO_VERIFY_MESSAGE_SID, + .key_id = key, + .alg = alg + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = input, .len = input_length}, + {.base = signature, .len = signature_length} + }; + + status = API_DISPATCH_NO_OUTVEC(tfm_crypto_verify_message, + TFM_CRYPTO_VERIFY_MESSAGE); + + return status; } psa_status_t psa_sign_hash(psa_key_id_t key, @@ -1056,28 +961,14 @@ psa_status_t psa_sign_hash(psa_key_id_t key, {.base = signature, .len = signature_size}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_sign_hash, TFM_CRYPTO_SIGN_HASH); *signature_length = out_vec[0].len; - PSA_CLOSE(); - return status; } -psa_status_t psa_asymmetric_verify(psa_key_id_t key, - psa_algorithm_t alg, - const uint8_t *hash, - size_t hash_length, - const uint8_t *signature, - size_t signature_length) -{ - return psa_verify_hash(key, alg, hash, hash_length, signature, signature_length); -} - psa_status_t psa_verify_hash(psa_key_id_t key, psa_algorithm_t alg, const uint8_t *hash, @@ -1098,13 +989,9 @@ psa_status_t psa_verify_hash(psa_key_id_t key, {.base = signature, .len = signature_length} }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH_NO_OUTVEC(tfm_crypto_verify_hash, TFM_CRYPTO_VERIFY_HASH); - PSA_CLOSE(); - return status; } @@ -1140,19 +1027,15 @@ psa_status_t psa_asymmetric_encrypt(psa_key_id_t key, {.base = output, .len = output_size}, }; - PSA_CONNECT(TFM_CRYPTO); - - size_t in_len = ARRAY_SIZE(in_vec); + size_t in_len = IOVEC_LEN(in_vec); if (salt == NULL) { in_len--; } - status = psa_call(ipc_handle, PSA_IPC_CALL, in_vec, in_len, - out_vec, ARRAY_SIZE(out_vec)); + status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len, + out_vec, IOVEC_LEN(out_vec)); *output_length = out_vec[0].len; - PSA_CLOSE(); - return status; } @@ -1188,19 +1071,15 @@ psa_status_t psa_asymmetric_decrypt(psa_key_id_t key, {.base = output, .len = output_size}, }; - PSA_CONNECT(TFM_CRYPTO); - - size_t in_len = ARRAY_SIZE(in_vec); + size_t in_len = IOVEC_LEN(in_vec); if (salt == NULL) { in_len--; } - status = psa_call(ipc_handle, PSA_IPC_CALL, in_vec, in_len, - out_vec, ARRAY_SIZE(out_vec)); + status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len, + out_vec, IOVEC_LEN(out_vec)); *output_length = out_vec[0].len; - PSA_CLOSE(); - return status; } @@ -1222,13 +1101,9 @@ psa_status_t psa_key_derivation_get_capacity( {.base = capacity, .len = sizeof(size_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_key_derivation_get_capacity, TFM_CRYPTO_KEY_DERIVATION_GET_CAPACITY); - PSA_CLOSE(); - return status; } @@ -1251,13 +1126,9 @@ psa_status_t psa_key_derivation_output_bytes( {.base = output, .len = output_length}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_key_derivation_output_bytes, TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES); - PSA_CLOSE(); - return status; } @@ -1278,13 +1149,9 @@ psa_status_t psa_key_derivation_input_key( {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH_NO_OUTVEC(tfm_crypto_key_derivation_input_key, TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY); - PSA_CLOSE(); - return status; } @@ -1305,13 +1172,9 @@ psa_status_t psa_key_derivation_abort( {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_key_derivation_abort, TFM_CRYPTO_KEY_DERIVATION_ABORT); - PSA_CLOSE(); - return status; } @@ -1335,13 +1198,9 @@ psa_status_t psa_key_derivation_key_agreement( {.base = peer_key, .len = peer_key_length}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH_NO_OUTVEC(tfm_crypto_key_derivation_key_agreement, TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT); - PSA_CLOSE(); - return status; } @@ -1365,13 +1224,9 @@ psa_status_t psa_generate_random(uint8_t *output, return PSA_SUCCESS; } - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_generate_random, TFM_CRYPTO_GENERATE_RANDOM); - PSA_CLOSE(); - return status; } @@ -1392,36 +1247,8 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, {.base = key, .len = sizeof(psa_key_id_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_generate_key, TFM_CRYPTO_GENERATE_KEY); - PSA_CLOSE(); - - return status; -} - -psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes, - psa_key_type_t type, - const uint8_t *data, - size_t data_length) -{ - psa_status_t status; - - status = PSA_ERROR_NOT_SUPPORTED; - - return status; -} - -psa_status_t psa_get_key_domain_parameters( - const psa_key_attributes_t *attributes, - uint8_t *data, - size_t data_size, - size_t *data_length) -{ - psa_status_t status; - - status = PSA_ERROR_NOT_SUPPORTED; return status; } @@ -1484,8 +1311,26 @@ psa_status_t psa_mac_compute(psa_key_id_t key, size_t *mac_length) { psa_status_t status; + struct tfm_crypto_pack_iovec iov = { + .sfn_id = TFM_CRYPTO_MAC_COMPUTE_SID, + .key_id = key, + .alg = alg, + }; - status = PSA_ERROR_NOT_SUPPORTED; + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = input, .len = input_length}, + }; + psa_outvec out_vec[] = { + {.base = mac, .len = mac_size}, + }; + + status = API_DISPATCH(tfm_crypto_mac_compute, + TFM_CRYPTO_MAC_COMPUTE); + + if (status == PSA_SUCCESS) { + *mac_length = out_vec[0].len; + } return status; } @@ -1498,8 +1343,20 @@ psa_status_t psa_mac_verify(psa_key_id_t key, const size_t mac_length) { psa_status_t status; + struct tfm_crypto_pack_iovec iov = { + .sfn_id = TFM_CRYPTO_MAC_VERIFY_SID, + .key_id = key, + .alg = alg, + }; - status = PSA_ERROR_NOT_SUPPORTED; + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = input, .len = input_length}, + {.base = mac, .len = mac_length}, + }; + + status = API_DISPATCH_NO_OUTVEC(tfm_crypto_mac_verify, + TFM_CRYPTO_MAC_VERIFY); return status; } @@ -1513,8 +1370,26 @@ psa_status_t psa_cipher_encrypt(psa_key_id_t key, size_t *output_length) { psa_status_t status; + struct tfm_crypto_pack_iovec iov = { + .sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SID, + .key_id = key, + .alg = alg, + }; - status = PSA_ERROR_NOT_SUPPORTED; + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = input, .len = input_length}, + }; + psa_outvec out_vec[] = { + {.base = output, .len = output_size} + }; + + status = API_DISPATCH(tfm_crypto_cipher_encrypt, + TFM_CRYPTO_CIPHER_ENCRYPT); + + if (status == PSA_SUCCESS) { + *output_length = out_vec[0].len; + } return status; } @@ -1528,8 +1403,26 @@ psa_status_t psa_cipher_decrypt(psa_key_id_t key, size_t *output_length) { psa_status_t status; + struct tfm_crypto_pack_iovec iov = { + .sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SID, + .key_id = key, + .alg = alg, + }; - status = PSA_ERROR_NOT_SUPPORTED; + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = input, .len = input_length}, + }; + psa_outvec out_vec[] = { + {.base = output, .len = output_size} + }; + + status = API_DISPATCH(tfm_crypto_cipher_decrypt, + TFM_CRYPTO_CIPHER_DECRYPT); + + if (status == PSA_SUCCESS) { + *output_length = out_vec[0].len; + } return status; } @@ -1558,15 +1451,11 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, {.base = output, .len = output_size}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_raw_key_agreement, TFM_CRYPTO_RAW_KEY_AGREEMENT); *output_length = out_vec[0].len; - PSA_CLOSE(); - return status; } @@ -1587,11 +1476,8 @@ psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation, {.base = &(operation->handle), .len = sizeof(uint32_t)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_key_derivation_setup, TFM_CRYPTO_KEY_DERIVATION_SETUP); - PSA_CLOSE(); return status; } @@ -1611,11 +1497,8 @@ psa_status_t psa_key_derivation_set_capacity( {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH_NO_OUTVEC(tfm_crypto_key_derivation_set_capacity, TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY); - PSA_CLOSE(); return status; } @@ -1638,11 +1521,8 @@ psa_status_t psa_key_derivation_input_bytes( {.base = data, .len = data_length}, }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH_NO_OUTVEC(tfm_crypto_key_derivation_input_bytes, TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES); - PSA_CLOSE(); return status; } @@ -1667,11 +1547,8 @@ psa_status_t psa_key_derivation_output_key( {.base = key, .len = sizeof(psa_key_id_t)} }; - PSA_CONNECT(TFM_CRYPTO); - status = API_DISPATCH(tfm_crypto_key_derivation_output_key, TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY); - PSA_CLOSE(); return status; } diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_firmware_update_ipc_api.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_firmware_update_ipc_api.c index 0118488f572..60d4b2e6d07 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_firmware_update_ipc_api.c +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_firmware_update_ipc_api.c @@ -5,13 +5,10 @@ * */ -#include "psa/update.h" -#include "tfm_api.h" - #include "psa/client.h" +#include "psa/update.h" #include "psa_manifest/sid.h" - -#define IOVEC_LEN(x) (uint32_t)(sizeof(x)/sizeof(x[0])) +#include "tfm_api.h" psa_status_t psa_fwu_write(const psa_image_id_t image_id, size_t block_offset, @@ -158,10 +155,13 @@ psa_status_t psa_fwu_request_reboot(void) return status; } -psa_status_t psa_fwu_accept(void) +psa_status_t psa_fwu_accept(psa_image_id_t image_id) { psa_handle_t handle; psa_status_t status; + psa_invec in_vec[] = { + { .base = &image_id, .len = sizeof(image_id) } + }; handle = psa_connect(TFM_FWU_ACCEPT_SID, TFM_FWU_ACCEPT_VERSION); @@ -169,7 +169,7 @@ psa_status_t psa_fwu_accept(void) return PSA_ERROR_GENERIC_ERROR; } - status = psa_call(handle, PSA_IPC_CALL, NULL, 0, NULL, 0); + status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), NULL, 0); psa_close(handle); diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_initial_attestation_ipc_api.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_initial_attestation_ipc_api.c index b4a8f379e3e..43c9b0e4791 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_initial_attestation_ipc_api.c +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_initial_attestation_ipc_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, Arm Limited. All rights reserved. + * Copyright (c) 2018-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -11,8 +11,6 @@ #include "psa/crypto_types.h" #include "psa_manifest/sid.h" -#define IOVEC_LEN(x) (sizeof(x)/sizeof(x[0])) - psa_status_t psa_initial_attest_get_token(const uint8_t *auth_challenge, size_t challenge_size, @@ -74,32 +72,3 @@ psa_initial_attest_get_token_size(size_t challenge_size, return status; } - -psa_status_t -tfm_initial_attest_get_public_key(uint8_t *public_key, - size_t public_key_buf_size, - size_t *public_key_len, - psa_ecc_family_t *elliptic_curve_type) -{ - psa_handle_t handle = PSA_NULL_HANDLE; - psa_status_t status; - - psa_outvec out_vec[] = { - {.base = public_key, .len = public_key_buf_size}, - {.base = elliptic_curve_type, .len = sizeof(*elliptic_curve_type)}, - {.base = public_key_len, .len = sizeof(*public_key_len)} - }; - - handle = psa_connect(TFM_ATTEST_GET_PUBLIC_KEY_SID, - TFM_ATTEST_GET_PUBLIC_KEY_VERSION); - if (!PSA_HANDLE_IS_VALID(handle)) { - return PSA_HANDLE_TO_ERROR(handle); - } - - status = psa_call(handle, PSA_IPC_CALL, - NULL, 0, - out_vec, IOVEC_LEN(out_vec)); - psa_close(handle); - - return status; -} diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_its_ipc_api.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_its_ipc_api.c index 8ad4a3bbb30..543b88f3d1b 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_its_ipc_api.c +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_its_ipc_api.c @@ -1,17 +1,14 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * */ -#include "psa/internal_trusted_storage.h" -#include "tfm_api.h" - #include "psa/client.h" +#include "psa/internal_trusted_storage.h" #include "psa_manifest/sid.h" - -#define IOVEC_LEN(x) (sizeof(x)/sizeof(x[0])) +#include "tfm_api.h" psa_status_t psa_its_set(psa_storage_uid_t uid, size_t data_length, diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_ps_ipc_api.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_ps_ipc_api.c index 4f937db2d03..106917e9bc2 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_ps_ipc_api.c +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_ps_ipc_api.c @@ -1,16 +1,14 @@ /* - * Copyright (c) 2017-2020, Arm Limited. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * */ +#include "psa/client.h" #include "psa/protected_storage.h" - -#include "tfm_ns_interface.h" #include "psa_manifest/sid.h" - -#define IOVEC_LEN(x) (uint32_t)(sizeof(x)/sizeof(x[0])) +#include "tfm_ns_interface.h" psa_status_t psa_ps_set(psa_storage_uid_t uid, size_t data_length, diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/CMakeLists.txt b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/CMakeLists.txt index a0e87f6a5c5..6bf70547903 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/CMakeLists.txt +++ b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/CMakeLists.txt @@ -43,6 +43,7 @@ target_sources(mbed-arm-musca-b1 serial_api.c sleep_api.c tfm_ioctl_ns_api.c + tfm_ns_interface.c us_ticker.c device/device_definition.c diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/bl2.bin b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/bl2.bin index dd45d614582..388b8140dd1 100644 Binary files a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/bl2.bin and b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/bl2.bin differ diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/device/TOOLCHAIN_ARMC6/musca_ns.sct b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/device/TOOLCHAIN_ARMC6/musca_ns.sct index c85746cb107..d5a58d417e3 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/device/TOOLCHAIN_ARMC6/musca_ns.sct +++ b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/device/TOOLCHAIN_ARMC6/musca_ns.sct @@ -18,6 +18,10 @@ * limitations under the License. */ +#if !defined(BL2) + #define BL2 +#endif + #include "../../partition/region_defs.h" #include "../cmsis_nvic.h" diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/partition/flash_layout.h b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/partition/flash_layout.h index 6b7a67abadb..34c23f4fa95 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/partition/flash_layout.h +++ b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/partition/flash_layout.h @@ -20,7 +20,11 @@ #ifndef __FLASH_LAYOUT_H__ #define __FLASH_LAYOUT_H__ -/* Flash layout on Musca-B1 with BL2 (multiple image boot, boot from eFlash 0): +#ifndef FORWARD_PROT_MSG +/* Flash layouts if FORWARD_PROT_MSG is OFF + * + * + * Flash layout on Musca-B1 with BL2 (multiple image boot, boot from eFlash 0): * * 0x0A00_0000 BL2 - MCUBoot (128 KB) * 0x0A02_0000 Secure image primary slot (384 KB) @@ -81,7 +85,6 @@ #define QSPI_FLASH_TOTAL_SIZE (0x800000) /* 8 MB */ /* Flash layout info for BL2 bootloader */ -/* Same as MUSCA_B1_EFLASH0_S_BASE */ #define FLASH_BASE_ADDRESS (0x1A000000) /* Offset and size definitions of the flash partitions that are handled by the @@ -179,41 +182,39 @@ * Note: Further documentation of these definitions can be found in the * TF-M PS Integration Guide. */ -#define PS_FLASH_DEV_NAME Driver_QSPI_FLASH0 +#define TFM_HAL_PS_FLASH_DRIVER Driver_QSPI_FLASH0 /* In this target the CMSIS driver requires only the offset from the base * address instead of the full memory address. */ -#define PS_FLASH_AREA_ADDR FLASH_PS_AREA_OFFSET -/* Dedicated flash area for PS */ -#define PS_FLASH_AREA_SIZE FLASH_PS_AREA_SIZE -#define PS_RAM_FS_SIZE PS_FLASH_AREA_SIZE -#define PS_SECTOR_SIZE QSPI_FLASH_AREA_IMAGE_SECTOR_SIZE -/* Number of PS_SECTOR_SIZE per block */ -#define PS_SECTORS_PER_BLOCK (0x1) -/* Specifies the smallest flash programmable unit in bytes */ -#define PS_FLASH_PROGRAM_UNIT (0x1) +/* Base address of dedicated flash area for PS */ +#define TFM_HAL_PS_FLASH_AREA_ADDR FLASH_PS_AREA_OFFSET +/* Size of dedicated flash area for PS */ +#define TFM_HAL_PS_FLASH_AREA_SIZE FLASH_PS_AREA_SIZE +#define PS_RAM_FS_SIZE TFM_HAL_PS_FLASH_AREA_SIZE +/* Number of physical erase sectors per logical FS block */ +#define TFM_HAL_PS_SECTORS_PER_BLOCK (1) +/* Smallest flash programmable unit in bytes */ +#define TFM_HAL_PS_PROGRAM_UNIT (0x1) /* Internal Trusted Storage (ITS) Service definitions * Note: Further documentation of these definitions can be found in the - * TF-M ITS Integration Guide. The ITS should be in the internal flash, but is - * allocated in the external flash just for development platforms that don't - * have internal flash available. + * TF-M ITS Integration Guide. */ -#define ITS_FLASH_DEV_NAME Driver_EFLASH0 +#define TFM_HAL_ITS_FLASH_DRIVER Driver_EFLASH0 /* In this target the CMSIS driver requires only the offset from the base * address instead of the full memory address. */ -#define ITS_FLASH_AREA_ADDR FLASH_ITS_AREA_OFFSET -/* Dedicated flash area for ITS */ -#define ITS_FLASH_AREA_SIZE FLASH_ITS_AREA_SIZE -#define ITS_RAM_FS_SIZE ITS_FLASH_AREA_SIZE -#define ITS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE -/* Number of ITS_SECTOR_SIZE per block */ -#define ITS_SECTORS_PER_BLOCK (0x1) -/* Specifies the smallest flash programmable unit in bytes */ -#define ITS_FLASH_PROGRAM_UNIT (0x4) +/* Base address of dedicated flash area for ITS */ +#define TFM_HAL_ITS_FLASH_AREA_ADDR FLASH_ITS_AREA_OFFSET +/* Size of dedicated flash area for ITS */ +#define TFM_HAL_ITS_FLASH_AREA_SIZE FLASH_ITS_AREA_SIZE +#define ITS_RAM_FS_SIZE TFM_HAL_ITS_FLASH_AREA_SIZE +/* Number of physical erase sectors per logical FS block */ +#define TFM_HAL_ITS_SECTORS_PER_BLOCK (1) +/* Smallest flash programmable unit in bytes */ +#define TFM_HAL_ITS_PROGRAM_UNIT (0x4) /* NV Counters definitions */ #define TFM_NV_COUNTERS_AREA_ADDR FLASH_NV_COUNTERS_AREA_OFFSET @@ -232,4 +233,73 @@ #define TOTAL_ROM_SIZE FLASH_TOTAL_SIZE #define TOTAL_RAM_SIZE (0x80000) /* 512 KB */ +#else /* FORWARD_PROT_MSG */ + +/* Flash layout information if FORWARD_PROT_MSG is ON. + * For information you can check Musca-B1 Secure Enclave's flash_layout.h + */ + +#define FLASH_S_PARTITION_SIZE (0x30000) /* S partition: 192 KB */ +#define FLASH_NS_PARTITION_SIZE (0x50000) /* NS partition: 320 KB */ + +/* Offset and size definition in flash area used by assemble.py */ +#define SECURE_IMAGE_OFFSET (0x0) +#define SECURE_IMAGE_MAX_SIZE FLASH_S_PARTITION_SIZE + +#define NON_SECURE_IMAGE_OFFSET (SECURE_IMAGE_OFFSET + \ + SECURE_IMAGE_MAX_SIZE) +#define NON_SECURE_IMAGE_MAX_SIZE FLASH_NS_PARTITION_SIZE + +/* Image placed in eFlash 1 */ +#define FLASH_BASE_ADDRESS (0x1A200000) + +#if (MCUBOOT_IMAGE_NUMBER != 1) +#error "If FORWARD_PROT_MSG is ON MCUBOOT_IMAGE_NUMBER must be 1" +#endif + +/* Secure + Non-secure image primary slot */ +#define FLASH_AREA_0_ID (1) +#define FLASH_AREA_0_OFFSET (0x60000) /* Address comes from SE */ +#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE + \ + FLASH_NS_PARTITION_SIZE) +/* Secure + Non-secure secondary slot */ +#define FLASH_AREA_2_ID (FLASH_AREA_0_ID + 1) +#define FLASH_AREA_2_OFFSET (0x160000) /* Address comes from SE */ +#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE + \ + FLASH_NS_PARTITION_SIZE) + +/* Image placed in eFlash 1 */ +#define S_ROM_ALIAS_BASE (0x1A200000) +#define NS_ROM_ALIAS_BASE (0x0A200000) + +#define S_RAM_ALIAS_BASE (0x30000000) +#define NS_RAM_ALIAS_BASE (0x20000000) + +#define TOTAL_RAM_SIZE (0x80000) /* 512 KB */ + +/* Macros needed for BL2 build with dummy values. + * This BL2 instance is not used, but the BL2 macro needs to be set, and this + * macro and BL2 build is entangled. If this is fixed the following macros can + * be deleted. + */ +#define FLASH_AREA_IMAGE_SECTOR_SIZE 0 + +#define MCUBOOT_STATUS_MAX_ENTRIES 0 +#define MCUBOOT_MAX_IMG_SECTORS 32 + +#define FLASH_AREA_SCRATCH_ID 0 +#define FLASH_AREA_SCRATCH_OFFSET 0 +#define FLASH_AREA_SCRATCH_SIZE 0 + +#define FLASH_DEV_NAME Driver_EFLASH0 +#define FLASH_AREA_BL2_OFFSET 0 +#define FLASH_AREA_BL2_SIZE 0x20000 + +#define TFM_NV_COUNTERS_AREA_ADDR 0 +#define TFM_NV_COUNTERS_AREA_SIZE 8 +#define TFM_NV_COUNTERS_SECTOR_ADDR 0 +#define TFM_NV_COUNTERS_SECTOR_SIZE 8 + +#endif /* FORWARD_PROT_MSG */ + #endif /* __FLASH_LAYOUT_H__ */ diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/partition/region_defs.h b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/partition/region_defs.h index 291c9489d33..196cdc17f86 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/partition/region_defs.h +++ b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/partition/region_defs.h @@ -21,10 +21,6 @@ #include "flash_layout.h" -#ifndef BL2 -#define BL2 -#endif - #define BL2_HEAP_SIZE (0x0001000) #define BL2_MSP_STACK_SIZE (0x0001800) @@ -89,7 +85,7 @@ #define IMAGE_NS_CODE_SIZE \ (FLASH_NS_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE) -#define CMSE_VENEER_REGION_SIZE (0x340) +#define CMSE_VENEER_REGION_SIZE (0x380) /* Alias definitions for secure and non-secure areas*/ #define S_ROM_ALIAS(x) (S_ROM_ALIAS_BASE + (x)) @@ -112,6 +108,12 @@ /* CMSE Veneers region */ #define CMSE_VENEER_REGION_START (S_CODE_LIMIT + 1) +/* Shared memory used by PSA Proxy partition */ +#ifdef TFM_PARTITION_PSA_PROXY +#define PSA_PROXY_SHARED_MEMORY_BASE (0x1A408000) +#define PSA_PROXY_SHARED_MEMORY_SIZE (0x00078000) /* 476 KiB */ +#endif /* TFM_PARTITION_PSA_PROXY */ + /* Non-secure regions */ #define NS_IMAGE_PRIMARY_AREA_OFFSET \ (NS_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE) @@ -157,11 +159,23 @@ #define BL2_DATA_LIMIT (BL2_DATA_START + BL2_DATA_SIZE - 1) #endif /* BL2 */ +/* Shared symbol area between bootloader and runtime firmware. Global variables + * in the shared code can be placed here. + */ +#ifdef CODE_SHARING +#define SHARED_SYMBOL_AREA_BASE S_RAM_ALIAS_BASE +#define SHARED_SYMBOL_AREA_SIZE 0x20 +#else +#define SHARED_SYMBOL_AREA_BASE S_RAM_ALIAS_BASE +#define SHARED_SYMBOL_AREA_SIZE 0x0 +#endif /* CODE_SHARING */ + /* Shared data area between bootloader and runtime firmware. - * Shared data area is allocated at the beginning of the RAM, it is overlapping + * These areas are allocated at the beginning of the RAM, it is overlapping * with TF-M Secure code's MSP stack */ -#define BOOT_TFM_SHARED_DATA_BASE S_RAM_ALIAS_BASE +#define BOOT_TFM_SHARED_DATA_BASE (SHARED_SYMBOL_AREA_BASE + \ + SHARED_SYMBOL_AREA_SIZE) #define BOOT_TFM_SHARED_DATA_SIZE (0x400) #define BOOT_TFM_SHARED_DATA_LIMIT (BOOT_TFM_SHARED_DATA_BASE + \ BOOT_TFM_SHARED_DATA_SIZE - 1) diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/s_veneers.o b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/s_veneers.o index eac7c5297e3..5b966265d6a 100644 Binary files a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/s_veneers.o and b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/s_veneers.o differ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_ns_interface.c b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_ns_interface.c similarity index 82% rename from platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_ns_interface.c rename to targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_ns_interface.c index 2f745c23f26..3bd401bcaa6 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_ns_interface.c +++ b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_ns_interface.c @@ -5,11 +5,9 @@ * */ #include -#include #include "os_wrapper/mutex.h" -#include "tfm_api.h" #include "tfm_ns_interface.h" /** @@ -17,7 +15,6 @@ */ static void *ns_lock_handle = NULL; -__attribute__((weak)) int32_t tfm_ns_interface_dispatch(veneer_fn fn, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3) @@ -35,16 +32,15 @@ int32_t tfm_ns_interface_dispatch(veneer_fn fn, return result; } -__attribute__((weak)) -enum tfm_status_e tfm_ns_interface_init(void) +uint32_t tfm_ns_interface_init(void) { void *handle; handle = os_wrapper_mutex_create(); if (!handle) { - return TFM_ERROR_GENERIC; + return OS_WRAPPER_ERROR; } ns_lock_handle = handle; - return TFM_SUCCESS; + return OS_WRAPPER_SUCCESS; } diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_s.axf b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_s.axf index e58594265b3..6a257403c46 100644 Binary files a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_s.axf and b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_s.axf differ diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_s.bin b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_s.bin index 8aeaa45d1d6..6a2bf1ac1cd 100644 Binary files a/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_s.bin and b/targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/tfm_s.bin differ diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/CMakeLists.txt b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/CMakeLists.txt index 559ba43a7bc..5e89026a9d3 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/CMakeLists.txt +++ b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/CMakeLists.txt @@ -45,6 +45,7 @@ target_sources(mbed-arm-musca-s1 serial_api.c sleep_api.c tfm_ioctl_ns_api.c + tfm_ns_interface.c us_ticker.c device/device_definition.c diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/bl2.bin b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/bl2.bin index f9e66202190..dae0d587380 100644 Binary files a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/bl2.bin and b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/bl2.bin differ diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/device/TOOLCHAIN_ARMC6/musca_ns.sct b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/device/TOOLCHAIN_ARMC6/musca_ns.sct index 77554e2d884..27c7c4b4a89 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/device/TOOLCHAIN_ARMC6/musca_ns.sct +++ b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/device/TOOLCHAIN_ARMC6/musca_ns.sct @@ -18,6 +18,10 @@ * limitations under the License. */ +#if !defined(BL2) + #define BL2 +#endif + #include "../../partition/region_defs.h" #include "../cmsis_nvic.h" diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/partition/flash_layout.h b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/partition/flash_layout.h index 5317e2cccef..0cbaa1f70fb 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/partition/flash_layout.h +++ b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/partition/flash_layout.h @@ -27,13 +27,14 @@ * 0x0A10_0000 Secure image secondary (384 KB) * 0x0A16_0000 Non-secure image secondary (512 KB) * 0x0A1E_0000 Scratch Area (16 KB) - * 0x0A1E_4000 Protected Storage Area (20 KB) - * 0x0A1E_9000 Internal Trusted Storage Area (16 KB) - * 0x0A1E_D000 NV counters area (4 KB) - * 0x0A1E_E000 TF-M key area (256 bytes) This area is referred to in - * /lib/ext/cryptocell-312-runtime/shared/hw/include/musca_s1/ \ + * 0x0A1E_4000 Internal Trusted Storage Area (16 KB) + * 0x0A1E_8000 NV counters area (4 KB) + * 0x0A1E_9000 TF-M key area (256 bytes) This area is referred to in + * /lib/ext/cryptocell-312-runtime/shared/hw/include/arm/musca_s1/ \ * dx_reg_base_host.h Do not change one without changing the other. - * 0x0A1E_E100 Unused + * 0x0A1E_9100 Unused + * 0x0020_0000 Protected storage area (20 KB) This area is placed in the QSPI + * flash * * Flash layout on Musca-S1 with BL2(single image boot): * 0x0A00_0000 BL2 - MCUBoot(128 KB) @@ -44,13 +45,14 @@ * 0x0A10_0000 Secure image secondary (384 KB) * 0x0A16_0000 Non-secure image secondary (512 KB) * 0x0A1E_0000 Scratch Area (16 KB) - * 0x0A1E_4000 Protected Storage Area (20 KB) - * 0x0A1E_9000 Internal Trusted Storage Area (16 KB) - * 0x0A1E_D000 NV counters area (4 KB) - * 0x0A1E_E000 TF-M key area (256 bytes) This area is referred to in - * /lib/ext/cryptocell-312-runtime/shared/hw/include/musca_s1/ \ + * 0x0A1E_4000 Internal Trusted Storage Area (16 KB) + * 0x0A1E_8000 NV counters area (4 KB) + * 0x0A1E_9000 TF-M key area (256 bytes) This area is referred to in + * /lib/ext/cryptocell-312-runtime/shared/hw/include/arm/musca_s1/ \ * dx_reg_base_host.h Do not change one without changing the other. - * 0x0A1E_E100 Unused + * 0x0A1E_9100 Unused + * 0x0020_0000 Protected storage area (20 KB) This area is placed in the QSPI + * flash * * Flash layout on Musca-S1 without BL2: * 0x0A00_0000 Secure image @@ -142,17 +144,9 @@ #error "Only MCUBOOT_IMAGE_NUMBER 1 and 2 are supported!" #endif /* MCUBOOT_IMAGE_NUMBER */ -/* Note: FLASH_PS_AREA_OFFSET, FLASH_ITS_AREA_OFFSET and - * FLASH_NV_COUNTERS_AREA_OFFSET point to offsets in flash, but reads and writes - * to these addresses are redirected to Code SRAM by Driver_Flash.c. - */ -#define FLASH_PS_AREA_OFFSET (FLASH_AREA_SCRATCH_OFFSET + \ - FLASH_AREA_SCRATCH_SIZE) -#define FLASH_PS_AREA_SIZE (0x5000) /* 20 KB */ - /* Internal Trusted Storage (ITS) Service definitions */ -#define FLASH_ITS_AREA_OFFSET (FLASH_PS_AREA_OFFSET + \ - FLASH_PS_AREA_SIZE) +#define FLASH_ITS_AREA_OFFSET (FLASH_AREA_SCRATCH_OFFSET + \ + FLASH_AREA_SCRATCH_SIZE) #define FLASH_ITS_AREA_SIZE (0x4000) /* 16 KB */ /* NV Counters definitions */ @@ -182,41 +176,39 @@ * Note: Further documentation of these definitions can be found in the * TF-M PS Integration Guide. */ -#define PS_FLASH_DEV_NAME Driver_FLASH0 +#define TFM_HAL_PS_FLASH_DRIVER Driver_QSPI_FLASH0 /* In this target the CMSIS driver requires only the offset from the base * address instead of the full memory address. */ -#define PS_FLASH_AREA_ADDR FLASH_PS_AREA_OFFSET -/* Dedicated flash area for PS */ -#define PS_FLASH_AREA_SIZE FLASH_PS_AREA_SIZE -#define PS_RAM_FS_SIZE PS_FLASH_AREA_SIZE -#define PS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE -/* Number of PS_SECTOR_SIZE per block */ -#define PS_SECTORS_PER_BLOCK (0x1) -/* Specifies the smallest flash programmable unit in bytes */ -#define PS_FLASH_PROGRAM_UNIT (0x1) +/* Base address of dedicated flash area for PS */ +#define TFM_HAL_PS_FLASH_AREA_ADDR 0x0 +/* Size of dedicated flash area for PS */ +#define TFM_HAL_PS_FLASH_AREA_SIZE (0x5000) /* 20 KB */ +#define PS_RAM_FS_SIZE TFM_HAL_PS_FLASH_AREA_SIZE +/* Number of physical erase sectors per logical FS block */ +#define TFM_HAL_PS_SECTORS_PER_BLOCK (1) +/* Smallest flash programmable unit in bytes */ +#define TFM_HAL_PS_PROGRAM_UNIT (0x1) /* Internal Trusted Storage (ITS) Service definitions * Note: Further documentation of these definitions can be found in the - * TF-M ITS Integration Guide. The ITS should be in the internal flash, but is - * allocated in the external flash just for development platforms that don't - * have internal flash available. + * TF-M ITS Integration Guide. */ -#define ITS_FLASH_DEV_NAME Driver_FLASH0 +#define TFM_HAL_ITS_FLASH_DRIVER Driver_FLASH0 /* In this target the CMSIS driver requires only the offset from the base * address instead of the full memory address. */ -#define ITS_FLASH_AREA_ADDR FLASH_ITS_AREA_OFFSET -/* Dedicated flash area for ITS */ -#define ITS_FLASH_AREA_SIZE FLASH_ITS_AREA_SIZE -#define ITS_RAM_FS_SIZE ITS_FLASH_AREA_SIZE -#define ITS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE -/* Number of ITS_SECTOR_SIZE per block */ -#define ITS_SECTORS_PER_BLOCK (0x1) -/* Specifies the smallest flash programmable unit in bytes */ -#define ITS_FLASH_PROGRAM_UNIT (0x1) +/* Base address of dedicated flash area for ITS */ +#define TFM_HAL_ITS_FLASH_AREA_ADDR FLASH_ITS_AREA_OFFSET +/* Size of dedicated flash area for ITS */ +#define TFM_HAL_ITS_FLASH_AREA_SIZE FLASH_ITS_AREA_SIZE +#define ITS_RAM_FS_SIZE TFM_HAL_ITS_FLASH_AREA_SIZE +/* Number of physical erase sectors per logical FS block */ +#define TFM_HAL_ITS_SECTORS_PER_BLOCK (1) +/* Smallest flash programmable unit in bytes */ +#define TFM_HAL_ITS_PROGRAM_UNIT (0x1) /* NV Counters definitions */ #define TFM_NV_COUNTERS_AREA_ADDR FLASH_NV_COUNTERS_AREA_OFFSET diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/partition/region_defs.h b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/partition/region_defs.h index 0e9a4323850..207ce8067c8 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/partition/region_defs.h +++ b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/partition/region_defs.h @@ -19,10 +19,6 @@ #ifndef __REGION_DEFS_H__ #define __REGION_DEFS_H__ -#ifndef BL2 -#define BL2 -#endif - #include "flash_layout.h" #define BL2_HEAP_SIZE (0x0001000) diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_ns_interface.c b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_ns_interface.c new file mode 100644 index 00000000000..3bd401bcaa6 --- /dev/null +++ b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_ns_interface.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017-2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#include + +#include "os_wrapper/mutex.h" + +#include "tfm_ns_interface.h" + +/** + * \brief the ns_lock ID + */ +static void *ns_lock_handle = NULL; + +int32_t tfm_ns_interface_dispatch(veneer_fn fn, + uint32_t arg0, uint32_t arg1, + uint32_t arg2, uint32_t arg3) +{ + int32_t result; + + /* TFM request protected by NS lock */ + while (os_wrapper_mutex_acquire(ns_lock_handle, OS_WRAPPER_WAIT_FOREVER) + != OS_WRAPPER_SUCCESS); + + result = fn(arg0, arg1, arg2, arg3); + + while (os_wrapper_mutex_release(ns_lock_handle) != OS_WRAPPER_SUCCESS); + + return result; +} + +uint32_t tfm_ns_interface_init(void) +{ + void *handle; + + handle = os_wrapper_mutex_create(); + if (!handle) { + return OS_WRAPPER_ERROR; + } + + ns_lock_handle = handle; + return OS_WRAPPER_SUCCESS; +} diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_s.axf b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_s.axf index 0af623d0781..9f3dca13b0a 100644 Binary files a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_s.axf and b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_s.axf differ diff --git a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_s.bin b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_s.bin index db8c0abac23..f5a477c40d0 100644 Binary files a/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_s.bin and b/targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/tfm_s.bin differ diff --git a/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/bl2.bin b/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/bl2.bin index 5240d6d1632..aa9c12b0046 100644 Binary files a/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/bl2.bin and b/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/bl2.bin differ diff --git a/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/tfm_s.axf b/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/tfm_s.axf new file mode 100644 index 00000000000..2169bd346dc Binary files /dev/null and b/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/tfm_s.axf differ diff --git a/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/tfm_s.bin b/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/tfm_s.bin index bb9fd021000..960d34d2f29 100644 Binary files a/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/tfm_s.bin and b/targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/tfm_s.bin differ diff --git a/targets/targets.json b/targets/targets.json index 81ddc62a0ea..e66c4c73d7e 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -5196,7 +5196,7 @@ "function": "ArmMuscaB1Code.binary_hook" }, "secure_image_filename": "tfm_s.bin", - "tfm_target_name": "musca_b1/sse_200", + "tfm_target_name": "arm/musca_b1/sse_200", "tfm_bootloader_supported": true, "tfm_default_toolchain": "ARMCLANG", "tfm_supported_toolchains": [ @@ -5252,7 +5252,7 @@ "function": "ArmMuscaS1Code.binary_hook" }, "secure_image_filename": "tfm_s.bin", - "tfm_target_name": "musca_s1", + "tfm_target_name": "arm/musca_s1", "tfm_bootloader_supported": true, "tfm_default_toolchain": "ARMCLANG", "tfm_supported_toolchains": [ diff --git a/tools/psa/tfm/bin_utils/imgtool/__init__.py b/tools/psa/tfm/bin_utils/imgtool/__init__.py index 3f67eed488b..4f1939904da 100644 --- a/tools/psa/tfm/bin_utils/imgtool/__init__.py +++ b/tools/psa/tfm/bin_utils/imgtool/__init__.py @@ -14,4 +14,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -imgtool_version = "1.7.0rc1" +imgtool_version = "1.7.0" diff --git a/tools/psa/tfm/bin_utils/imgtool/image.py b/tools/psa/tfm/bin_utils/imgtool/image.py index 7d7f2bac013..684c6b354a3 100644 --- a/tools/psa/tfm/bin_utils/imgtool/image.py +++ b/tools/psa/tfm/bin_utils/imgtool/image.py @@ -1,6 +1,6 @@ # Copyright 2018 Nordic Semiconductor ASA # Copyright 2017-2020 Linaro Limited -# Copyright 2019-2020 Arm Limited +# Copyright 2019-2021 Arm Limited # # SPDX-License-Identifier: Apache-2.0 # @@ -51,9 +51,11 @@ # Image header flags. IMAGE_F = { 'PIC': 0x0000001, + 'ENCRYPTED_AES128': 0x0000004, + 'ENCRYPTED_AES256': 0x0000008, 'NON_BOOTABLE': 0x0000010, 'RAM_LOAD': 0x0000020, - 'ENCRYPTED': 0x0000004, + 'ROM_FIXED': 0x0000100, } TLV_VALUES = { @@ -66,7 +68,7 @@ 'RSA3072': 0x23, 'ED25519': 0x24, 'ENCRSA2048': 0x30, - 'ENCKW128': 0x31, + 'ENCKW': 0x31, 'ENCEC256': 0x32, 'ENCX25519': 0x33, 'DEPENDENCY': 0x40, @@ -132,7 +134,12 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, pad_header=False, pad=False, confirm=False, align=1, slot_size=0, max_sectors=DEFAULT_MAX_SECTORS, overwrite_only=False, endian="little", load_addr=0, - erased_val=None, save_enctlv=False, security_counter=None): + rom_fixed=None, erased_val=None, save_enctlv=False, + security_counter=None): + + if load_addr and rom_fixed: + raise click.UsageError("Can not set rom_fixed and load_addr at the same time") + self.version = version or versmod.decode_version("0") self.header_size = header_size self.pad_header = pad_header @@ -145,6 +152,7 @@ def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, self.endian = endian self.base_addr = None self.load_addr = 0 if load_addr is None else load_addr + self.rom_fixed = rom_fixed self.erased_val = 0xff if erased_val is None else int(erased_val, 0) self.payload = [] self.enckey = None @@ -281,7 +289,7 @@ def ecies_hkdf(self, enckey, plainkey): return cipherkey, ciphermac, pubk def create(self, key, public_key_format, enckey, dependencies=None, - sw_type=None, custom_tlvs=None): + sw_type=None, custom_tlvs=None, encrypt_keylen=128): self.enckey = enckey # Calculate the hash of the public key @@ -347,10 +355,17 @@ def create(self, key, public_key_format, enckey, dependencies=None, if self.enckey is not None: pad_len = len(self.payload) % 16 if pad_len > 0: - self.payload += bytes(16 - pad_len) + pad = bytes(16 - pad_len) + if isinstance(self.payload, bytes): + self.payload += pad + else: + self.payload.extend(pad) # This adds the header to the payload as well - self.add_header(enckey, protected_tlv_size) + if encrypt_keylen == 256: + self.add_header(enckey, protected_tlv_size, 256) + else: + self.add_header(enckey, protected_tlv_size) prot_tlv = TLV(self.endian, TLV_PROT_INFO_MAGIC) @@ -418,7 +433,10 @@ def create(self, key, public_key_format, enckey, dependencies=None, self.payload = self.payload[:protected_tlv_off] if enckey is not None: - plainkey = os.urandom(16) + if encrypt_keylen == 256: + plainkey = os.urandom(32) + else: + plainkey = os.urandom(16) if isinstance(enckey, rsa.RSAPublic): cipherkey = enckey._get_public().encrypt( @@ -451,16 +469,21 @@ def create(self, key, public_key_format, enckey, dependencies=None, self.check_trailer() - def add_header(self, enckey, protected_tlv_size): + def add_header(self, enckey, protected_tlv_size, aes_length=128): """Install the image header.""" flags = 0 if enckey is not None: - flags |= IMAGE_F['ENCRYPTED'] + if aes_length == 128: + flags |= IMAGE_F['ENCRYPTED_AES128'] + else: + flags |= IMAGE_F['ENCRYPTED_AES256'] if self.load_addr != 0: # Indicates that this image should be loaded into RAM # instead of run directly from flash. flags |= IMAGE_F['RAM_LOAD'] + if self.rom_fixed: + flags |= IMAGE_F['ROM_FIXED'] e = STRUCT_ENDIAN_DICT[self.endian] fmt = (e + @@ -477,7 +500,7 @@ def add_header(self, enckey, protected_tlv_size): assert struct.calcsize(fmt) == IMAGE_HEADER_SIZE header = struct.pack(fmt, IMAGE_MAGIC, - self.load_addr, + self.rom_fixed or self.load_addr, self.header_size, protected_tlv_size, # TLV Info header + Protected TLVs len(self.payload) - self.header_size, # ImageSz @@ -537,16 +560,22 @@ def verify(imgfile, key): if magic != IMAGE_MAGIC: return VerifyResult.INVALID_MAGIC, None, None - tlv_info = b[header_size+img_size:header_size+img_size+TLV_INFO_SIZE] + tlv_off = header_size + img_size + tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE] magic, tlv_tot = struct.unpack('HH', tlv_info) + if magic == TLV_PROT_INFO_MAGIC: + tlv_off += tlv_tot + tlv_info = b[tlv_off:tlv_off+TLV_INFO_SIZE] + magic, tlv_tot = struct.unpack('HH', tlv_info) + if magic != TLV_INFO_MAGIC: return VerifyResult.INVALID_TLV_INFO_MAGIC, None, None sha = hashlib.sha256() - sha.update(b[:header_size+img_size]) + prot_tlv_size = tlv_off + sha.update(b[:prot_tlv_size]) digest = sha.digest() - tlv_off = header_size + img_size tlv_end = tlv_off + tlv_tot tlv_off += TLV_INFO_SIZE # skip tlv info while tlv_off < tlv_end: @@ -562,7 +591,7 @@ def verify(imgfile, key): elif key is not None and tlv_type == TLV_VALUES[key.sig_tlv()]: off = tlv_off + TLV_SIZE tlv_sig = b[off:off+tlv_len] - payload = b[:header_size+img_size] + payload = b[:prot_tlv_size] try: if hasattr(key, 'verify'): key.verify(tlv_sig, payload) diff --git a/tools/psa/tfm/bin_utils/imgtool/keys/general.py b/tools/psa/tfm/bin_utils/imgtool/keys/general.py index 442b1eab8bd..3fad3ddc10c 100644 --- a/tools/psa/tfm/bin_utils/imgtool/keys/general.py +++ b/tools/psa/tfm/bin_utils/imgtool/keys/general.py @@ -46,7 +46,7 @@ def emit_c_public(self, file=sys.stdout): def emit_rust_public(self, file=sys.stdout): self._emit( - header="static {}_PUB_KEY: &'static [u8] = &[".format(self.shortname().upper()), + header="static {}_PUB_KEY: &[u8] = &[".format(self.shortname().upper()), trailer="];", encoded_bytes=self.get_public_bytes(), indent=" ", diff --git a/tools/psa/tfm/bin_utils/imgtool/main.py b/tools/psa/tfm/bin_utils/imgtool/main.py index 46be8a8271a..dd6c0447b04 100755 --- a/tools/psa/tfm/bin_utils/imgtool/main.py +++ b/tools/psa/tfm/bin_utils/imgtool/main.py @@ -1,7 +1,7 @@ #! /usr/bin/env python3 # # Copyright 2017-2020 Linaro Limited -# Copyright 2019-2020 Arm Limited +# Copyright 2019-2021 Arm Limited # # SPDX-License-Identifier: Apache-2.0 # @@ -241,6 +241,8 @@ def convert(self, value, param, ctx): help='Adjust address in hex output file.') @click.option('-L', '--load-addr', type=BasedIntParamType(), required=False, help='Load address for image when it should run from RAM.') +@click.option('-F', '--rom-fixed', type=BasedIntParamType(), required=False, + help='Set flash address the image is built for.') @click.option('--save-enctlv', default=False, is_flag=True, help='When upgrading, save encrypted key TLVs instead of plain ' 'keys. Enable when BOOT_SWAP_SAVE_ENCTLV config option ' @@ -248,6 +250,10 @@ def convert(self, value, param, ctx): @click.option('-E', '--encrypt', metavar='filename', help='Encrypt image using the provided public key. ' '(Not supported in direct-xip or ram-load mode.)') +@click.option('--encrypt-keylen', default='128', + type=click.Choice(['128','256']), + help='When encrypting the image using AES, select a 128 bit or ' + '256 bit key len.') @click.option('-e', '--endian', type=click.Choice(['little', 'big']), default='little', help="Select little or big endian") @click.option('--overwrite-only', default=False, is_flag=True, @@ -293,8 +299,9 @@ def convert(self, value, param, ctx): .hex extension, otherwise binary format is used''') def sign(key, public_key_format, align, version, pad_sig, header_size, pad_header, slot_size, pad, confirm, max_sectors, overwrite_only, - endian, encrypt, infile, outfile, dependencies, load_addr, hex_addr, - erased_val, save_enctlv, security_counter, boot_record, custom_tlv): + endian, encrypt_keylen, encrypt, infile, outfile, dependencies, + load_addr, hex_addr, erased_val, save_enctlv, security_counter, + boot_record, custom_tlv, rom_fixed): if confirm: # Confirmed but non-padded images don't make much sense, because @@ -304,8 +311,8 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, pad_header=pad_header, pad=pad, confirm=confirm, align=int(align), slot_size=slot_size, max_sectors=max_sectors, overwrite_only=overwrite_only, - endian=endian, load_addr=load_addr, erased_val=erased_val, - save_enctlv=save_enctlv, + endian=endian, load_addr=load_addr, rom_fixed=rom_fixed, + erased_val=erased_val, save_enctlv=save_enctlv, security_counter=security_counter) img.load(infile) key = load_key(key) if key else None @@ -341,7 +348,7 @@ def sign(key, public_key_format, align, version, pad_sig, header_size, custom_tlvs[tag] = value.encode('utf-8') img.create(key, public_key_format, enckey, dependencies, boot_record, - custom_tlvs) + custom_tlvs, int(encrypt_keylen)) img.save(outfile, hex_addr) diff --git a/tools/psa/tfm/bin_utils/macro_parser.py b/tools/psa/tfm/bin_utils/macro_parser.py index 5d9418a4e87..12e8a92f1af 100644 --- a/tools/psa/tfm/bin_utils/macro_parser.py +++ b/tools/psa/tfm/bin_utils/macro_parser.py @@ -1,7 +1,7 @@ #! /usr/bin/env python3 # # ----------------------------------------------------------------------------- -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2021, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -11,7 +11,8 @@ import re import os -expression_re = re.compile(r"[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?") +# Match (((x) + (y))) mode and ((x) + (y)) mode. x, y can be HEX or DEC value. +expression_re = re.compile(r"([(]?[(]?[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?\s*([\+\-])\s*[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?[)]?[)]?)|([(]?[(]?[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?[)]?[)]?)") # Simple parser that takes a string and evaluates an expression from it. # The expression might contain additions and subtractions amongst numbers that diff --git a/tools/psa/tfm/bin_utils/wrapper.py b/tools/psa/tfm/bin_utils/wrapper.py index 7799ce06daa..247cb1042fc 100755 --- a/tools/psa/tfm/bin_utils/wrapper.py +++ b/tools/psa/tfm/bin_utils/wrapper.py @@ -1,7 +1,7 @@ #! /usr/bin/env python3 # # ----------------------------------------------------------------------------- -# Copyright (c) 2020, Arm Limited. All rights reserved. +# Copyright (c) 2020-2021, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -26,6 +26,7 @@ sign_bin_size_re = re.compile(r"^\s*RE_SIGN_BIN_SIZE\s*=\s*(.*)") load_addr_re = re.compile(r"^\s*RE_IMAGE_LOAD_ADDRESS\s*=\s*(.*)") +rom_fixed_re = re.compile(r"^\s*RE_IMAGE_ROM_FIXED\s*=\s*(.*)") #This works around Python 2 and Python 3 handling character encodings #differently. More information about this issue at @@ -91,7 +92,7 @@ def wrap(key, align, version, header_size, pad_header, layout, pad, confirm, slot_size = macro_parser.evaluate_macro(layout, sign_bin_size_re, 0, 1) load_addr = macro_parser.evaluate_macro(layout, load_addr_re, 0, 1) - + rom_fixed = macro_parser.evaluate_macro(layout, rom_fixed_re, 0, 1) if "_s" in layout: boot_record = "SPE" elif "_ns" in layout: @@ -104,7 +105,8 @@ def wrap(key, align, version, header_size, pad_header, layout, pad, confirm, pad=pad, confirm=confirm, align=int(align), slot_size=slot_size, max_sectors=max_sectors, overwrite_only=overwrite_only, endian=endian, - load_addr=load_addr, erased_val=erased_val, + load_addr=load_addr, rom_fixed=rom_fixed, + erased_val=erased_val, save_enctlv=save_enctlv, security_counter=security_counter)