Crypto: Refactor the API dispatcher interface to reduce code size
This patch restructures the way the underlying APIs that
implements the PSA Crypto APIs are interfaced to the TF-M
Crypto service through a thin shim layer. The size of this
layer is reduced by nearly 45% on the default configuration.
Also, it removes the check for parameter number and size on
each function call as that is a redundant check as per the
overall threat model of the interaction between the crypto
service and the partition manager.
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: I07165bad00346cd12cf63620532f55da0c5d1262
diff --git a/secure_fw/partitions/crypto/tfm_crypto_api.h b/secure_fw/partitions/crypto/tfm_crypto_api.h
index 42c643b..ef26901 100644
--- a/secure_fw/partitions/crypto/tfm_crypto_api.h
+++ b/secure_fw/partitions/crypto/tfm_crypto_api.h
@@ -14,21 +14,8 @@
#include <stdint.h>
#include "tfm_crypto_defs.h"
-#ifdef TFM_PSA_API
-#include "psa/service.h"
-
-/**
- * \brief This define is a function pointer type to the Uniform Signature API
- * prototype.
- */
-typedef psa_status_t (*tfm_crypto_us_t)(psa_invec[],size_t,psa_outvec[],size_t);
-#endif
-
#include "psa/crypto_client_struct.h"
-#define UNIFORM_SIGNATURE_API(api_name) \
- psa_status_t api_name(psa_invec[], size_t, psa_outvec[], size_t)
-
/**
* \brief List of possible operation types supported by the TFM based
* implementation. This type is needed by the operation allocation,
@@ -48,6 +35,68 @@
};
/**
+ * \brief Type associated to a function for the TF-M Crypto service
+ * API. It describes if an API is multipart related or not, i.e. and
+ * which multipart operation it requires (i.e. setup or lookup)
+ */
+enum tfm_crypto_function_type {
+ TFM_CRYPTO_FUNCTION_TYPE_NON_MULTIPART = 0x0,
+ TFM_CRYPTO_FUNCTION_TYPE_SETUP,
+ TFM_CRYPTO_FUNCTION_TYPE_LOOKUP
+};
+
+/**
+ * \brief Type associated to the group of a function encoding. There can be
+ * nine groups (Random, Key management, Hash, MAC, Cipher, AEAD,
+ * Asym sign, Asym encrypt, Key derivation).
+ */
+enum tfm_crypto_group_id {
+ TFM_CRYPTO_GROUP_ID_RANDOM = 0x0,
+ TFM_CRYPTO_GROUP_ID_KEY_MANAGEMENT,
+ TFM_CRYPTO_GROUP_ID_HASH,
+ TFM_CRYPTO_GROUP_ID_MAC,
+ TFM_CRYPTO_GROUP_ID_CIPHER,
+ TFM_CRYPTO_GROUP_ID_AEAD,
+ TFM_CRYPTO_GROUP_ID_ASYM_SIGN,
+ TFM_CRYPTO_GROUP_ID_ASYM_ENCRYPT,
+ TFM_CRYPTO_GROUP_ID_KEY_DERIVATION,
+};
+
+/**
+ * \brief Accessor to the API descriptor table that returns function_type of the API
+ *
+ * \param[in] func Function ID for the API to retrieve the associated group
+ *
+ * \return Return values as described in \ref enum tfm_crypto_function_type
+ */
+enum tfm_crypto_function_type
+ get_function_type_from_descriptor(enum tfm_crypto_function_id func);
+
+/**
+ * \brief Accessor to the API descriptor table that returns function_type of the API
+ *
+ * \param[in] id Pointer to hold the ID of the caller
+ *
+ * \return Return values as described in \ref enum tfm_crypto_group_id
+ */
+enum tfm_crypto_group_id
+ get_group_id_from_descriptor(enum tfm_crypto_function_id func);
+
+/**
+ * \brief Macro to determine the group_id corresponding to a function_id by
+ * accessing the tfm_crypto_api_descriptor table
+ */
+#define TFM_CRYPTO_IS_GROUP_ID(_function_id, _group_id) \
+ (get_group_id_from_descriptor((_function_id)) == (_group_id))
+
+/**
+ * \brief Macro to get the function_type associated to a function_id by
+ * accessing the tfm_crypto_api_descriptor table
+ */
+#define TFM_CRYPTO_GET_FUNCTION_TYPE(_function_id) \
+ (get_function_type_from_descriptor((_function_id)))
+
+/**
* \brief Initialise the service
*
* \return Return values as described in \ref psa_status_t
@@ -130,86 +179,131 @@
uint32_t handle,
void **ctx);
/**
- * \brief Encodes the input key id and owner to output key
+ * \brief This function handles the operations to allocate or retrieve a
+ * multipart context. It receives a operation and function type as
+ * inputs and then returns the looked or allocated context using
+ * the provided handle. If a context is allocated in a setup call
+ * the returned handle is then updated with the allocated value
*
- * \param[in] key_id Id of the key to encode
- * \param[out] enc_key_ptr Pointer to encoded key with id and owner
+ * \param[in] type Type of the operation context to look up
+ * \param[in] function_type Type of the function
+ * \param[in, out] handle Pointer to the handle
+ * \param[out] ctx Double pointer to the context
*
* \return Return values as described in \ref psa_status_t
*/
-psa_status_t tfm_crypto_encode_id_and_owner(psa_key_id_t key_id,
- mbedtls_svc_key_id_t *enc_key_ptr);
-
-#define LIST_TFM_CRYPTO_UNIFORM_SIGNATURE_API \
- X(tfm_crypto_get_key_attributes) \
- X(tfm_crypto_reset_key_attributes) \
- X(tfm_crypto_open_key) \
- X(tfm_crypto_close_key) \
- X(tfm_crypto_import_key) \
- X(tfm_crypto_destroy_key) \
- X(tfm_crypto_export_key) \
- X(tfm_crypto_export_public_key) \
- X(tfm_crypto_purge_key) \
- X(tfm_crypto_copy_key) \
- X(tfm_crypto_hash_compute) \
- X(tfm_crypto_hash_compare) \
- X(tfm_crypto_hash_setup) \
- X(tfm_crypto_hash_update) \
- X(tfm_crypto_hash_finish) \
- X(tfm_crypto_hash_verify) \
- X(tfm_crypto_hash_abort) \
- X(tfm_crypto_hash_clone) \
- X(tfm_crypto_mac_compute) \
- X(tfm_crypto_mac_verify) \
- X(tfm_crypto_mac_sign_setup) \
- X(tfm_crypto_mac_verify_setup) \
- X(tfm_crypto_mac_update) \
- X(tfm_crypto_mac_sign_finish) \
- X(tfm_crypto_mac_verify_finish) \
- X(tfm_crypto_mac_abort) \
- X(tfm_crypto_cipher_encrypt) \
- X(tfm_crypto_cipher_decrypt) \
- X(tfm_crypto_cipher_encrypt_setup) \
- X(tfm_crypto_cipher_decrypt_setup) \
- X(tfm_crypto_cipher_generate_iv) \
- X(tfm_crypto_cipher_set_iv) \
- X(tfm_crypto_cipher_update) \
- X(tfm_crypto_cipher_finish) \
- X(tfm_crypto_cipher_abort) \
- X(tfm_crypto_aead_encrypt) \
- X(tfm_crypto_aead_decrypt) \
- X(tfm_crypto_aead_encrypt_setup) \
- X(tfm_crypto_aead_decrypt_setup) \
- X(tfm_crypto_aead_generate_nonce) \
- X(tfm_crypto_aead_set_nonce) \
- X(tfm_crypto_aead_set_lengths) \
- X(tfm_crypto_aead_update_ad) \
- X(tfm_crypto_aead_update) \
- X(tfm_crypto_aead_finish) \
- X(tfm_crypto_aead_verify) \
- X(tfm_crypto_aead_abort) \
- X(tfm_crypto_sign_message) \
- X(tfm_crypto_verify_message) \
- X(tfm_crypto_sign_hash) \
- X(tfm_crypto_verify_hash) \
- X(tfm_crypto_asymmetric_encrypt) \
- X(tfm_crypto_asymmetric_decrypt) \
- X(tfm_crypto_key_derivation_setup) \
- X(tfm_crypto_key_derivation_get_capacity) \
- X(tfm_crypto_key_derivation_set_capacity) \
- X(tfm_crypto_key_derivation_input_bytes) \
- X(tfm_crypto_key_derivation_input_key) \
- X(tfm_crypto_key_derivation_key_agreement)\
- X(tfm_crypto_key_derivation_output_bytes) \
- X(tfm_crypto_key_derivation_output_key) \
- X(tfm_crypto_key_derivation_abort) \
- X(tfm_crypto_raw_key_agreement) \
- X(tfm_crypto_generate_random) \
- X(tfm_crypto_generate_key) \
-
-#define X(api_name) UNIFORM_SIGNATURE_API(api_name);
-LIST_TFM_CRYPTO_UNIFORM_SIGNATURE_API
-#undef X
+psa_status_t tfm_crypto_operation_handling(enum tfm_crypto_operation_type type,
+ enum tfm_crypto_function_type function_type,
+ uint32_t *handle,
+ void **ctx);
+/**
+ * \brief This function acts as interface from the framework dispatching
+ * calls to the set of functions that implement the PSA Crypto APIs.
+ * It is based on the Uniform Signatures prototype.
+ *
+ * \param[in] in_vec Array of invec parameters
+ * \param[in] in_len Length of the valid entries in in_vec
+ * \param[out] out_vec Array of outvec parameters
+ * \param[in] out_len Length of the valid entries in out_vec
+ *
+ * \return Return values as described in \ref psa_status_t
+ */
+psa_status_t tfm_crypto_api_dispatcher(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len);
+/**
+ * \brief This function acts as interface for the Key management module
+ *
+ * \param[in] in_vec Array of invec parameters
+ * \param[out] out_vec Array of outvec parameters
+ * \param[in] encoded_key Key encoded with partition_id and key_id
+ *
+ * \return Return values as described in \ref psa_status_t
+ */
+psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
+ psa_outvec out_vec[],
+ mbedtls_svc_key_id_t *encoded_key);
+/**
+ * \brief This function acts as interface for the MAC module
+ *
+ * \param[in] in_vec Array of invec parameters
+ * \param[out] out_vec Array of outvec parameters
+ * \param[in] encoded_key Key encoded with partition_id and key_id
+ *
+ * \return Return values as described in \ref psa_status_t
+ */
+psa_status_t tfm_crypto_mac_interface(psa_invec in_vec[],
+ psa_outvec out_vec[],
+ mbedtls_svc_key_id_t *encoded_key);
+/**
+ * \brief This function acts as interface for the Cipher module
+ *
+ * \param[in] in_vec Array of invec parameters
+ * \param[out] out_vec Array of outvec parameters
+ * \param[in] encoded_key Key encoded with partition_id and key_id
+ *
+ * \return Return values as described in \ref psa_status_t
+ */
+psa_status_t tfm_crypto_cipher_interface(psa_invec in_vec[],
+ psa_outvec out_vec[],
+ mbedtls_svc_key_id_t *encoded_key);
+/**
+ * \brief This function acts as interface for the AEAD module
+ *
+ * \param[in] in_vec Array of invec parameters
+ * \param[out] out_vec Array of outvec parameters
+ * \param[in] encoded_key Key encoded with partition_id and key_id
+ *
+ * \return Return values as described in \ref psa_status_t
+ */
+psa_status_t tfm_crypto_aead_interface(psa_invec in_vec[],
+ psa_outvec out_vec[],
+ mbedtls_svc_key_id_t *encoded_key);
+/**
+ * \brief This function acts as interface for the Asymmetric module
+ *
+ * \param[in] in_vec Array of invec parameters
+ * \param[out] out_vec Array of outvec parameters
+ * \param[in] encoded_key Key encoded with partition_id and key_id
+ *
+ * \return Return values as described in \ref psa_status_t
+ */
+psa_status_t tfm_crypto_asymmetric_interface(psa_invec in_vec[],
+ psa_outvec out_vec[],
+ mbedtls_svc_key_id_t *encoded_key);
+/**
+ * \brief This function acts as interface for the Key derivation module
+ *
+ * \param[in] in_vec Array of invec parameters
+ * \param[out] out_vec Array of outvec parameters
+ * \param[in] encoded_key Key encoded with partition_id and key_id
+ *
+ * \return Return values as described in \ref psa_status_t
+ */
+psa_status_t tfm_crypto_key_derivation_interface(psa_invec in_vec[],
+ psa_outvec out_vec[],
+ mbedtls_svc_key_id_t *encoded_key);
+/**
+ * \brief This function acts as interface for the Random module
+ *
+ * \param[in] in_vec Array of invec parameters
+ * \param[out] out_vec Array of outvec parameters
+ *
+ * \return Return values as described in \ref psa_status_t
+ */
+psa_status_t tfm_crypto_random_interface(psa_invec in_vec[],
+ psa_outvec out_vec[]);
+/**
+ * \brief This function acts as interface for the Hash module
+ *
+ * \param[in] in_vec Array of invec parameters
+ * \param[out] out_vec Array of outvec parameters
+ *
+ * \return Return values as described in \ref psa_status_t
+ */
+psa_status_t tfm_crypto_hash_interface(psa_invec in_vec[],
+ psa_outvec out_vec[]);
#ifdef __cplusplus
}