Crypto: Add IPC compatibility
This patch introduces compatibility in the Crypto
service with the IPC infrastructure of TF-M.
Change-Id: I5a095780e1f2bd489c83cfbca138ca6dd0bfe9ba
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/CommonConfig.cmake b/CommonConfig.cmake
index eb49a41..9815d94 100644
--- a/CommonConfig.cmake
+++ b/CommonConfig.cmake
@@ -160,7 +160,12 @@
if (CORE_TEST_IPC)
add_definitions(-DCORE_TEST_IPC)
set(TFM_PARTITION_TEST_SECURE_SERVICES ON)
- set(TEST_FRAMEWORK_NS ON)
+ # If PSA_API_TEST is enabled, don't run TF-M test framework from NS
+ if (PSA_API_TEST)
+ set(TEST_FRAMEWORK_NS OFF)
+ else()
+ set(TEST_FRAMEWORK_NS ON)
+ endif()
endif()
if (SERVICE_TEST_S)
diff --git a/ConfigCoreIPC.cmake b/ConfigCoreIPC.cmake
index 3a350b2..c06d0c9 100644
--- a/ConfigCoreIPC.cmake
+++ b/ConfigCoreIPC.cmake
@@ -29,6 +29,7 @@
set (REGRESSION True)
set (CORE_TEST False)
set (CORE_IPC True)
+set (PSA_API_TEST False)
# TF-M isolation level: 1..3
set (TFM_LVL 1)
diff --git a/ConfigPsaApiTest.cmake b/ConfigPsaApiTest.cmake
index 0c7bf46..b63b373 100644
--- a/ConfigPsaApiTest.cmake
+++ b/ConfigPsaApiTest.cmake
@@ -14,7 +14,7 @@
elseif(${TARGET_PLATFORM} STREQUAL "AN521")
set(PLATFORM_CMAKE_FILE "${CMAKE_CURRENT_LIST_DIR}/platform/ext/Mps2AN521.cmake")
elseif(${TARGET_PLATFORM} STREQUAL "AN519")
- set (PLATFORM_CMAKE_FILE "${CMAKE_CURRENT_LIST_DIR}/platform/ext/Mps2AN519.cmake")
+ set(PLATFORM_CMAKE_FILE "${CMAKE_CURRENT_LIST_DIR}/platform/ext/Mps2AN519.cmake")
elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_A")
set(PLATFORM_CMAKE_FILE "${CMAKE_CURRENT_LIST_DIR}/platform/ext/musca_a.cmake")
elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_B1")
@@ -28,6 +28,7 @@
#definitions) based on these.
set (REGRESSION False)
set (CORE_TEST False)
+set (CORE_IPC False)
set (PSA_API_TEST True)
#TF-M isolation level: 1..3
diff --git a/interface/include/tfm_crypto_defs.h b/interface/include/tfm_crypto_defs.h
index 02e9770..8d926c2 100644
--- a/interface/include/tfm_crypto_defs.h
+++ b/interface/include/tfm_crypto_defs.h
@@ -18,10 +18,95 @@
#include "psa_crypto.h"
/**
+ * \brief This type is used to overcome a limitation in the number of maximum
+ * IOVECs that can be used especially in psa_aead_encrypt and
+ * psa_aead_decrypt. To be removed in case the AEAD APIs number of
+ * parameters passed gets restructured
+ */
+#define TFM_CRYPTO_MAX_NONCE_LENGTH (16u)
+struct tfm_crypto_aead_pack_input {
+ uint8_t nonce[TFM_CRYPTO_MAX_NONCE_LENGTH];
+ uint32_t nonce_length;
+};
+
+/**
+ * \brief Structure used to pack non-pointer types in a call
+ *
+ */
+struct tfm_crypto_pack_iovec {
+ uint32_t sfn_id; /*!< Secure function ID used to dispatch the
+ * request
+ */
+ psa_key_slot_t key; /*!< Key slot */
+ psa_key_type_t type; /*!< Key type */
+ psa_key_usage_t usage; /*!< Usage policy for a key */
+ psa_algorithm_t alg; /*!< Algorithm */
+ psa_key_lifetime_t lifetime; /*!< Lifetime policy for a key */
+ uint32_t handle; /*!< Frontend context handle associated to a
+ * multipart operation
+ */
+
+ struct tfm_crypto_aead_pack_input aead_in; /*!< FixMe: Temporarily used for
+ * AEAD until the API is
+ * restructured
+ */
+};
+
+/**
+ * \brief Define a numerical value for each SFID which can be used when
+ * dispatching the requests to the service
+ */
+#define TFM_CRYPTO_IMPORT_KEY_SFID (0u)
+#define TFM_CRYPTO_DESTROY_KEY_SFID (1u)
+#define TFM_CRYPTO_GET_KEY_INFORMATION_SFID (2u)
+#define TFM_CRYPTO_EXPORT_KEY_SFID (3u)
+#define TFM_CRYPTO_KEY_POLICY_INIT_SFID (4u)
+#define TFM_CRYPTO_KEY_POLICY_SET_USAGE_SFID (5u)
+#define TFM_CRYPTO_KEY_POLICY_GET_USAGE_SFID (6u)
+#define TFM_CRYPTO_KEY_POLICY_GET_ALGORITHM_SFID (7u)
+#define TFM_CRYPTO_SET_KEY_POLICY_SFID (8u)
+#define TFM_CRYPTO_GET_KEY_POLICY_SFID (9u)
+#define TFM_CRYPTO_SET_KEY_LIFETIME_SFID (10u)
+#define TFM_CRYPTO_GET_KEY_LIFETIME_SFID (11u)
+#define TFM_CRYPTO_CIPHER_SET_IV_SFID (12u)
+#define TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SFID (13u)
+#define TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SFID (14u)
+#define TFM_CRYPTO_CIPHER_UPDATE_SFID (15u)
+#define TFM_CRYPTO_CIPHER_ABORT_SFID (16u)
+#define TFM_CRYPTO_CIPHER_FINISH_SFID (17u)
+#define TFM_CRYPTO_HASH_SETUP_SFID (18u)
+#define TFM_CRYPTO_HASH_UPDATE_SFID (19u)
+#define TFM_CRYPTO_HASH_FINISH_SFID (20u)
+#define TFM_CRYPTO_HASH_VERIFY_SFID (21u)
+#define TFM_CRYPTO_HASH_ABORT_SFID (22u)
+#define TFM_CRYPTO_MAC_SIGN_SETUP_SFID (23u)
+#define TFM_CRYPTO_MAC_VERIFY_SETUP_SFID (24u)
+#define TFM_CRYPTO_MAC_UPDATE_SFID (25u)
+#define TFM_CRYPTO_MAC_SIGN_FINISH_SFID (26u)
+#define TFM_CRYPTO_MAC_VERIFY_FINISH_SFID (27u)
+#define TFM_CRYPTO_MAC_ABORT_SFID (28u)
+#define TFM_CRYPTO_AEAD_ENCRYPT_SFID (29u)
+#define TFM_CRYPTO_AEAD_DECRYPT_SFID (30u)
+
+/**
+ * \brief Define the SID values and minor versions to match the ones defined in
+ * the service manifest files
+ */
+#define TFM_CRYPTO_SID (0x00004000u)
+#define TFM_CRYPTO_MIN_VER (0x0001)
+
+/**
+ * \brief Define the maximum value based on the previous list, and
+ * an invalid value
+ */
+#define TFM_CRYPTO_SFID_MAX (TFM_CRYPTO_AEAD_DECRYPT_SFID + 1u)
+#define TFM_CRYPTO_SFID_INVALID (~0x0u)
+
+/**
* \brief This value is used to mark an handle as invalid.
*
*/
-#define TFM_CRYPTO_INVALID_HANDLE (0xFFFFFFFF)
+#define TFM_CRYPTO_INVALID_HANDLE (~0x0u)
/**
* \brief Define miscellaneous literal constants that are used in the service
@@ -32,19 +117,6 @@
TFM_CRYPTO_IN_USE = 1
};
-/**
- * \brief This type is used to overcome a limitation in the number of maximum
- * IOVECs that can be used especially in psa_aead_encrypt and
- * psa_aead_decrypt. To be removed in case the AEAD APIs number of
- * parameters passed gets restructured
- */
-#define TFM_CRYPTO_MAX_NONCE_LENGTH (16u)
-struct tfm_crypto_aead_pack_input {
- psa_key_slot_t key;
- psa_algorithm_t alg;
- uint8_t nonce[TFM_CRYPTO_MAX_NONCE_LENGTH];
-};
-
#ifdef __cplusplus
}
#endif
diff --git a/interface/src/tfm_crypto_api.c b/interface/src/tfm_crypto_api.c
index 3b70d49..19dc6f4 100644
--- a/interface/src/tfm_crypto_api.c
+++ b/interface/src/tfm_crypto_api.c
@@ -10,24 +10,44 @@
#include "psa_crypto.h"
#include "tfm_ns_lock.h"
-#define NS_LOCK_DISPATCH(sfn_name) \
- tfm_ns_lock_dispatch((veneer_fn)tfm_##sfn_name##_veneer, \
- (uint32_t)in_vec, sizeof(in_vec)/sizeof(in_vec[0]), \
- (uint32_t)out_vec, sizeof(out_vec)/sizeof(out_vec[0]))
+#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
-#define NS_LOCK_DISPATCH_NO_INVEC(sfn_name) \
- tfm_ns_lock_dispatch((veneer_fn)tfm_##sfn_name##_veneer, \
- (uint32_t)NULL, 0, \
- (uint32_t)out_vec, sizeof(out_vec)/sizeof(out_vec[0]))
+#ifdef TFM_PSA_API
+#include "psa_client.h"
-#define NS_LOCK_DISPATCH_NO_OUTVEC(sfn_name) \
- tfm_ns_lock_dispatch((veneer_fn)tfm_##sfn_name##_veneer, \
- (uint32_t)in_vec, sizeof(in_vec)/sizeof(in_vec[0]), \
+/* Macro to check for a valid PSA handle */
+/* FixMe: Here temporarily until it's added to the framework headers */
+#define PSA_IS_HANDLE_VALID(handle) ((handle) > (psa_handle_t)0)
+
+#define PSA_CONNECT(service) \
+ psa_handle_t handle; \
+ handle = psa_connect(service##_SID, service##_MIN_VER); \
+ if (!PSA_IS_HANDLE_VALID(handle)) { \
+ return PSA_ERROR_UNKNOWN_ERROR; \
+ } \
+
+#define PSA_CLOSE() psa_close(handle)
+
+#define API_DISPATCH(sfn_name, sfn_id) \
+ psa_call(handle, /*PSA_IPC_CALL,*/ \
+ in_vec, ARRAY_SIZE(in_vec), \
+ out_vec, ARRAY_SIZE(out_vec))
+
+#define API_DISPATCH_NO_OUTVEC(sfn_name, sfn_id) \
+ psa_call(handle, /*PSA_IPC_CALL,*/ \
+ in_vec, ARRAY_SIZE(in_vec), \
+ (psa_outvec *)NULL, 0)
+#else
+#define API_DISPATCH(sfn_name, sfn_id) \
+ tfm_ns_lock_dispatch((veneer_fn)tfm_##sfn_name##_veneer, \
+ (uint32_t)in_vec, ARRAY_SIZE(in_vec), \
+ (uint32_t)out_vec, ARRAY_SIZE(out_vec))
+
+#define API_DISPATCH_NO_OUTVEC(sfn_name, sfn_id) \
+ tfm_ns_lock_dispatch((veneer_fn)tfm_##sfn_name##_veneer, \
+ (uint32_t)in_vec, ARRAY_SIZE(in_vec), \
(uint32_t)NULL, 0)
-
-#define API_DISPATCH(sfn_name) NS_LOCK_DISPATCH(sfn_name)
-#define API_DISPATCH_NO_INVEC(sfn_name) NS_LOCK_DISPATCH_NO_INVEC(sfn_name)
-#define API_DISPATCH_NO_OUTVEC(sfn_name) NS_LOCK_DISPATCH_NO_OUTVEC(sfn_name)
+#endif
psa_status_t psa_crypto_init(void)
{
@@ -43,13 +63,25 @@
size_t data_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_IMPORT_KEY_SFID,
+ .key = key,
+ .type = type,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &type, .len = sizeof(psa_key_type_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = data, .len = data_length}
};
- status = API_DISPATCH_NO_OUTVEC(tfm_crypto_import_key);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_import_key,
+ TFM_CRYPTO_IMPORT_KEY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -57,11 +89,23 @@
psa_status_t psa_destroy_key(psa_key_slot_t key)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_DESTROY_KEY_SFID,
+ .key = key,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
- status = API_DISPATCH_NO_OUTVEC(tfm_crypto_destroy_key);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_destroy_key,
+ TFM_CRYPTO_DESTROY_KEY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -71,15 +115,27 @@
size_t *bits)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_KEY_INFORMATION_SFID,
+ .key = key,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = type, .len = sizeof(psa_key_type_t)},
{.base = bits, .len = sizeof(size_t)}
};
- status = API_DISPATCH(tfm_crypto_get_key_information);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_get_key_information,
+ TFM_CRYPTO_GET_KEY_INFORMATION);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -90,17 +146,30 @@
size_t *data_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_EXPORT_KEY_SFID,
+ .key = key,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = data, .len = data_size}
};
- status = API_DISPATCH(tfm_crypto_export_key);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_export_key,
+ TFM_CRYPTO_EXPORT_KEY);
*data_length = out_vec[0].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -121,12 +190,31 @@
void psa_key_policy_init(psa_key_policy_t *policy)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_POLICY_INIT_SFID,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
psa_outvec out_vec[] = {
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+ handle = psa_connect(TFM_CRYPTO_SID,
+ TFM_CRYPTO_MIN_VER);
+ if (!PSA_IS_HANDLE_VALID(handle)) {
+ return;
+ }
+#endif
+
/* PSA API returns void so just ignore error value returned */
- status = API_DISPATCH_NO_INVEC(tfm_crypto_key_policy_init);
+ status = API_DISPATCH(tfm_crypto_key_policy_init,
+ TFM_CRYPTO_KEY_POLICY_INIT);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
}
void psa_key_policy_set_usage(psa_key_policy_t *policy,
@@ -134,16 +222,33 @@
psa_algorithm_t alg)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_POLICY_SET_USAGE_SFID,
+ .usage = usage,
+ .alg = alg,
+ };
psa_invec in_vec[] = {
- {.base = &usage, .len = sizeof(psa_key_usage_t)},
- {.base = &alg, .len = sizeof(psa_algorithm_t)}
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+ handle = psa_connect(TFM_CRYPTO_SID,
+ TFM_CRYPTO_MIN_VER);
+ if (!PSA_IS_HANDLE_VALID(handle)) {
+ return;
+ }
+#endif
+
/* PSA API returns void so just ignore error value returned */
- status = API_DISPATCH(tfm_crypto_key_policy_set_usage);
+ status = API_DISPATCH(tfm_crypto_key_policy_set_usage,
+ TFM_CRYPTO_KEY_POLICY_SET_USAGE);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
}
psa_key_usage_t psa_key_policy_get_usage(const psa_key_policy_t *policy)
@@ -151,20 +256,33 @@
psa_status_t status;
psa_key_usage_t usage;
- /* Initialise to a sensible default to avoid returning an uninitialised
- * value in case the secure function fails.
- */
- usage = 0;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_POLICY_GET_USAGE_SFID,
+ };
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
psa_outvec out_vec[] = {
{.base = &usage, .len = sizeof(psa_key_usage_t)},
};
+ /* Initialise to a sensible default to avoid returning an uninitialised
+ * value in case the secure function fails.
+ */
+ usage = 0;
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
/* The PSA API does not return an error, so ignore any error from TF-M */
- status = API_DISPATCH(tfm_crypto_key_policy_get_usage);
+ status = API_DISPATCH(tfm_crypto_key_policy_get_usage,
+ TFM_CRYPTO_KEY_POLICY_GET_USAGE);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return usage;
}
@@ -174,20 +292,33 @@
psa_status_t status;
psa_algorithm_t alg;
- /* Initialise to a sensible default to avoid returning an uninitialised
- * value in case the secure function fails.
- */
- alg = 0;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_POLICY_GET_ALGORITHM_SFID,
+ };
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
psa_outvec out_vec[] = {
{.base = &alg, .len = sizeof(psa_algorithm_t)},
};
+ /* Initialise to a sensible default to avoid returning an uninitialised
+ * value in case the secure function fails.
+ */
+ alg = 0;
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
/* The PSA API does not return an error, so ignore any error from TF-M */
- status = API_DISPATCH(tfm_crypto_key_policy_get_algorithm);
+ status = API_DISPATCH(tfm_crypto_key_policy_get_algorithm,
+ TFM_CRYPTO_KEY_POLICY_GET_ALGORITHM);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return alg;
}
@@ -196,12 +327,25 @@
const psa_key_policy_t *policy)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_SET_KEY_POLICY_SFID,
+ .key = key,
+ };
+
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
- status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_policy);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_policy,
+ TFM_CRYPTO_SET_KEY_POLICY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -210,14 +354,27 @@
psa_key_policy_t *policy)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_KEY_POLICY_SFID,
+ .key = key,
+ };
+
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
- status = API_DISPATCH(tfm_crypto_get_key_policy);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_get_key_policy,
+ TFM_CRYPTO_GET_KEY_POLICY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -226,12 +383,25 @@
psa_key_lifetime_t lifetime)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &lifetime, .len = sizeof(psa_key_lifetime_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_SET_KEY_LIFETIME_SFID,
+ .key = key,
+ .lifetime = lifetime,
};
- status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_lifetime);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_lifetime,
+ TFM_CRYPTO_SET_KEY_LIFETIME);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -240,14 +410,27 @@
psa_key_lifetime_t *lifetime)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_KEY_LIFETIME_SFID,
+ .key = key,
+ };
+
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = lifetime, .len = sizeof(psa_key_lifetime_t)},
};
- status = API_DISPATCH(tfm_crypto_get_key_lifetime);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_get_key_lifetime,
+ TFM_CRYPTO_GET_KEY_LIFETIME);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -257,14 +440,28 @@
size_t iv_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_SET_IV_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = iv, .len = iv_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
};
- status = API_DISPATCH(tfm_crypto_cipher_set_iv);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_set_iv,
+ TFM_CRYPTO_CIPHER_SET_IV);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -274,15 +471,29 @@
psa_algorithm_t alg)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &alg, .len = sizeof(psa_algorithm_t)},
- };
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SFID,
+ .key = key,
+ .alg = alg,
+ .handle = operation->handle,
};
- status = API_DISPATCH(tfm_crypto_cipher_encrypt_setup);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_encrypt_setup,
+ TFM_CRYPTO_CIPHER_ENCRYPT_SETUP);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -292,15 +503,29 @@
psa_algorithm_t alg)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &alg, .len = sizeof(psa_algorithm_t)},
- };
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SFID,
+ .key = key,
+ .alg = alg,
+ .handle = operation->handle,
};
- status = API_DISPATCH(tfm_crypto_cipher_decrypt_setup);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_decrypt_setup,
+ TFM_CRYPTO_CIPHER_DECRYPT_SETUP);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -313,29 +538,60 @@
size_t *output_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_UPDATE_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = input, .len = input_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
{.base = output, .len = output_size}
};
- status = API_DISPATCH(tfm_crypto_cipher_update);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_update,
+ TFM_CRYPTO_CIPHER_UPDATE);
*output_length = out_vec[1].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
{
psa_status_t status;
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_ABORT_SFID,
+ .handle = operation->handle,
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_cipher_abort);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_abort,
+ TFM_CRYPTO_CIPHER_ABORT);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -346,15 +602,32 @@
size_t *output_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_FINISH_SFID,
+ .handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
{.base = output, .len = output_size},
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_cipher_finish);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_finish,
+ TFM_CRYPTO_CIPHER_FINISH);
*output_length = out_vec[1].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -362,14 +635,29 @@
psa_algorithm_t alg)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &alg, .len = sizeof(psa_algorithm_t)},
- };
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_SETUP_SFID,
+ .alg = alg,
+ .handle = operation->handle,
};
- status = API_DISPATCH(tfm_crypto_hash_setup);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_setup,
+ TFM_CRYPTO_HASH_SETUP);
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -379,14 +667,29 @@
size_t input_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_UPDATE_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = input, .len = input_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
};
- status = API_DISPATCH(tfm_crypto_hash_update);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_update,
+ TFM_CRYPTO_HASH_UPDATE);
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -397,15 +700,32 @@
size_t *hash_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_FINISH_SFID,
+ .handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
{.base = hash, .len = hash_size},
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_hash_finish);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_finish,
+ TFM_CRYPTO_HASH_FINISH);
*hash_length = out_vec[1].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -414,14 +734,28 @@
size_t hash_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_VERIFY_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = hash, .len = hash_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
};
- status = API_DISPATCH(tfm_crypto_hash_verify);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_verify,
+ TFM_CRYPTO_HASH_VERIFY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -429,11 +763,27 @@
psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
{
psa_status_t status;
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_ABORT_SFID,
+ .handle = operation->handle,
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_hash_abort);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_abort,
+ TFM_CRYPTO_HASH_ABORT);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -443,15 +793,29 @@
psa_algorithm_t alg)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &alg, .len = sizeof(psa_algorithm_t)}
- };
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_SIGN_SETUP_SFID,
+ .key = key,
+ .alg = alg,
+ .handle = operation->handle,
};
- status = API_DISPATCH(tfm_crypto_mac_sign_setup);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_sign_setup,
+ TFM_CRYPTO_MAC_SIGN_SETUP);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -461,15 +825,29 @@
psa_algorithm_t alg)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &alg, .len = sizeof(psa_algorithm_t)}
- };
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_VERIFY_SETUP_SFID,
+ .key = key,
+ .alg = alg,
+ .handle = operation->handle,
};
- status = API_DISPATCH(tfm_crypto_mac_verify_setup);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_verify_setup,
+ TFM_CRYPTO_MAC_VERIFY_SETUP);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -479,14 +857,28 @@
size_t input_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_UPDATE_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = input, .len = input_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
};
- status = API_DISPATCH(tfm_crypto_mac_update);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_update,
+ TFM_CRYPTO_MAC_UPDATE);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -497,15 +889,32 @@
size_t *mac_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_SIGN_FINISH_SFID,
+ .handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
{.base = mac, .len = mac_size},
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_mac_sign_finish);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_sign_finish,
+ TFM_CRYPTO_MAC_SIGN_FINISH);
*mac_length = out_vec[1].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -514,14 +923,29 @@
size_t mac_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_VERIFY_FINISH_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = mac, .len = mac_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
};
- status = API_DISPATCH(tfm_crypto_mac_verify_finish);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_verify_finish,
+ TFM_CRYPTO_MAC_VERIFY_FINISH);
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -529,11 +953,27 @@
psa_status_t psa_mac_abort(psa_mac_operation_t *operation)
{
psa_status_t status;
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_ABORT_SFID,
+ .handle = operation->handle,
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_mac_abort);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_abort,
+ TFM_CRYPTO_MAC_ABORT);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -551,17 +991,18 @@
size_t *ciphertext_length)
{
psa_status_t status;
- struct tfm_crypto_aead_pack_input input_s = {
- .key = key,
- .alg = alg,
- .nonce = {0},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_ENCRYPT_SFID,
+ .key = key,
+ .alg = alg,
+ .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
};
+
size_t idx = 0;
psa_invec in_vec[] = {
- {.base = &input_s, .len = nonce_length + sizeof(psa_key_slot_t)
- + sizeof(psa_algorithm_t)},
- {.base = additional_data, .len = additional_data_length},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = plaintext, .len = plaintext_length},
+ {.base = additional_data, .len = additional_data_length},
};
psa_outvec out_vec[] = {
{.base = ciphertext, .len = ciphertext_size},
@@ -573,14 +1014,32 @@
if (nonce != NULL) {
for (idx = 0; idx < nonce_length; idx++) {
- input_s.nonce[idx] = nonce[idx];
+ iov.aead_in.nonce[idx] = nonce[idx];
}
}
- status = API_DISPATCH(tfm_crypto_aead_encrypt);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = sizeof(in_vec)/sizeof(in_vec[0]);
+ if (additional_data == NULL) {
+ in_len--;
+ }
+ status = psa_call(handle, in_vec, in_len,
+ out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+#else
+ status = API_DISPATCH(tfm_crypto_aead_encrypt,
+ TFM_CRYPTO_AEAD_ENCRYPT);
+#endif
*ciphertext_length = out_vec[0].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -597,17 +1056,18 @@
size_t *plaintext_length)
{
psa_status_t status;
- struct tfm_crypto_aead_pack_input input_s = {
- .key = key,
- .alg = alg,
- .nonce = {0},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_DECRYPT_SFID,
+ .key = key,
+ .alg = alg,
+ .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
};
+
size_t idx = 0;
psa_invec in_vec[] = {
- {.base = &input_s, .len = nonce_length + sizeof(psa_key_slot_t)
- + sizeof(psa_algorithm_t)},
- {.base = additional_data, .len = additional_data_length},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = ciphertext, .len = ciphertext_length},
+ {.base = additional_data, .len = additional_data_length},
};
psa_outvec out_vec[] = {
{.base = plaintext, .len = plaintext_size},
@@ -619,13 +1079,31 @@
if (nonce != NULL) {
for (idx = 0; idx < nonce_length; idx++) {
- input_s.nonce[idx] = nonce[idx];
+ iov.aead_in.nonce[idx] = nonce[idx];
}
}
- status = API_DISPATCH(tfm_crypto_aead_decrypt);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = sizeof(in_vec)/sizeof(in_vec[0]);
+ if (additional_data == NULL) {
+ in_len--;
+ }
+ status = psa_call(handle, in_vec, in_len,
+ out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+#else
+ status = API_DISPATCH(tfm_crypto_aead_decrypt,
+ TFM_CRYPTO_AEAD_DECRYPT);
+#endif
*plaintext_length = out_vec[0].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
diff --git a/secure_fw/core/ipc/include/tfm_spm_signal_defs.h b/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
index c0c4bf4..1402bd0 100644
--- a/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
+++ b/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
@@ -10,7 +10,8 @@
#include "test/test_services/tfm_ipc_service/tfm_ipc_service_partition.h"
#include "test/test_services/tfm_core_test/tfm_ss_core_test_signal.h"
#include "test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h"
+#include "secure_fw/services/crypto/tfm_crypto_signal.h"
#include "secure_fw/services/secure_storage/tfm_sst_signal.h"
#include "test/test_services/tfm_secure_client_service/tfm_sec_client_ser_sig.h"
-#endif
+#endif /* __TFM_SPM_SIGNAL_DEFS_H__ */
diff --git a/secure_fw/services/crypto/CMakeLists.inc b/secure_fw/services/crypto/CMakeLists.inc
index dc70627..6a65652 100644
--- a/secure_fw/services/crypto/CMakeLists.inc
+++ b/secure_fw/services/crypto/CMakeLists.inc
@@ -81,6 +81,13 @@
else()
message("- CRYPTO_ENGINE_BUF_SIZE: " ${CRYPTO_ENGINE_BUF_SIZE})
endif()
+ if (TFM_PSA_API)
+ if (NOT DEFINED CRYPTO_IOVEC_BUFFER_SIZE)
+ message("- CRYPTO_IOVEC_BUFFER_SIZE using default value")
+ else()
+ message("- CRYPTO_IOVEC_BUFFER_SIZE: " ${CRYPTO_IOVEC_BUFFER_SIZE})
+ endif()
+ endif()
else()
message(FATAL_ERROR "Build system currently doesn't support selectively disabling of a service.")
diff --git a/secure_fw/services/crypto/CMakeLists.txt b/secure_fw/services/crypto/CMakeLists.txt
index 04bda24..0cce934 100644
--- a/secure_fw/services/crypto/CMakeLists.txt
+++ b/secure_fw/services/crypto/CMakeLists.txt
@@ -62,6 +62,9 @@
if (DEFINED CRYPTO_ENGINE_BUF_SIZE)
list(APPEND TFM_CRYPTO_C_DEFINES_LIST TFM_CRYPTO_ENGINE_BUF_SIZE=${CRYPTO_ENGINE_BUF_SIZE})
endif()
+if (TFM_PSA_API AND DEFINED CRYPTO_IOVEC_BUFFER_SIZE)
+ list(APPEND TFM_CRYPTO_C_DEFINES_LIST TFM_CRYPTO_IOVEC_BUFFER_SIZE=${CRYPTO_IOVEC_BUFFER_SIZE})
+endif()
if (CRYPTO_ENGINE_MBEDTLS)
#Set mbed TLS compiler flags
diff --git a/secure_fw/services/crypto/crypto_aead.c b/secure_fw/services/crypto/crypto_aead.c
index 7978d7f..4926b28 100644
--- a/secure_fw/services/crypto/crypto_aead.c
+++ b/secure_fw/services/crypto/crypto_aead.c
@@ -7,13 +7,15 @@
#include <limits.h>
-#include "tfm_crypto_defs.h"
-
-#include "crypto_engine.h"
-
-#include "psa_crypto.h"
-
#include "tfm_crypto_api.h"
+#include "crypto_engine.h"
+#include "tfm_crypto_struct.h"
+
+/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
+ * integrity checks but this will have to be revised
+ * when the full set of error codes mandated by PSA FF
+ * is available.
+ */
/**
* \def CRYPTO_AEAD_MAX_KEY_LENGTH
@@ -29,17 +31,24 @@
psa_key_type_t *type,
size_t *bits)
{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_KEY_INFORMATION_SFID,
+ .key = key,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = type, .len = sizeof(psa_key_type_t)},
{.base = bits, .len = sizeof(size_t)}
};
- return tfm_crypto_get_key_information(
+ status = tfm_crypto_get_key_information(
in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+
+ return status;
}
/*!
@@ -58,28 +67,31 @@
uint32_t key_size;
psa_key_type_t key_type;
- if ((in_len != 3) || (out_len != 1)) {
+ if ( !((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((in_vec[0].len < (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))) ||
- (in_vec[0].len > (TFM_CRYPTO_MAX_NONCE_LENGTH
- + (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
return PSA_CONNECTION_REFUSED;
}
-
- const struct tfm_crypto_aead_pack_input *input_s = in_vec[0].base;
- psa_key_slot_t key = input_s->key;
- psa_algorithm_t alg = input_s->alg;
- const uint8_t *nonce = input_s->nonce;
- size_t nonce_length = in_vec[0].len - sizeof(psa_key_slot_t)
- - sizeof(psa_algorithm_t);
- const uint8_t *additional_data = in_vec[1].base;
- size_t additional_data_length = in_vec[1].len;
- const uint8_t *plaintext = in_vec[2].base;
- size_t plaintext_length = in_vec[2].len;
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ const struct tfm_crypto_aead_pack_input *aead_pack_input = &iov->aead_in;
+ psa_key_slot_t key = iov->key;
+ psa_algorithm_t alg = iov->alg;
+ const uint8_t *nonce = aead_pack_input->nonce;
+ size_t nonce_length = aead_pack_input->nonce_length;
+ const uint8_t *plaintext = in_vec[1].base;
+ size_t plaintext_length = in_vec[1].len;
uint8_t *ciphertext = out_vec[0].base;
size_t ciphertext_size = out_vec[0].len;
+ const uint8_t *additional_data = NULL;
+ size_t additional_data_length = 0;
+
+ /* Check if additional data has been passed and initialise it */
+ if (in_len == 3) {
+ additional_data = in_vec[2].base;
+ additional_data_length = in_vec[2].len;
+ }
/* Initialise ciphertext_length to zero */
out_vec[0].len = 0;
@@ -158,24 +170,31 @@
uint32_t key_size;
psa_key_type_t key_type;
- if ((in_vec[0].len < (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))) ||
- (in_vec[0].len > (TFM_CRYPTO_MAX_NONCE_LENGTH
- + (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))))) {
+ if ( !((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- const struct tfm_crypto_aead_pack_input *input_s = in_vec[0].base;
- psa_key_slot_t key = input_s->key;
- psa_algorithm_t alg = input_s->alg;
- const uint8_t *nonce = input_s->nonce;
- size_t nonce_length = in_vec[0].len - sizeof(psa_key_slot_t)
- - sizeof(psa_algorithm_t);
- const uint8_t *additional_data = in_vec[1].base;
- size_t additional_data_length = in_vec[1].len;
- const uint8_t *ciphertext = in_vec[2].base;
- size_t ciphertext_length = in_vec[2].len;
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ const struct tfm_crypto_aead_pack_input *aead_pack_input = &iov->aead_in;
+ psa_key_slot_t key = iov->key;
+ psa_algorithm_t alg = iov->alg;
+ const uint8_t *nonce = aead_pack_input->nonce;
+ size_t nonce_length = aead_pack_input->nonce_length;
+ const uint8_t *ciphertext = in_vec[1].base;
+ size_t ciphertext_length = in_vec[1].len;
uint8_t *plaintext = out_vec[0].base;
size_t plaintext_size = out_vec[0].len;
+ const uint8_t *additional_data = NULL;
+ size_t additional_data_length = 0;
+
+ /* Check if additional data has been passed and initialise it */
+ if (in_len == 3) {
+ additional_data = in_vec[2].base;
+ additional_data_length = in_vec[2].len;
+ }
/* Initialise plaintext_length to zero */
out_vec[0].len = 0;
diff --git a/secure_fw/services/crypto/crypto_alloc.c b/secure_fw/services/crypto/crypto_alloc.c
index 8705029..9726fa0 100644
--- a/secure_fw/services/crypto/crypto_alloc.c
+++ b/secure_fw/services/crypto/crypto_alloc.c
@@ -16,47 +16,6 @@
#include "secure_fw/core/tfm_memory_utils.h"
/**
- * \def LIST_OPERATION_LOOKUP
- *
- * \brief This is an X macro which enforces the correspondence
- * between backend operation type (through the enum
- * tfm_crypto_operation_type) and the corresponding frontend type
- */
-#define LIST_OPERATION_LOOKUP \
- X(TFM_CRYPTO_CIPHER_OPERATION, psa_cipher_operation_t) \
- X(TFM_CRYPTO_MAC_OPERATION, psa_mac_operation_t) \
- X(TFM_CRYPTO_HASH_OPERATION, psa_hash_operation_t)
-
-/**
- * \def CHECK_ALIGNMENT
- *
- * \brief This macro checks the alignment of the operation object pointer which
- * receives as input based on the requirement of the front end operation
- * type. This macro expands in a case statement so it must be used in a
- * switch-case construct. It sets the handle value it receives in input
- * with the proper value or TFM_CRYPTO_INVALID_HANDLE in case the oper
- * pointer does not satisfy alignment requirements of the front end type
- */
-#define CHECK_ALIGNMENT(e,t,oper,handle) \
- case e: \
- if ((uintptr_t)oper % offsetof(struct {char c; t x;},x)) { \
- handle = TFM_CRYPTO_INVALID_HANDLE; \
- } else { \
- handle = ((t *)oper)->handle; \
- } \
- break;
-/**
- * \def GET_HANDLE_POINTER
- *
- * \brief This macro extracts the pointer to handle value from the object
- * operation pointer it receives as input. This macro expands in a case
- * statement so it must be used in a switch case-case construct.
- */
-#define GET_HANDLE_POINTER(e,t,oper,handle) \
- case e: \
- handle = &(((t *)oper)->handle); \
- break;
-/**
* \def TFM_CRYPTO_CONC_OPER_NUM
*
* \brief This value defines the maximum number of simultaneous operations
@@ -110,80 +69,6 @@
(void)tfm_memset(mem_ptr, 0, mem_size);
}
-/*
- * \brief Function used to extract the handle value from a pointer to a
- * frontend operation
- *
- * \param[in] type Type of the operation context to extract from
- * \param[in] oper Pointer to the frontend operation
- *
- * \return handle 4-byte identifier associated to the context,
- * TFM_CRYPTO_INVALID_HANDLE in case of problems
- *
- */
-static uint32_t get_handle(enum tfm_crypto_operation_type type,
- const void *oper)
-{
- uint32_t handle = TFM_CRYPTO_INVALID_HANDLE;
-
- /* Dereference the pointer */
- switch(type) {
- /* Generate the list of cases needed to check alignment for all the
- * possible operation types listed in LIST_OPERATION_LOOKUP. The default
- * case and TFM_CRYPTO_OPERATION_NONE must be created explicitly
- */
-#define X(e,t) CHECK_ALIGNMENT(e,t,oper,handle)
-LIST_OPERATION_LOOKUP
-#undef X
- case TFM_CRYPTO_OPERATION_NONE:
- default:
- break;
- }
-
- return handle;
-}
-
-/*
- * \brief Function used to set the handle value in a pointer to a
- * frontend operation
- *
- * \param[in] type Type of the operation context to extract from
- * \param[out] oper Pointer to the frontend operation
- *
- * \return handle 4-byte identifier associated to the context,
- * TFM_CRYPTO_INVALID_HANDLE in case of problems
- *
- */
-static uint32_t set_handle(enum tfm_crypto_operation_type type,
- void *oper,
- uint32_t set_value)
-{
- uint32_t *handle = NULL;
-
- /* Extract the pointer value */
- switch(type) {
- /* Generate the list of cases needed to get the handle pointer for all the
- * possible operation types listed in LIST_OPERATION_LOOKUP. The default
- * case and TFM_CRYPTO_OPERATION_NONE must be created explicitly
- */
-#define X(e,t) GET_HANDLE_POINTER(e,t,oper,handle)
-LIST_OPERATION_LOOKUP
-#undef X
- case TFM_CRYPTO_OPERATION_NONE:
- default:
- break;
- }
-
- if (handle == NULL || ((uintptr_t)handle % sizeof(uint32_t))) {
- return TFM_CRYPTO_INVALID_HANDLE;
- }
-
- /* Set the value by derefencing the pointer, alignment is correct */
- *handle = set_value;
-
- return set_value;
-}
-
/*!
* \defgroup public Public functions
*
@@ -198,10 +83,10 @@
}
psa_status_t tfm_crypto_operation_alloc(enum tfm_crypto_operation_type type,
- void *oper,
+ uint32_t *handle,
void **ctx)
{
- uint32_t i = 0, handle;
+ uint32_t i = 0;
/* Init to invalid values */
if (ctx == NULL) {
@@ -213,30 +98,27 @@
if (operation[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
operation[i].in_use = TFM_CRYPTO_IN_USE;
operation[i].type = type;
- handle = set_handle(type, oper, i);
- if (handle == TFM_CRYPTO_INVALID_HANDLE) {
- return PSA_ERROR_NOT_PERMITTED;
- }
+ *handle = i;
*ctx = (void *) &(operation[i].operation);
return PSA_SUCCESS;
}
}
+ *handle = TFM_CRYPTO_INVALID_HANDLE;
return PSA_ERROR_NOT_PERMITTED;
}
-psa_status_t tfm_crypto_operation_release(enum tfm_crypto_operation_type type,
- void *oper)
+psa_status_t tfm_crypto_operation_release(uint32_t *handle)
{
- uint32_t handle = get_handle(type, oper);
+ uint32_t h_val = *handle;
- if ( (handle != TFM_CRYPTO_INVALID_HANDLE) &&
- (handle < TFM_CRYPTO_CONC_OPER_NUM) &&
- (operation[handle].in_use == TFM_CRYPTO_IN_USE) ) {
- memset_operation_context(handle);
- operation[handle].in_use = TFM_CRYPTO_NOT_IN_USE;
- operation[handle].type = TFM_CRYPTO_OPERATION_NONE;
- (void)set_handle(type, oper, TFM_CRYPTO_INVALID_HANDLE);
+ if ( (h_val != TFM_CRYPTO_INVALID_HANDLE) &&
+ (h_val < TFM_CRYPTO_CONC_OPER_NUM) &&
+ (operation[h_val].in_use == TFM_CRYPTO_IN_USE) ) {
+ memset_operation_context(h_val);
+ operation[h_val].in_use = TFM_CRYPTO_NOT_IN_USE;
+ operation[h_val].type = TFM_CRYPTO_OPERATION_NONE;
+ *handle = TFM_CRYPTO_INVALID_HANDLE;
return PSA_SUCCESS;
}
@@ -244,11 +126,9 @@
}
psa_status_t tfm_crypto_operation_lookup(enum tfm_crypto_operation_type type,
- const void *oper,
+ uint32_t handle,
void **ctx)
{
- uint32_t handle = get_handle(type, oper);
-
if ( (handle != TFM_CRYPTO_INVALID_HANDLE) &&
(handle < TFM_CRYPTO_CONC_OPER_NUM) &&
(operation[handle].in_use == TFM_CRYPTO_IN_USE) &&
diff --git a/secure_fw/services/crypto/crypto_cipher.c b/secure_fw/services/crypto/crypto_cipher.c
index 05d8285..757ccc0 100644
--- a/secure_fw/services/crypto/crypto_cipher.c
+++ b/secure_fw/services/crypto/crypto_cipher.c
@@ -9,6 +9,12 @@
#include "crypto_engine.h"
#include "tfm_crypto_struct.h"
+/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
+ * integrity checks but this will have to be revised
+ * when the full set of error codes mandated by PSA FF
+ * is available.
+ */
+
/**
* \def CRYPTO_CIPHER_MAX_KEY_LENGTH
*
@@ -23,17 +29,24 @@
psa_key_type_t *type,
size_t *bits)
{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_KEY_INFORMATION_SFID,
+ .key = key,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = type, .len = sizeof(psa_key_type_t)},
{.base = bits, .len = sizeof(size_t)}
};
- return tfm_crypto_get_key_information(
+ status = tfm_crypto_get_key_information(
in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+
+ return status;
}
/**
@@ -45,7 +58,7 @@
* \return Return values as described in \ref tfm_crypto_err_t
*/
static psa_status_t tfm_crypto_cipher_release(
- psa_cipher_operation_t *operation,
+ uint32_t *handle,
struct tfm_cipher_operation_s *ctx)
{
psa_status_t status = PSA_SUCCESS;
@@ -57,10 +70,10 @@
}
/* Release the operation context */
- return tfm_crypto_operation_release(TFM_CRYPTO_CIPHER_OPERATION, operation);
+ return tfm_crypto_operation_release(handle);
}
-static psa_status_t tfm_crypto_cipher_setup(psa_cipher_operation_t *operation,
+static psa_status_t tfm_crypto_cipher_setup(uint32_t *handle,
psa_key_slot_t key,
psa_algorithm_t alg,
enum engine_cipher_mode_t c_mode)
@@ -105,7 +118,7 @@
/* Allocate the operation context in the secure world */
status = tfm_crypto_operation_alloc(TFM_CRYPTO_CIPHER_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
@@ -121,7 +134,7 @@
status = tfm_crypto_engine_cipher_start(&(ctx->engine_ctx), &engine_info);
if (status != PSA_SUCCESS) {
/* Release the operation context, ignore if this operation fails. */
- (void)tfm_crypto_cipher_release(operation, ctx);
+ (void)tfm_crypto_cipher_release(handle, ctx);
return status;
}
@@ -138,7 +151,7 @@
&key_size);
if (status != PSA_SUCCESS) {
/* Release the operation context, ignore if this operation fails. */
- (void)tfm_crypto_cipher_release(operation, ctx);
+ (void)tfm_crypto_cipher_release(handle, ctx);
return status;
}
@@ -149,7 +162,7 @@
&engine_info);
if (status != PSA_SUCCESS) {
/* Release the operation context, ignore if this operation fails. */
- (void)tfm_crypto_cipher_release(operation, ctx);
+ (void)tfm_crypto_cipher_release(handle, ctx);
return status;
}
@@ -164,7 +177,7 @@
&engine_info);
if (status != PSA_SUCCESS) {
/* Release the operation context, ignore if this operation fails. */
- (void)tfm_crypto_cipher_release(operation, ctx);
+ (void)tfm_crypto_cipher_release(handle, ctx);
return status;
}
}
@@ -190,33 +203,42 @@
psa_status_t status = PSA_SUCCESS;
struct tfm_cipher_operation_s *ctx = NULL;
- if ((in_len != 1) || (out_len != 1)) {
+ if ((in_len != 2) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if (out_vec[0].len != sizeof(psa_cipher_operation_t)) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
+ const unsigned char *iv = in_vec[1].base;
+ size_t iv_length = in_vec[1].len;
- psa_cipher_operation_t *operation = out_vec[0].base;
- const unsigned char *iv = in_vec[0].base;
- size_t iv_length = in_vec[0].len;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
}
if ((iv_length != ctx->block_size) || (iv_length > TFM_CIPHER_IV_MAX_SIZE)){
- (void)tfm_crypto_cipher_release(operation, ctx);
+ if (tfm_crypto_cipher_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_INVALID_ARGUMENT;
}
if ((ctx->iv_set == 1) || (ctx->iv_required == 0)) {
- (void)tfm_crypto_cipher_release(operation, ctx);
+ if (tfm_crypto_cipher_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_BAD_STATE;
}
@@ -225,7 +247,9 @@
iv,
iv_length);
if (status != PSA_SUCCESS) {
- (void)tfm_crypto_cipher_release(operation, ctx);
+ if (tfm_crypto_cipher_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return status;
}
@@ -235,45 +259,59 @@
return PSA_SUCCESS;
}
-static psa_status_t _psa_cipher_set_iv(psa_cipher_operation_t *operation,
+static psa_status_t _psa_cipher_set_iv(uint32_t *handle,
const unsigned char *iv,
size_t iv_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_SET_IV_SFID,
+ .handle = *handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = iv, .len = iv_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ {.base = handle, .len = sizeof(uint32_t)},
};
status = tfm_crypto_cipher_set_iv(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
return status;
}
+
psa_status_t tfm_crypto_cipher_encrypt_setup(psa_invec in_vec[],
size_t in_len,
psa_outvec out_vec[],
size_t out_len)
{
- if ((in_len != 2) || (out_len != 1)) {
+ psa_status_t status = PSA_SUCCESS;
+ if ((in_len != 1) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_cipher_operation_t)) ||
- (in_vec[0].len != sizeof(psa_key_slot_t)) ||
- (in_vec[1].len != sizeof(psa_algorithm_t))) {
+ if ((out_vec[0].len != sizeof(uint32_t)) ||
+ (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
+ psa_key_slot_t key = iov->key;
+ psa_algorithm_t alg = iov->alg;
- psa_cipher_operation_t *operation = out_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
- psa_algorithm_t alg = *((psa_algorithm_t *)in_vec[1].base);
-
- return tfm_crypto_cipher_setup(operation,
- key,
- alg,
- ENGINE_CIPHER_MODE_ENCRYPT);
+ status = tfm_crypto_cipher_setup(&handle,
+ key,
+ alg,
+ ENGINE_CIPHER_MODE_ENCRYPT);
+ if (status == PSA_SUCCESS) {
+ *handle_out = handle;
+ } else {
+ *handle_out = iov->handle;
+ }
+ return status;
}
psa_status_t tfm_crypto_cipher_decrypt_setup(psa_invec in_vec[],
@@ -281,24 +319,29 @@
psa_outvec out_vec[],
size_t out_len)
{
- if ((in_len != 2) || (out_len != 1)) {
+ psa_status_t status = PSA_SUCCESS;
+ if ((in_len != 1) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_cipher_operation_t)) ||
- (in_vec[0].len != sizeof(psa_key_slot_t)) ||
- (in_vec[1].len != sizeof(psa_algorithm_t))) {
+ if ((out_vec[0].len != sizeof(uint32_t)) ||
+ (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
+ psa_key_slot_t key = iov->key;
+ psa_algorithm_t alg = iov->alg;
- psa_cipher_operation_t *operation = out_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
- psa_algorithm_t alg = *((psa_algorithm_t *)in_vec[1].base);
-
- return tfm_crypto_cipher_setup(operation,
- key,
- alg,
- ENGINE_CIPHER_MODE_DECRYPT);
+ status = tfm_crypto_cipher_setup(&handle,
+ key,
+ alg,
+ ENGINE_CIPHER_MODE_DECRYPT);
+ if (status == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
+ return status;
}
psa_status_t tfm_crypto_cipher_update(psa_invec in_vec[],
@@ -309,26 +352,31 @@
psa_status_t status = PSA_SUCCESS;
struct tfm_cipher_operation_s *ctx = NULL;
- if ((in_len != 1) || (out_len != 2)) {
+ if ((in_len != 2) || (out_len != 2)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_cipher_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
-
- psa_cipher_operation_t *operation = out_vec[0].base;
- const uint8_t *input = in_vec[0].base;
- size_t input_length = in_vec[0].len;
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
+ const uint8_t *input = in_vec[1].base;
+ size_t input_length = in_vec[1].len;
unsigned char *output = out_vec[1].base;
size_t output_size = out_vec[1].len;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
+
/* Initialise the output_length to zero */
out_vec[1].len = 0;
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
@@ -338,17 +386,21 @@
if ((ctx->iv_required == 1) && (ctx->iv_set == 0)) {
if (ctx->cipher_mode != ENGINE_CIPHER_MODE_DECRYPT) {
- (void)tfm_crypto_cipher_release(operation, ctx);
+ if (tfm_crypto_cipher_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_BAD_STATE;
}
/* This call is used to set the IV on the object */
- return _psa_cipher_set_iv(operation, input, input_length);
+ return _psa_cipher_set_iv(handle_out, input, input_length);
}
/* If the key is not set, setup phase has not been completed */
if (ctx->key_set == 0) {
- (void)tfm_crypto_cipher_release(operation, ctx);
+ if (tfm_crypto_cipher_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_BAD_STATE;
}
@@ -356,7 +408,9 @@
* of input data whose length is equal to the block size
*/
if (input_length > output_size) {
- (void)tfm_crypto_cipher_release(operation, ctx);
+ if (tfm_crypto_cipher_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_BUFFER_TOO_SMALL;
}
@@ -367,7 +421,9 @@
output,
(uint32_t *)&(out_vec[1].len));
if (status != PSA_SUCCESS) {
- (void)tfm_crypto_cipher_release(operation, ctx);
+ if (tfm_crypto_cipher_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return status;
}
@@ -382,24 +438,29 @@
psa_status_t status = PSA_SUCCESS;
struct tfm_cipher_operation_s *ctx = NULL;
- if ((in_len != 0) || (out_len != 2)) {
+ if ((in_len != 1) || (out_len != 2)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_cipher_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
-
- psa_cipher_operation_t *operation = out_vec[0].base;
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
unsigned char *output = out_vec[1].base;
size_t output_size = out_vec[1].len;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
+
/* Initialise the output_length to zero */
out_vec[1].len = 0;
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
@@ -409,7 +470,9 @@
* output data.
*/
if (output_size < ctx->block_size) {
- (void)tfm_crypto_cipher_release(operation, ctx);
+ if (tfm_crypto_cipher_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_BUFFER_TOO_SMALL;
}
@@ -419,11 +482,17 @@
(uint32_t *)&(out_vec[1].len));
if (status != PSA_SUCCESS) {
out_vec[1].len = 0;
- (void)tfm_crypto_cipher_release(operation, ctx);
+ if (tfm_crypto_cipher_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return status;
}
- return tfm_crypto_cipher_release(operation, ctx);
+ status = tfm_crypto_cipher_release(&handle, ctx);
+ if (status == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
+ return status;
}
psa_status_t tfm_crypto_cipher_abort(psa_invec in_vec[],
@@ -434,24 +503,33 @@
psa_status_t status = PSA_SUCCESS;
struct tfm_cipher_operation_s *ctx = NULL;
- if ((in_len != 0) || (out_len != 1)) {
+ if ((in_len != 1) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_cipher_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
- psa_cipher_operation_t *operation = out_vec[0].base;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
}
- return tfm_crypto_cipher_release(operation, ctx);
+ status = tfm_crypto_cipher_release(&handle, ctx);
+ if (status == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
+ return status;
}
/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_engine.h b/secure_fw/services/crypto/crypto_engine.h
index 6263aae..3130396 100644
--- a/secure_fw/services/crypto/crypto_engine.h
+++ b/secure_fw/services/crypto/crypto_engine.h
@@ -25,6 +25,7 @@
#if !defined(MBEDTLS_CONFIG_FILE)
#include "platform/ext/common/tfm_mbedtls_config.h"
#else
+// cppcheck-suppress preprocessorErrorDirective
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/secure_fw/services/crypto/crypto_hash.c b/secure_fw/services/crypto/crypto_hash.c
index cd546b9..36e5759 100644
--- a/secure_fw/services/crypto/crypto_hash.c
+++ b/secure_fw/services/crypto/crypto_hash.c
@@ -9,6 +9,12 @@
#include "crypto_engine.h"
#include "tfm_crypto_struct.h"
+/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
+ * integrity checks but this will have to be revised
+ * when the full set of error codes mandated by PSA FF
+ * is available.
+ */
+
/**
* \brief Release all resources associated with a hash operation.
*
@@ -17,7 +23,7 @@
*
* \return Return values as described in \ref tfm_crypto_err_t
*/
-static psa_status_t tfm_crypto_hash_release(psa_hash_operation_t *operation,
+static psa_status_t tfm_crypto_hash_release(uint32_t *handle,
struct tfm_hash_operation_s *ctx)
{
psa_status_t status = PSA_SUCCESS;
@@ -29,7 +35,7 @@
}
/* Release the operation context */
- return tfm_crypto_operation_release(TFM_CRYPTO_HASH_OPERATION, operation);
+ return tfm_crypto_operation_release(handle);
}
/*!
@@ -51,13 +57,17 @@
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_hash_operation_t)) ||
- (in_vec[0].len != sizeof(psa_algorithm_t))) {
+ if ((out_vec[0].len != sizeof(uint32_t)) ||
+ (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
+ psa_algorithm_t alg = iov->alg;
- psa_hash_operation_t *operation = out_vec[0].base;
- psa_algorithm_t alg = *((psa_algorithm_t *)in_vec[0].base);
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
if (PSA_ALG_IS_HASH(alg) == 0) {
return PSA_ERROR_INVALID_ARGUMENT;
@@ -71,12 +81,14 @@
/* Allocate the operation context in the secure world */
status = tfm_crypto_operation_alloc(TFM_CRYPTO_HASH_OPERATION,
- operation,
+ &handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
}
+ *handle_out = handle;
+
/* Bind the algorithm to the hash context */
ctx->alg = alg;
@@ -84,7 +96,7 @@
status = tfm_crypto_engine_hash_start(&(ctx->engine_ctx), &engine_info);
if (status != PSA_SUCCESS) {
/* Release the operation context, ignore if the operation fails. */
- (void)tfm_crypto_hash_release(operation, ctx);
+ (void)tfm_crypto_hash_release(&handle, ctx);
return status;
}
@@ -99,21 +111,26 @@
psa_status_t status = PSA_SUCCESS;
struct tfm_hash_operation_s *ctx = NULL;
- if ((in_len != 1) || (out_len != 1)) {
+ if ((in_len != 2) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_hash_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
+ const uint8_t *input = in_vec[1].base;
+ size_t input_length = in_vec[1].len;
- psa_hash_operation_t *operation = out_vec[0].base;
- const uint8_t *input = in_vec[0].base;
- size_t input_length = in_vec[0].len;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
@@ -124,7 +141,9 @@
input,
input_length);
if (status != PSA_SUCCESS) {
- (void)tfm_crypto_hash_release(operation, ctx);
+ if (tfm_crypto_hash_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return status;
}
@@ -139,59 +158,80 @@
psa_status_t status = PSA_SUCCESS;
struct tfm_hash_operation_s *ctx = NULL;
- if ((in_len != 0) || (out_len != 2)) {
+ if ((in_len != 1) || (out_len != 2)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_hash_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
-
- psa_hash_operation_t *operation = out_vec[0].base;
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
uint8_t *hash = out_vec[1].base;
size_t hash_size = out_vec[1].len;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
+
/* Initialise hash_length to zero */
out_vec[1].len = 0;
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
}
if (hash_size < PSA_HASH_SIZE(ctx->alg)) {
- (void)tfm_crypto_hash_release(operation, ctx);
+ if (tfm_crypto_hash_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_BUFFER_TOO_SMALL;
}
/* Finalise the hash value using the engine */
status = tfm_crypto_engine_hash_finish(&(ctx->engine_ctx), hash);
if (status != PSA_SUCCESS) {
- (void)tfm_crypto_hash_release(operation, ctx);
+ if (tfm_crypto_hash_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return status;
}
/* Set the length of the hash that has been produced */
out_vec[1].len = PSA_HASH_SIZE(ctx->alg);
- return tfm_crypto_hash_release(operation, ctx);
+ status = tfm_crypto_hash_release(&handle, ctx);
+ if (status == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
+ return status;
}
-static psa_status_t _psa_hash_finish(psa_hash_operation_t *operation,
+static psa_status_t _psa_hash_finish(uint32_t *handle,
uint8_t *hash,
size_t hash_size,
size_t *hash_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_FINISH_SFID,
+ .handle = *handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = handle, .len = sizeof(uint32_t)},
{.base = hash, .len = hash_size},
};
- status = tfm_crypto_hash_finish(NULL, 0,
+ status = tfm_crypto_hash_finish(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
*hash_length = out_vec[1].len;
@@ -208,20 +248,21 @@
size_t digest_length;
uint32_t idx, comp_mismatch = 0;
- if ((in_len != 1) || (out_len != 1)) {
+ if ((in_len != 2) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_hash_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
- psa_hash_operation_t *operation = out_vec[0].base;
- const uint8_t *hash = in_vec[0].base;
- size_t hash_length = in_vec[0].len;
+ uint32_t *handle_out = out_vec[0].base;
+ const uint8_t *hash = in_vec[1].base;
+ size_t hash_length = in_vec[1].len;
/* Finalise the hash operation */
- status = _psa_hash_finish(operation,
+ status = _psa_hash_finish(handle_out,
digest,
PSA_HASH_MAX_SIZE,
&digest_length);
@@ -257,24 +298,33 @@
psa_status_t status = PSA_SUCCESS;
struct tfm_hash_operation_s *ctx = NULL;
- if ((in_len != 0) || (out_len != 1)) {
+ if ((in_len != 1) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_hash_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
- psa_hash_operation_t *operation = out_vec[0].base;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
}
- return tfm_crypto_hash_release(operation, ctx);
+ status = tfm_crypto_hash_release(&handle, ctx);
+ if (status == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
+ return status;
}
/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_init.c b/secure_fw/services/crypto/crypto_init.c
index 1ec7dee..aaabea8 100644
--- a/secure_fw/services/crypto/crypto_init.c
+++ b/secure_fw/services/crypto/crypto_init.c
@@ -8,6 +8,254 @@
#include "tfm_crypto_api.h"
#include "crypto_engine.h"
+#ifdef TFM_PSA_API
+#include "psa_service.h"
+#include "tfm_crypto_signal.h"
+#include "secure_fw/core/tfm_memory_utils.h"
+
+/**
+ * \brief Table containing all the Uniform Signature API exposed
+ * by the TF-M Crypto partition
+ */
+static const tfm_crypto_us_t sfid_func_table[TFM_CRYPTO_SFID_MAX] = {
+ tfm_crypto_import_key,
+ tfm_crypto_destroy_key,
+ tfm_crypto_get_key_information,
+ tfm_crypto_export_key,
+ tfm_crypto_key_policy_init,
+ tfm_crypto_key_policy_set_usage,
+ tfm_crypto_key_policy_get_usage,
+ tfm_crypto_key_policy_get_algorithm,
+ tfm_crypto_set_key_policy,
+ tfm_crypto_get_key_policy,
+ tfm_crypto_set_key_lifetime,
+ tfm_crypto_get_key_lifetime,
+ tfm_crypto_cipher_set_iv,
+ tfm_crypto_cipher_encrypt_setup,
+ tfm_crypto_cipher_decrypt_setup,
+ tfm_crypto_cipher_update,
+ tfm_crypto_cipher_abort,
+ tfm_crypto_cipher_finish,
+ tfm_crypto_hash_setup,
+ tfm_crypto_hash_update,
+ tfm_crypto_hash_finish,
+ tfm_crypto_hash_verify,
+ tfm_crypto_hash_abort,
+ tfm_crypto_mac_sign_setup,
+ tfm_crypto_mac_verify_setup,
+ tfm_crypto_mac_update,
+ tfm_crypto_mac_sign_finish,
+ tfm_crypto_mac_verify_finish,
+ tfm_crypto_mac_abort,
+ tfm_crypto_aead_encrypt,
+ tfm_crypto_aead_decrypt
+};
+
+/**
+ * \brief Aligns a value x up to an alignment a.
+ */
+#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
+
+/**
+ * \brief Maximum alignment required by any iovec parameters to the TF-M Crypto
+ * partition.
+ */
+#define TFM_CRYPTO_IOVEC_ALIGNMENT (4u)
+
+/**
+ * \brief Default size of the internal scratch buffer used for IOVec allocations
+ * in bytes
+ */
+#ifndef TFM_CRYPTO_IOVEC_BUFFER_SIZE
+#define TFM_CRYPTO_IOVEC_BUFFER_SIZE (1024)
+#endif
+
+/**
+ * \brief Internal scratch used for IOVec allocations
+ *
+ */
+static struct tfm_crypto_scratch {
+ __attribute__((__aligned__(TFM_CRYPTO_IOVEC_ALIGNMENT)))
+ uint8_t buf[TFM_CRYPTO_IOVEC_BUFFER_SIZE];
+ uint32_t alloc_index;
+} scratch = {.buf = {0}, .alloc_index = 0};
+
+static psa_status_t tfm_crypto_alloc_scratch(size_t requested_size, void **buf)
+{
+ /* Ensure alloc_index remains aligned to the required iovec alignment */
+ requested_size = ALIGN(requested_size, TFM_CRYPTO_IOVEC_ALIGNMENT);
+
+ if (requested_size > (sizeof(scratch.buf) - scratch.alloc_index)) {
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ /* Compute the pointer to the allocated space */
+ *buf = (void *)&scratch.buf[scratch.alloc_index];
+
+ /* Increase the allocated size */
+ scratch.alloc_index += requested_size;
+
+ return PSA_SUCCESS;
+}
+
+static psa_status_t tfm_crypto_clear_scratch(void)
+{
+ scratch.alloc_index = 0;
+ (void)tfm_memset(scratch.buf, 0, sizeof(scratch.buf));
+
+ return PSA_SUCCESS;
+}
+
+static psa_status_t tfm_crypto_call_sfn(psa_msg_t *msg,
+ struct tfm_crypto_pack_iovec *iov,
+ const uint32_t sfn_id)
+{
+ psa_status_t status = PSA_SUCCESS;
+ size_t in_len = 0, out_len = 0, i, read_size;
+ psa_invec in_vec[PSA_MAX_IOVEC] = { {0} };
+ psa_outvec out_vec[PSA_MAX_IOVEC] = { {0} };
+ void *alloc_buf_ptr = NULL;
+
+ /* Check the number of in_vec filled */
+ while ((in_len < PSA_MAX_IOVEC) && (msg->in_size[in_len] != 0)) {
+ in_len++;
+ }
+
+ /* There will always be a tfm_crypto_pack_iovec in the first iovec */
+ if (in_len < 1) {
+ return PSA_ERROR_UNKNOWN_ERROR;
+ }
+ /* Initialise the first iovec with the IOV read when parsing */
+ in_vec[0].base = iov;
+ in_vec[0].len = sizeof(struct tfm_crypto_pack_iovec);
+
+ /* Alloc/read from the second element as the first is read when parsing */
+ for (i = 1; i < in_len; i++) {
+ /* Allocate necessary space in the internal scratch */
+ status = tfm_crypto_alloc_scratch(msg->in_size[i], &alloc_buf_ptr);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+ /* Read from the IPC framework inputs into the scratch */
+ read_size = psa_read(msg->handle, i, alloc_buf_ptr, msg->in_size[i]);
+ /* Populate the fields of the input to the secure function */
+ in_vec[i].base = alloc_buf_ptr;
+ in_vec[i].len = msg->in_size[i];
+ }
+
+ /* Check the number of out_vec filled */
+ while ((out_len < PSA_MAX_IOVEC) && (msg->out_size[out_len] != 0)) {
+ out_len++;
+ }
+
+ for (i = 0; i < out_len; i++) {
+ /* Allocate necessary space for the output in the internal scratch */
+ status = tfm_crypto_alloc_scratch(msg->out_size[i], &alloc_buf_ptr);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+ /* Populate the fields of the output to the secure function */
+ out_vec[i].base = alloc_buf_ptr;
+ out_vec[i].len = msg->out_size[i];
+ }
+
+ /* Call the uniform signature API */
+ status = sfid_func_table[sfn_id](in_vec, in_len, out_vec, out_len);
+
+ /* Write into the IPC framework outputs from the scratch */
+ for (i = 0; i < out_len; i++) {
+ psa_write(msg->handle, i, out_vec[i].base, out_vec[i].len);
+ }
+
+ /* Clear the allocated internal scratch before returning */
+ if (tfm_crypto_clear_scratch() != PSA_SUCCESS) {
+ return PSA_ERROR_UNKNOWN_ERROR;
+ }
+
+ return status;
+}
+
+static psa_status_t tfm_crypto_parse_msg(psa_msg_t *msg,
+ struct tfm_crypto_pack_iovec *iov,
+ uint32_t *sfn_id_p)
+{
+ size_t read_size;
+
+ /* Read the in_vec[0] which holds the IOVEC always */
+ read_size = psa_read(msg->handle,
+ 0,
+ iov,
+ sizeof(struct tfm_crypto_pack_iovec));
+
+ if (read_size != sizeof(struct tfm_crypto_pack_iovec)) {
+ return PSA_ERROR_UNKNOWN_ERROR;
+ }
+
+ if (iov->sfn_id >= TFM_CRYPTO_SFID_MAX) {
+ *sfn_id_p = TFM_CRYPTO_SFID_INVALID;
+ return PSA_ERROR_UNKNOWN_ERROR;
+ }
+
+ *sfn_id_p = iov->sfn_id;
+
+ return PSA_SUCCESS;
+}
+
+static void tfm_crypto_ipc_handler(void)
+{
+ psa_signal_t signals = 0;
+ psa_msg_t msg;
+ psa_status_t status = PSA_SUCCESS;
+ uint32_t sfn_id = TFM_CRYPTO_SFID_INVALID;
+ struct tfm_crypto_pack_iovec iov = {0};
+
+ while (1) {
+ signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
+ if (signals & TFM_CRYPTO_SIG) {
+ /* Extract the message */
+ if (psa_get(TFM_CRYPTO_SIG, &msg) != PSA_SUCCESS) {
+ /* FIXME: Should be replaced by TF-M error handling */
+ while (1) {
+ ;
+ }
+ }
+
+ /* Process the message type */
+ switch (msg.type) {
+ case PSA_IPC_CONNECT:
+ case PSA_IPC_DISCONNECT:
+ psa_reply(msg.handle, PSA_SUCCESS);
+ break;
+ case PSA_IPC_CALL:
+ /* Parse the message */
+ status = tfm_crypto_parse_msg(&msg, &iov, &sfn_id);
+ /* Call the dispatcher based on the SFID passed as type */
+ if (sfn_id != TFM_CRYPTO_SFID_INVALID) {
+ status = tfm_crypto_call_sfn(&msg, &iov, sfn_id);
+ } else {
+ status = PSA_ERROR_UNKNOWN_ERROR;
+ }
+ psa_reply(msg.handle, status);
+ break;
+ default:
+ /* FIXME: Should be replaced by TF-M error handling */
+ while (1) {
+ ;
+ }
+ }
+ } else {
+ /* FIXME: Should be replaced by TF-M error handling */
+ while (1) {
+ ;
+ }
+ }
+ }
+
+ /* This is unreachable */
+ return;
+}
+#endif /* TFM_PSA_API */
+
static psa_status_t tfm_crypto_module_init(void)
{
psa_status_t status = PSA_SUCCESS;
@@ -35,13 +283,13 @@
/* Initialise the engine interface module */
status = tfm_crypto_engine_init();
if (status != PSA_SUCCESS) {
- /* FIXME: For the time being, keep returning success even if the engine
- * is not initialised correctly. This can be used to test corner cases
- * without triggering any TF-M recovery mechanism during boot-up if it
- * recognises that a service has not completed booting correctly.
- */
- return PSA_SUCCESS;
+ return status;
}
- return PSA_SUCCESS;
+#ifdef TFM_PSA_API
+ /* Should not return in normal operations */
+ tfm_crypto_ipc_handler();
+#endif
+
+ return status;
}
diff --git a/secure_fw/services/crypto/crypto_key.c b/secure_fw/services/crypto/crypto_key.c
index 2bef9ca..dc55de6 100644
--- a/secure_fw/services/crypto/crypto_key.c
+++ b/secure_fw/services/crypto/crypto_key.c
@@ -13,6 +13,12 @@
#include "tfm_crypto_defs.h"
#include "secure_fw/core/tfm_memory_utils.h"
+/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
+ * integrity checks but this will have to be revised
+ * when the full set of error codes mandated by PSA FF
+ * is available.
+ */
+
/**
* \brief This is the default value of maximum number of simultaneous
* key stores supported.
@@ -153,19 +159,19 @@
struct tfm_crypto_key_storage_s *key_store = NULL;
size_t i;
- if ((in_len != 3) || (out_len != 0)) {
+ if ((in_len != 2) || (out_len != 0)) {
return PSA_CONNECTION_REFUSED;
}
- if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
- (in_vec[1].len != sizeof(psa_key_type_t))) {
+ if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
- psa_key_type_t type = *((psa_key_type_t *)in_vec[1].base);
- const uint8_t *data = in_vec[2].base;
- size_t data_length = in_vec[2].len;
+ psa_key_slot_t key = iov->key;
+ psa_key_type_t type = iov->type;
+ const uint8_t *data = in_vec[1].base;
+ size_t data_length = in_vec[1].len;
key_store = get_key_store(key);
if (key_store == NULL) {
@@ -204,11 +210,12 @@
return PSA_CONNECTION_REFUSED;
}
- if (in_vec[0].len != sizeof(psa_key_slot_t)) {
+ if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
+ psa_key_slot_t key = iov->key;
key_store = get_key_store(key);
if (key_store == NULL) {
@@ -240,13 +247,14 @@
return PSA_CONNECTION_REFUSED;
}
- if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
(out_vec[0].len != sizeof(psa_key_type_t)) ||
(out_vec[1].len != sizeof(size_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
+ psa_key_slot_t key = iov->key;
psa_key_type_t *type = out_vec[0].base;
size_t *bits = out_vec[1].base;
@@ -279,11 +287,12 @@
return PSA_CONNECTION_REFUSED;
}
- if (in_vec[0].len != sizeof(psa_key_slot_t)) {
+ if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
+ psa_key_slot_t key = iov->key;
uint8_t *data = out_vec[0].base;
size_t data_size = out_vec[0].len;
@@ -310,11 +319,12 @@
psa_outvec out_vec[],
size_t out_len)
{
- if ((in_len != 0) || (out_len != 1)) {
+ if ((in_len != 1) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if (out_vec[0].len != sizeof(psa_key_policy_t)) {
+ if ((out_vec[0].len != sizeof(psa_key_policy_t)) ||
+ (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
return PSA_CONNECTION_REFUSED;
}
@@ -331,19 +341,19 @@
psa_outvec out_vec[],
size_t out_len)
{
- if ((in_len != 2) || (out_len != 1)) {
+ if ((in_len != 1) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
if ((out_vec[0].len != sizeof(psa_key_policy_t)) ||
- (in_vec[0].len != sizeof(psa_key_usage_t)) ||
- (in_vec[1].len != sizeof(psa_algorithm_t))) {
+ (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
psa_key_policy_t *policy = out_vec[0].base;
- psa_key_usage_t usage = *((psa_key_usage_t *)in_vec[0].base);
- psa_algorithm_t alg = *((psa_algorithm_t *)in_vec[1].base);
+ psa_key_usage_t usage = iov->usage;
+ psa_algorithm_t alg = iov->alg;
policy->usage = usage;
policy->alg = alg;
@@ -356,16 +366,17 @@
psa_outvec out_vec[],
size_t out_len)
{
- if ((in_len != 1) || (out_len != 1)) {
+ if ((in_len != 2) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((in_vec[0].len != sizeof(psa_key_policy_t)) ||
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (in_vec[1].len != sizeof(psa_key_policy_t)) ||
(out_vec[0].len != sizeof(psa_key_usage_t))) {
return PSA_CONNECTION_REFUSED;
}
- const psa_key_policy_t *policy = in_vec[0].base;
+ const psa_key_policy_t *policy = in_vec[1].base;
psa_key_usage_t *usage = out_vec[0].base;
*usage = policy->usage;
@@ -378,16 +389,17 @@
psa_outvec out_vec[],
size_t out_len)
{
- if ((in_len != 1) || (out_len != 1)) {
+ if ((in_len != 2) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((in_vec[0].len != sizeof(psa_key_policy_t)) ||
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (in_vec[1].len != sizeof(psa_key_policy_t)) ||
(out_vec[0].len != sizeof(psa_algorithm_t))) {
return PSA_CONNECTION_REFUSED;
}
- const psa_key_policy_t *policy = in_vec[0].base;
+ const psa_key_policy_t *policy = in_vec[1].base;
psa_algorithm_t *alg = out_vec[0].base;
*alg = policy->alg;
@@ -406,12 +418,13 @@
return PSA_CONNECTION_REFUSED;
}
- if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
(in_vec[1].len != sizeof(psa_key_policy_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
+ psa_key_slot_t key = iov->key;
const psa_key_policy_t *policy = in_vec[1].base;
/* Check that the policy is valid */
@@ -452,12 +465,13 @@
return PSA_CONNECTION_REFUSED;
}
- if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
(out_vec[0].len != sizeof(psa_key_policy_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
+ psa_key_slot_t key = iov->key;
psa_key_policy_t *policy = out_vec[0].base;
key_store = get_key_store(key);
@@ -477,17 +491,17 @@
{
struct tfm_crypto_key_storage_s *key_store = NULL;
- if ((in_len != 2) || (out_len != 0)) {
+ if ((in_len != 1) || (out_len != 0)) {
return PSA_CONNECTION_REFUSED;
}
- if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
- (in_vec[1].len != sizeof(psa_key_lifetime_t))) {
+ if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
- psa_key_lifetime_t lifetime = *((psa_key_lifetime_t *)in_vec[1].base);
+ psa_key_slot_t key = iov->key;
+ psa_key_lifetime_t lifetime = iov->lifetime;
/* Check that the lifetime is valid */
if (lifetime != PSA_KEY_LIFETIME_VOLATILE
@@ -529,12 +543,13 @@
return PSA_CONNECTION_REFUSED;
}
- if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
(out_vec[0].len != sizeof(psa_key_lifetime_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
+ psa_key_slot_t key = iov->key;
psa_key_lifetime_t *lifetime = out_vec[0].base;
key_store = get_key_store(key);
diff --git a/secure_fw/services/crypto/crypto_mac.c b/secure_fw/services/crypto/crypto_mac.c
index 7000b18..ae6a00b 100644
--- a/secure_fw/services/crypto/crypto_mac.c
+++ b/secure_fw/services/crypto/crypto_mac.c
@@ -10,78 +10,128 @@
#include "crypto_engine.h"
#include "tfm_crypto_struct.h"
+/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
+ * integrity checks but this will have to be revised
+ * when the full set of error codes mandated by PSA FF
+ * is available.
+ */
+
static psa_status_t _psa_get_key_information(psa_key_slot_t key,
psa_key_type_t *type,
size_t *bits)
{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_KEY_INFORMATION_SFID,
+ .key = key,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = type, .len = sizeof(psa_key_type_t)},
{.base = bits, .len = sizeof(size_t)}
};
- return tfm_crypto_get_key_information(
+ status = tfm_crypto_get_key_information(
in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+
+ return status;
}
-static psa_status_t _psa_hash_setup(psa_hash_operation_t *operation,
+static psa_status_t _psa_hash_setup(uint32_t *handle,
psa_algorithm_t alg)
{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_SETUP_SFID,
+ .alg = alg,
+ .handle = *handle,
+ };
+
psa_invec in_vec[] = {
- {.base = &alg, .len = sizeof(psa_algorithm_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = handle, .len = sizeof(uint32_t)},
};
- return tfm_crypto_hash_setup(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
+ status = tfm_crypto_hash_setup(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+
+ return status;
}
-static psa_status_t _psa_hash_update(psa_hash_operation_t *operation,
+static psa_status_t _psa_hash_update(uint32_t *handle,
const uint8_t *input,
size_t input_length)
{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_UPDATE_SFID,
+ .handle = *handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = input, .len = input_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = handle, .len = sizeof(uint32_t)},
};
- return tfm_crypto_hash_update(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
+ status = tfm_crypto_hash_update(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+
+ return status;
}
-static psa_status_t _psa_hash_finish(psa_hash_operation_t *operation,
+static psa_status_t _psa_hash_finish(uint32_t *handle,
uint8_t *hash,
size_t hash_size,
size_t *hash_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_FINISH_SFID,
+ .handle = *handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = handle, .len = sizeof(uint32_t)},
{.base = hash, .len = hash_size},
};
- status = tfm_crypto_hash_finish(NULL, 0,
+ status = tfm_crypto_hash_finish(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
*hash_length = out_vec[1].len;
return status;
}
-static psa_status_t _psa_hash_abort(psa_hash_operation_t *operation)
+static psa_status_t _psa_hash_abort(uint32_t *handle)
{
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_ABORT_SFID,
+ .handle = *handle,
};
- return tfm_crypto_hash_abort(NULL, 0,
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = handle, .len = sizeof(uint32_t)},
+ };
+
+ status = tfm_crypto_hash_abort(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+
+ return status;
}
/**
@@ -132,14 +182,14 @@
}
}
-static psa_status_t tfm_crypto_mac_release(psa_mac_operation_t *operation,
+static psa_status_t tfm_crypto_mac_release(uint32_t *handle,
struct tfm_mac_operation_s *ctx)
{
/* No release necessary on the ctx related items for the time being */
UNUSED_VAR(ctx);
/* Release the operation context */
- return tfm_crypto_operation_release(TFM_CRYPTO_MAC_OPERATION, operation);
+ return tfm_crypto_operation_release(handle);
}
static psa_status_t tfm_crypto_hmac_setup(struct tfm_mac_operation_s *ctx,
@@ -197,13 +247,13 @@
*/
if (key_size > block_size) {
/* Hash the key to reduce it to block size */
- status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation.handle),
PSA_ALG_HMAC_HASH(alg));
if (status != PSA_SUCCESS) {
return status;
}
- status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation.handle),
&key_data[0],
key_size);
if (status != PSA_SUCCESS) {
@@ -211,7 +261,7 @@
}
/* Replace the key with the hashed key */
- status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation.handle),
hashed_key,
sizeof(hashed_key),
&key_size);
@@ -237,7 +287,7 @@
}
/* Start hash1 = H(i_key_pad || message) */
- status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation.handle),
PSA_ALG_HMAC_HASH(alg));
if (status != PSA_SUCCESS) {
/* Clear key information on stack */
@@ -248,17 +298,13 @@
return status;
}
- status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation.handle),
ipad,
block_size);
- if (status != PSA_SUCCESS) {
- return status;
- }
-
- return PSA_SUCCESS;
+ return status;
}
-static psa_status_t tfm_crypto_mac_setup(psa_mac_operation_t *operation,
+static psa_status_t tfm_crypto_mac_setup(uint32_t *handle,
psa_key_slot_t key,
psa_algorithm_t alg,
uint8_t sign_operation)
@@ -272,7 +318,7 @@
/* Allocate the operation context in the secure world */
status = tfm_crypto_operation_alloc(TFM_CRYPTO_MAC_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
@@ -294,7 +340,7 @@
status = tfm_crypto_hmac_setup(ctx, key, alg);
if (status != PSA_SUCCESS) {
/* Release the operation context */
- (void)tfm_crypto_mac_release(operation, ctx);
+ (void)tfm_crypto_mac_release(handle, ctx);
return status;
}
@@ -302,14 +348,14 @@
} else {
/* Other MAC types constructions are not supported */
/* Release the operation context */
- (void)tfm_crypto_mac_release(operation, ctx);
+ (void)tfm_crypto_mac_release(handle, ctx);
return PSA_ERROR_NOT_SUPPORTED;
}
return PSA_SUCCESS;
}
-static psa_status_t tfm_crypto_mac_finish(psa_mac_operation_t *operation,
+static psa_status_t tfm_crypto_mac_finish(uint32_t *handle,
struct tfm_mac_operation_s *ctx,
uint8_t *mac,
size_t mac_size,
@@ -323,12 +369,12 @@
/* Sanity checks */
if (mac_size < ctx->mac_size) {
- (void)tfm_crypto_mac_release(operation, ctx);
+ (void)tfm_crypto_mac_release(handle, ctx);
return PSA_ERROR_BUFFER_TOO_SMALL;
}
if (!(ctx->has_input)) {
- (void)tfm_crypto_mac_release(operation, ctx);
+ (void)tfm_crypto_mac_release(handle, ctx);
return PSA_ERROR_BAD_STATE;
}
@@ -337,49 +383,49 @@
block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(ctx->alg));
/* finish the hash1 = H(ipad || message) */
- status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation.handle),
hash1,
sizeof(hash1),
&hash_size);
if (status != PSA_SUCCESS) {
- (void)tfm_crypto_mac_release(operation, ctx);
+ (void)tfm_crypto_mac_release(handle, ctx);
return status;
}
/* compute the final mac value = H(opad || hash1) */
- status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation.handle),
PSA_ALG_HMAC_HASH(ctx->alg));
if (status != PSA_SUCCESS) {
mac_zeroize(hash1, sizeof(hash1));
- (void)tfm_crypto_mac_release(operation, ctx);
+ (void)tfm_crypto_mac_release(handle, ctx);
return status;
}
- status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation.handle),
opad,
block_size);
if (status != PSA_SUCCESS) {
mac_zeroize(hash1, sizeof(hash1));
- (void)tfm_crypto_mac_release(operation, ctx);
+ (void)tfm_crypto_mac_release(handle, ctx);
return status;
}
- status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation.handle),
hash1,
hash_size);
if (status != PSA_SUCCESS) {
mac_zeroize(hash1, sizeof(hash1));
- (void)tfm_crypto_mac_release(operation, ctx);
+ (void)tfm_crypto_mac_release(handle, ctx);
return status;
}
- status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation.handle),
mac,
mac_size,
mac_length);
if (status != PSA_SUCCESS) {
mac_zeroize(hash1, sizeof(hash1));
- (void)tfm_crypto_mac_release(operation, ctx);
+ (void)tfm_crypto_mac_release(handle, ctx);
return status;
}
@@ -390,7 +436,7 @@
return PSA_ERROR_INVALID_ARGUMENT;
}
- return tfm_crypto_mac_release(operation, ctx);
+ return tfm_crypto_mac_release(handle, ctx);
}
/*!
@@ -404,21 +450,28 @@
psa_outvec out_vec[],
size_t out_len)
{
- if ((in_len != 2) || (out_len != 1)) {
+ psa_status_t status = PSA_SUCCESS;
+ if ((in_len != 1) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_mac_operation_t)) ||
- (in_vec[0].len != sizeof(psa_key_slot_t)) ||
- (in_vec[1].len != sizeof(psa_algorithm_t))) {
+ if ((out_vec[0].len != sizeof(uint32_t)) ||
+ (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
+ psa_key_slot_t key = iov->key;
+ psa_algorithm_t alg = iov->alg;
- psa_mac_operation_t *operation = out_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
- psa_algorithm_t alg = *((psa_algorithm_t *)in_vec[1].base);
-
- return tfm_crypto_mac_setup(operation, key, alg, 1);
+ status = tfm_crypto_mac_setup(&handle, key, alg, 1);
+ if (status == PSA_SUCCESS) {
+ *handle_out = handle;
+ } else {
+ *handle_out = iov->handle;
+ }
+ return status;
}
psa_status_t tfm_crypto_mac_verify_setup(psa_invec in_vec[],
@@ -426,21 +479,28 @@
psa_outvec out_vec[],
size_t out_len)
{
- if ((in_len != 2) || (out_len != 1)) {
+ psa_status_t status = PSA_SUCCESS;
+ if ((in_len != 1) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_mac_operation_t)) ||
- (in_vec[0].len != sizeof(psa_key_slot_t)) ||
- (in_vec[1].len != sizeof(psa_algorithm_t))) {
+ if ((out_vec[0].len != sizeof(uint32_t)) ||
+ (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
+ psa_key_slot_t key = iov->key;
+ psa_algorithm_t alg = iov->alg;
- psa_mac_operation_t *operation = out_vec[0].base;
- psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
- psa_algorithm_t alg = *((psa_algorithm_t *)in_vec[1].base);
-
- return tfm_crypto_mac_setup(operation, key, alg, 0);
+ status = tfm_crypto_mac_setup(&handle, key, alg, 0);
+ if (status == PSA_SUCCESS) {
+ *handle_out = handle;
+ } else {
+ *handle_out = iov->handle;
+ }
+ return status;
}
psa_status_t tfm_crypto_mac_update(psa_invec in_vec[],
@@ -451,21 +511,26 @@
psa_status_t status = PSA_SUCCESS;
struct tfm_mac_operation_s *ctx = NULL;
- if ((in_len != 1) || (out_len != 1)) {
+ if ((in_len != 2) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_mac_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
+ const uint8_t *input = in_vec[1].base;
+ size_t input_length = in_vec[1].len;
- psa_mac_operation_t *operation = out_vec[0].base;
- const uint8_t *input = in_vec[0].base;
- size_t input_length = in_vec[0].len;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
@@ -473,28 +538,36 @@
/* Sanity check */
if (!(ctx->key_set)) {
- (void)tfm_crypto_mac_release(operation, ctx);
+ if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_BAD_STATE;
}
if (input_length == 0) {
- (void)tfm_crypto_mac_release(operation, ctx);
+ if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_INVALID_ARGUMENT;
}
/* Process the input chunk */
if (PSA_ALG_IS_HMAC(ctx->alg)) {
- status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation),
+ status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation.handle),
input,
input_length);
if (status != PSA_SUCCESS) {
- (void)tfm_crypto_mac_release(operation, ctx);
+ if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return status;
}
/* Set this flag to avoid HMAC without data */
ctx->has_input = 1;
} else {
- (void)tfm_crypto_mac_release(operation, ctx);
+ if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_INVALID_ARGUMENT;
}
@@ -509,18 +582,23 @@
psa_status_t status = PSA_SUCCESS;
struct tfm_mac_operation_s *ctx = NULL;
- if ((in_len != 0) || (out_len != 2)) {
+ if ((in_len != 1) || (out_len != 2)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_mac_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
-
- psa_mac_operation_t *operation = out_vec[0].base;
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
uint8_t *mac = out_vec[1].base;
size_t mac_size = out_vec[1].len;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
+
/* Initialise mac_length to zero */
out_vec[1].len = 0;
@@ -530,7 +608,7 @@
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
@@ -538,19 +616,17 @@
if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
/* Finalise the mac operation */
- status = tfm_crypto_mac_finish(operation,
+ status = tfm_crypto_mac_finish(&handle,
ctx, mac, mac_size, &(out_vec[1].len));
- if (status != PSA_SUCCESS) {
- return status;
- }
- /* A call to tfm_crypto_mac_finish() always releases the operation */
-
} else {
- (void)tfm_crypto_mac_release(operation, ctx);
+ if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_BAD_STATE;
}
- return PSA_SUCCESS;
+ *handle_out = handle;
+ return status;
}
psa_status_t tfm_crypto_mac_verify_finish(psa_invec in_vec[],
@@ -565,17 +641,22 @@
size_t i;
uint32_t comp_mismatch = 0;
- if ((in_len != 1) || (out_len != 1)) {
+ if ((in_len != 2) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_mac_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
+ const uint8_t *mac = in_vec[1].base;
+ size_t mac_length = in_vec[1].len;
- psa_mac_operation_t *operation = out_vec[0].base;
- const uint8_t *mac = in_vec[0].base;
- size_t mac_length = in_vec[0].len;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
if (mac_length == 0) {
return PSA_ERROR_INVALID_ARGUMENT;
@@ -583,7 +664,7 @@
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
@@ -591,15 +672,15 @@
if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
/* Finalise the mac operation */
- status = tfm_crypto_mac_finish(operation,
+ status = tfm_crypto_mac_finish(&handle,
ctx,
computed_mac,
sizeof(computed_mac),
&computed_mac_length);
+ *handle_out = handle;
if (status != PSA_SUCCESS) {
return status;
}
- /* A call to tfm_crypto_mac_finish() always releases the operation */
/* Check that the computed mac match the expected one */
if (computed_mac_length != mac_length) {
@@ -616,7 +697,9 @@
return PSA_ERROR_INVALID_SIGNATURE;
}
} else {
- (void)tfm_crypto_mac_release(operation, ctx);
+ if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
return PSA_ERROR_BAD_STATE;
}
@@ -631,19 +714,24 @@
psa_status_t status = PSA_SUCCESS;
struct tfm_mac_operation_s *ctx = NULL;
- if ((in_len != 0) || (out_len != 1)) {
+ if ((in_len != 1) || (out_len != 1)) {
return PSA_CONNECTION_REFUSED;
}
- if ((out_vec[0].len != sizeof(psa_mac_operation_t))) {
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
return PSA_CONNECTION_REFUSED;
}
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->handle;
+ uint32_t *handle_out = out_vec[0].base;
- psa_mac_operation_t *operation = out_vec[0].base;
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->handle;
/* Look up the corresponding operation context */
status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
- operation,
+ handle,
(void **)&ctx);
if (status != PSA_SUCCESS) {
return status;
@@ -653,7 +741,7 @@
/* Check if the HMAC internal context needs to be deallocated */
if (ctx->ctx.hmac.hash_operation.handle != TFM_CRYPTO_INVALID_HANDLE) {
/* Clear hash context */
- status = _psa_hash_abort(&(ctx->ctx.hmac.hash_operation));
+ status = _psa_hash_abort(&(ctx->ctx.hmac.hash_operation.handle));
if (status != PSA_SUCCESS) {
return status;
}
@@ -663,6 +751,10 @@
return PSA_ERROR_NOT_SUPPORTED;
}
- return tfm_crypto_mac_release(operation, ctx);
+ status = tfm_crypto_mac_release(&handle, ctx);
+ if (status == PSA_SUCCESS) {
+ *handle_out = handle;
+ }
+ return status;
}
/*!@}*/
diff --git a/secure_fw/services/crypto/manifest.yaml b/secure_fw/services/crypto/manifest.yaml
index a3cba08..7964ba4 100644
--- a/secure_fw/services/crypto/manifest.yaml
+++ b/secure_fw/services/crypto/manifest.yaml
@@ -13,6 +13,7 @@
"entry_point": "tfm_crypto_init",
"stack_size": "0x2000",
"heap_size": "0x0400",
+ "tfm_partition_ipc": true,
"secure_functions": [
{
"sfid": "TFM_CRYPTO_IMPORT_KEY_SFID",
@@ -263,6 +264,16 @@
"minor_policy": "strict"
},
],
+ "services" : [
+ {
+ "name": "TFM_CRYPTO_SID",
+ "sid": "0x00004000",
+ "signal": "TFM_CRYPTO_SIG",
+ "non_secure_clients": "true",
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ ],
"source_files": [
"crypto_alloc.c",
"crypto_cipher.c",
diff --git a/secure_fw/services/crypto/tfm_crypto_api.h b/secure_fw/services/crypto/tfm_crypto_api.h
index 5e6ffbd..36a0915 100644
--- a/secure_fw/services/crypto/tfm_crypto_api.h
+++ b/secure_fw/services/crypto/tfm_crypto_api.h
@@ -16,6 +16,15 @@
#include "tfm_api.h"
#include "tfm_crypto_defs.h"
#include "psa_crypto.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
#define UNIFORM_SIGNATURE_API(api_name) \
psa_status_t api_name(psa_invec[], size_t, psa_outvec[], size_t)
@@ -60,38 +69,35 @@
/**
* \brief Allocate an operation context in the backend
*
- * \param[in] type Type of the operation context to allocate
- * \param[out] oper Pointer to the frontend operation
- * \param[out ctx Double pointer to the corresponding context
+ * \param[in] type Type of the operation context to allocate
+ * \param[out] handle Pointer to the hold the allocated handle
+ * \param[out ctx Double pointer to the corresponding context
*
* \return Return values as described in \ref psa_status_t
*/
psa_status_t tfm_crypto_operation_alloc(enum tfm_crypto_operation_type type,
- void *oper,
+ uint32_t *handle,
void **ctx);
/**
* \brief Release an operation context in the backend
*
- * \param[in] type Type of the operation context to release
- * \param[in/out] oper Pointer to the frontend operation for the release
- * of the corresponding backend context
+ * \param[in] handle Pointer to the handle of the context to release
*
* \return Return values as described in \ref psa_status_t
*/
-psa_status_t tfm_crypto_operation_release(enum tfm_crypto_operation_type type,
- void *oper);
+psa_status_t tfm_crypto_operation_release(uint32_t *handle);
/**
* \brief Look up an operation context in the backend for the corresponding
* frontend operation
*
- * \param[in] type Type of the operation context to look up
- * \param[in] oper Pointer to the frontend operation
- * \param[out] ctx Double pointer to the corresponding context
+ * \param[in] type Type of the operation context to look up
+ * \param[in] handle Handle of the context to lookup
+ * \param[out] ctx Double pointer to the corresponding context
*
* \return Return values as described in \ref psa_status_t
*/
psa_status_t tfm_crypto_operation_lookup(enum tfm_crypto_operation_type type,
- const void *oper,
+ uint32_t handle,
void **ctx);
/**
* \brief Retrieve a key from the provided key slot according to the key
diff --git a/secure_fw/services/crypto/tfm_crypto_secure_api.c b/secure_fw/services/crypto/tfm_crypto_secure_api.c
index f04f470..4d6f726 100644
--- a/secure_fw/services/crypto/tfm_crypto_secure_api.c
+++ b/secure_fw/services/crypto/tfm_crypto_secure_api.c
@@ -9,24 +9,44 @@
#include "tfm_crypto_defs.h"
#include "psa_crypto.h"
-#define SFN_DISPATCH(sfn_name) \
- tfm_##sfn_name##_veneer( \
- in_vec, sizeof(in_vec)/sizeof(in_vec[0]), \
- out_vec, sizeof(out_vec)/sizeof(out_vec[0]))
+#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
-#define SFN_DISPATCH_NO_INVEC(sfn_name) \
- tfm_##sfn_name##_veneer( \
- NULL, 0, \
- out_vec, sizeof(out_vec)/sizeof(out_vec[0]))
+#ifdef TFM_PSA_API
+#include "psa_client.h"
-#define SFN_DISPATCH_NO_OUTVEC(sfn_name) \
+/* Macro to check for a valid PSA handle */
+/* FixMe: Here temporarily until it's added to the framework headers */
+#define PSA_IS_HANDLE_VALID(handle) ((handle) > (psa_handle_t)0)
+
+#define PSA_CONNECT(service) \
+ psa_handle_t handle; \
+ handle = psa_connect(service##_SID, service##_MIN_VER); \
+ if (!PSA_IS_HANDLE_VALID(handle)) { \
+ return PSA_ERROR_UNKNOWN_ERROR; \
+ } \
+
+#define PSA_CLOSE() psa_close(handle)
+
+#define API_DISPATCH(sfn_name, sfn_id) \
+ psa_call(handle, /*PSA_IPC_CALL,*/ \
+ in_vec, ARRAY_SIZE(in_vec), \
+ out_vec, ARRAY_SIZE(out_vec))
+
+#define API_DISPATCH_NO_OUTVEC(sfn_name, sfn_id) \
+ psa_call(handle, /*PSA_IPC_CALL,*/ \
+ in_vec, ARRAY_SIZE(in_vec), \
+ (psa_outvec *)NULL, 0)
+#else
+#define API_DISPATCH(sfn_name, sfn_id) \
tfm_##sfn_name##_veneer( \
- in_vec, sizeof(in_vec)/sizeof(in_vec[0]), \
+ in_vec, ARRAY_SIZE(in_vec), \
+ out_vec, ARRAY_SIZE(out_vec))
+
+#define API_DISPATCH_NO_OUTVEC(sfn_name, sfn_id) \
+ tfm_##sfn_name##_veneer( \
+ in_vec, ARRAY_SIZE(in_vec), \
NULL, 0)
-
-#define API_DISPATCH(sfn_name) SFN_DISPATCH(sfn_name)
-#define API_DISPATCH_NO_INVEC(sfn_name) SFN_DISPATCH_NO_INVEC(sfn_name)
-#define API_DISPATCH_NO_OUTVEC(sfn_name) SFN_DISPATCH_NO_OUTVEC(sfn_name)
+#endif /* TFM_PSA_API */
__attribute__(( section("SFN")))
psa_status_t psa_crypto_init(void)
@@ -44,13 +64,25 @@
size_t data_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_IMPORT_KEY_SFID,
+ .key = key,
+ .type = type,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &type, .len = sizeof(psa_key_type_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = data, .len = data_length}
};
- status = API_DISPATCH_NO_OUTVEC(tfm_crypto_import_key);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_import_key,
+ TFM_CRYPTO_IMPORT_KEY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -59,11 +91,23 @@
psa_status_t psa_destroy_key(psa_key_slot_t key)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_DESTROY_KEY_SFID,
+ .key = key,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
- status = API_DISPATCH_NO_OUTVEC(tfm_crypto_destroy_key);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_destroy_key,
+ TFM_CRYPTO_DESTROY_KEY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -74,15 +118,27 @@
size_t *bits)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_KEY_INFORMATION_SFID,
+ .key = key,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = type, .len = sizeof(psa_key_type_t)},
{.base = bits, .len = sizeof(size_t)}
};
- status = API_DISPATCH(tfm_crypto_get_key_information);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_get_key_information,
+ TFM_CRYPTO_GET_KEY_INFORMATION);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -94,17 +150,30 @@
size_t *data_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_EXPORT_KEY_SFID,
+ .key = key,
+ };
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = data, .len = data_size}
};
- status = API_DISPATCH(tfm_crypto_export_key);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_export_key,
+ TFM_CRYPTO_EXPORT_KEY);
*data_length = out_vec[0].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -114,6 +183,11 @@
size_t data_size,
size_t *data_length)
{
+ (void)key;
+ (void)data;
+ (void)data_size;
+ (void)data_length;
+
/* TODO: This API is not supported yet */
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -122,12 +196,31 @@
void psa_key_policy_init(psa_key_policy_t *policy)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_POLICY_INIT_SFID,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
psa_outvec out_vec[] = {
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+ handle = psa_connect(TFM_CRYPTO_SID,
+ TFM_CRYPTO_MIN_VER);
+ if (!PSA_IS_HANDLE_VALID(handle)) {
+ return;
+ }
+#endif
+
/* PSA API returns void so just ignore error value returned */
- status = API_DISPATCH_NO_INVEC(tfm_crypto_key_policy_init);
+ status = API_DISPATCH(tfm_crypto_key_policy_init,
+ TFM_CRYPTO_KEY_POLICY_INIT);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
}
__attribute__(( section("SFN")))
@@ -136,16 +229,33 @@
psa_algorithm_t alg)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_POLICY_SET_USAGE_SFID,
+ .usage = usage,
+ .alg = alg,
+ };
psa_invec in_vec[] = {
- {.base = &usage, .len = sizeof(psa_key_usage_t)},
- {.base = &alg, .len = sizeof(psa_algorithm_t)}
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
+#ifdef TFM_PSA_API
+ psa_handle_t handle;
+ handle = psa_connect(TFM_CRYPTO_SID,
+ TFM_CRYPTO_MIN_VER);
+ if (!PSA_IS_HANDLE_VALID(handle)) {
+ return;
+ }
+#endif
+
/* PSA API returns void so just ignore error value returned */
- status = API_DISPATCH(tfm_crypto_key_policy_set_usage);
+ status = API_DISPATCH(tfm_crypto_key_policy_set_usage,
+ TFM_CRYPTO_KEY_POLICY_SET_USAGE);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
}
__attribute__(( section("SFN")))
@@ -154,20 +264,33 @@
psa_status_t status;
psa_key_usage_t usage;
- /* Initialise to a sensible default to avoid returning an uninitialised
- * value in case the secure function fails.
- */
- usage = 0;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_POLICY_GET_USAGE_SFID,
+ };
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
psa_outvec out_vec[] = {
{.base = &usage, .len = sizeof(psa_key_usage_t)},
};
+ /* Initialise to a sensible default to avoid returning an uninitialised
+ * value in case the secure function fails.
+ */
+ usage = 0;
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
/* The PSA API does not return an error, so ignore any error from TF-M */
- status = API_DISPATCH(tfm_crypto_key_policy_get_usage);
+ status = API_DISPATCH(tfm_crypto_key_policy_get_usage,
+ TFM_CRYPTO_KEY_POLICY_GET_USAGE);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return usage;
}
@@ -178,20 +301,33 @@
psa_status_t status;
psa_algorithm_t alg;
- /* Initialise to a sensible default to avoid returning an uninitialised
- * value in case the secure function fails.
- */
- alg = 0;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_POLICY_GET_ALGORITHM_SFID,
+ };
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
psa_outvec out_vec[] = {
{.base = &alg, .len = sizeof(psa_algorithm_t)},
};
+ /* Initialise to a sensible default to avoid returning an uninitialised
+ * value in case the secure function fails.
+ */
+ alg = 0;
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
/* The PSA API does not return an error, so ignore any error from TF-M */
- status = API_DISPATCH(tfm_crypto_key_policy_get_algorithm);
+ status = API_DISPATCH(tfm_crypto_key_policy_get_algorithm,
+ TFM_CRYPTO_KEY_POLICY_GET_ALGORITHM);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return alg;
}
@@ -201,12 +337,25 @@
const psa_key_policy_t *policy)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_SET_KEY_POLICY_SFID,
+ .key = key,
+ };
+
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
- status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_policy);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_policy,
+ TFM_CRYPTO_SET_KEY_POLICY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -216,14 +365,27 @@
psa_key_policy_t *policy)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_KEY_POLICY_SFID,
+ .key = key,
+ };
+
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = policy, .len = sizeof(psa_key_policy_t)},
};
- status = API_DISPATCH(tfm_crypto_get_key_policy);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_get_key_policy,
+ TFM_CRYPTO_GET_KEY_POLICY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -233,12 +395,25 @@
psa_key_lifetime_t lifetime)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &lifetime, .len = sizeof(psa_key_lifetime_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_SET_KEY_LIFETIME_SFID,
+ .key = key,
+ .lifetime = lifetime,
};
- status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_lifetime);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_set_key_lifetime,
+ TFM_CRYPTO_SET_KEY_LIFETIME);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -248,14 +423,27 @@
psa_key_lifetime_t *lifetime)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_KEY_LIFETIME_SFID,
+ .key = key,
+ };
+
psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
};
psa_outvec out_vec[] = {
{.base = lifetime, .len = sizeof(psa_key_lifetime_t)},
};
- status = API_DISPATCH(tfm_crypto_get_key_lifetime);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_get_key_lifetime,
+ TFM_CRYPTO_GET_KEY_LIFETIME);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -266,14 +454,28 @@
size_t iv_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_SET_IV_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = iv, .len = iv_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
};
- status = API_DISPATCH(tfm_crypto_cipher_set_iv);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_set_iv,
+ TFM_CRYPTO_CIPHER_SET_IV);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -284,15 +486,29 @@
psa_algorithm_t alg)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &alg, .len = sizeof(psa_algorithm_t)},
- };
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SFID,
+ .key = key,
+ .alg = alg,
+ .handle = operation->handle,
};
- status = API_DISPATCH(tfm_crypto_cipher_encrypt_setup);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_encrypt_setup,
+ TFM_CRYPTO_CIPHER_ENCRYPT_SETUP);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -303,15 +519,29 @@
psa_algorithm_t alg)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &alg, .len = sizeof(psa_algorithm_t)},
- };
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SFID,
+ .key = key,
+ .alg = alg,
+ .handle = operation->handle,
};
- status = API_DISPATCH(tfm_crypto_cipher_decrypt_setup);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_decrypt_setup,
+ TFM_CRYPTO_CIPHER_DECRYPT_SETUP);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -325,18 +555,33 @@
size_t *output_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_UPDATE_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = input, .len = input_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
{.base = output, .len = output_size}
};
- status = API_DISPATCH(tfm_crypto_cipher_update);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_update,
+ TFM_CRYPTO_CIPHER_UPDATE);
*output_length = out_vec[1].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -344,11 +589,27 @@
psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
{
psa_status_t status;
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_ABORT_SFID,
+ .handle = operation->handle,
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_cipher_abort);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_abort,
+ TFM_CRYPTO_CIPHER_ABORT);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -360,15 +621,32 @@
size_t *output_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_FINISH_SFID,
+ .handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_cipher_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
{.base = output, .len = output_size},
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_cipher_finish);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_finish,
+ TFM_CRYPTO_CIPHER_FINISH);
*output_length = out_vec[1].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -377,14 +655,29 @@
psa_algorithm_t alg)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &alg, .len = sizeof(psa_algorithm_t)},
- };
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_SETUP_SFID,
+ .alg = alg,
+ .handle = operation->handle,
};
- status = API_DISPATCH(tfm_crypto_hash_setup);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_setup,
+ TFM_CRYPTO_HASH_SETUP);
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -395,14 +688,29 @@
size_t input_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_UPDATE_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = input, .len = input_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
};
- status = API_DISPATCH(tfm_crypto_hash_update);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_update,
+ TFM_CRYPTO_HASH_UPDATE);
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -414,15 +722,32 @@
size_t *hash_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_FINISH_SFID,
+ .handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
{.base = hash, .len = hash_size},
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_hash_finish);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_finish,
+ TFM_CRYPTO_HASH_FINISH);
*hash_length = out_vec[1].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -432,14 +757,28 @@
size_t hash_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_VERIFY_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = hash, .len = hash_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
};
- status = API_DISPATCH(tfm_crypto_hash_verify);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_verify,
+ TFM_CRYPTO_HASH_VERIFY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -448,11 +787,27 @@
psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
{
psa_status_t status;
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_ABORT_SFID,
+ .handle = operation->handle,
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_hash_abort);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_abort,
+ TFM_CRYPTO_HASH_ABORT);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -463,15 +818,29 @@
psa_algorithm_t alg)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &alg, .len = sizeof(psa_algorithm_t)}
- };
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_SIGN_SETUP_SFID,
+ .key = key,
+ .alg = alg,
+ .handle = operation->handle,
};
- status = API_DISPATCH(tfm_crypto_mac_sign_setup);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_sign_setup,
+ TFM_CRYPTO_MAC_SIGN_SETUP);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -482,15 +851,29 @@
psa_algorithm_t alg)
{
psa_status_t status;
- psa_invec in_vec[] = {
- {.base = &key, .len = sizeof(psa_key_slot_t)},
- {.base = &alg, .len = sizeof(psa_algorithm_t)}
- };
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_VERIFY_SETUP_SFID,
+ .key = key,
+ .alg = alg,
+ .handle = operation->handle,
};
- status = API_DISPATCH(tfm_crypto_mac_verify_setup);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_verify_setup,
+ TFM_CRYPTO_MAC_VERIFY_SETUP);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -501,14 +884,28 @@
size_t input_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_UPDATE_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = input, .len = input_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
};
- status = API_DISPATCH(tfm_crypto_mac_update);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_update,
+ TFM_CRYPTO_MAC_UPDATE);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -520,15 +917,32 @@
size_t *mac_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_SIGN_FINISH_SFID,
+ .handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
{.base = mac, .len = mac_size},
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_mac_sign_finish);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_sign_finish,
+ TFM_CRYPTO_MAC_SIGN_FINISH);
*mac_length = out_vec[1].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -538,14 +952,29 @@
size_t mac_length)
{
psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_VERIFY_FINISH_SFID,
+ .handle = operation->handle,
+ };
+
psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = mac, .len = mac_length},
};
psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
};
- status = API_DISPATCH(tfm_crypto_mac_verify_finish);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_verify_finish,
+ TFM_CRYPTO_MAC_VERIFY_FINISH);
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -554,11 +983,27 @@
psa_status_t psa_mac_abort(psa_mac_operation_t *operation)
{
psa_status_t status;
- psa_outvec out_vec[] = {
- {.base = operation, .len = sizeof(psa_mac_operation_t)},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_MAC_ABORT_SFID,
+ .handle = operation->handle,
};
- status = API_DISPATCH_NO_INVEC(tfm_crypto_mac_abort);
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_mac_abort,
+ TFM_CRYPTO_MAC_ABORT);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
return status;
}
@@ -577,17 +1022,18 @@
size_t *ciphertext_length)
{
psa_status_t status;
- struct tfm_crypto_aead_pack_input input_s = {
- .key = key,
- .alg = alg,
- .nonce = {0},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_ENCRYPT_SFID,
+ .key = key,
+ .alg = alg,
+ .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
};
+
size_t idx = 0;
psa_invec in_vec[] = {
- {.base = &input_s, .len = nonce_length + sizeof(psa_key_slot_t)
- + sizeof(psa_algorithm_t)},
- {.base = additional_data, .len = additional_data_length},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = plaintext, .len = plaintext_length},
+ {.base = additional_data, .len = additional_data_length},
};
psa_outvec out_vec[] = {
{.base = ciphertext, .len = ciphertext_size},
@@ -599,14 +1045,32 @@
if (nonce != NULL) {
for (idx = 0; idx < nonce_length; idx++) {
- input_s.nonce[idx] = nonce[idx];
+ iov.aead_in.nonce[idx] = nonce[idx];
}
}
- status = API_DISPATCH(tfm_crypto_aead_encrypt);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = sizeof(in_vec)/sizeof(in_vec[0]);
+ if (additional_data == NULL) {
+ in_len--;
+ }
+ status = psa_call(handle, in_vec, in_len,
+ out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+#else
+ status = API_DISPATCH(tfm_crypto_aead_encrypt,
+ TFM_CRYPTO_AEAD_ENCRYPT);
+#endif
*ciphertext_length = out_vec[0].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
@@ -624,17 +1088,18 @@
size_t *plaintext_length)
{
psa_status_t status;
- struct tfm_crypto_aead_pack_input input_s = {
- .key = key,
- .alg = alg,
- .nonce = {0},
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_DECRYPT_SFID,
+ .key = key,
+ .alg = alg,
+ .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
};
+
size_t idx = 0;
psa_invec in_vec[] = {
- {.base = &input_s, .len = nonce_length + sizeof(psa_key_slot_t)
- + sizeof(psa_algorithm_t)},
- {.base = additional_data, .len = additional_data_length},
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = ciphertext, .len = ciphertext_length},
+ {.base = additional_data, .len = additional_data_length},
};
psa_outvec out_vec[] = {
{.base = plaintext, .len = plaintext_size},
@@ -646,13 +1111,31 @@
if (nonce != NULL) {
for (idx = 0; idx < nonce_length; idx++) {
- input_s.nonce[idx] = nonce[idx];
+ iov.aead_in.nonce[idx] = nonce[idx];
}
}
- status = API_DISPATCH(tfm_crypto_aead_decrypt);
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = sizeof(in_vec)/sizeof(in_vec[0]);
+ if (additional_data == NULL) {
+ in_len--;
+ }
+ status = psa_call(handle, in_vec, in_len,
+ out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+#else
+ status = API_DISPATCH(tfm_crypto_aead_decrypt,
+ TFM_CRYPTO_AEAD_DECRYPT);
+#endif
*plaintext_length = out_vec[0].len;
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
return status;
}
diff --git a/secure_fw/services/crypto/tfm_crypto_signal.h b/secure_fw/services/crypto/tfm_crypto_signal.h
new file mode 100644
index 0000000..e632a8b
--- /dev/null
+++ b/secure_fw/services/crypto/tfm_crypto_signal.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_CRYPTO_SIGNAL_H__
+#define __TFM_CRYPTO_SIGNAL_H__
+
+#define TFM_IPC_SIG_RESERVED_POS (4U)
+
+#define TFM_CRYPTO_SIG_POS (TFM_IPC_SIG_RESERVED_POS+0U)
+
+/**
+ * \brief Definitions for the signals available in the Crypto partition
+ *
+ */
+#define TFM_CRYPTO_SIG (1U << TFM_CRYPTO_SIG_POS)
+
+#endif /* __TFM_CRYPTO_SIGNAL_H__ */
diff --git a/secure_fw/services/tfm_partition_list.inc b/secure_fw/services/tfm_partition_list.inc
index 06e2310..bd57977 100644
--- a/secure_fw/services/tfm_partition_list.inc
+++ b/secure_fw/services/tfm_partition_list.inc
@@ -26,6 +26,7 @@
/******** TFM_SP_CRYPTO ********/
PARTITION_DECLARE(TFM_SP_CRYPTO, 0
+ | SPM_PART_FLAG_IPC
, "PSA-ROT", 0x00000102, NORMAL);
PARTITION_ADD_INIT_FUNC(TFM_SP_CRYPTO, tfm_crypto_init);
diff --git a/secure_fw/services/tfm_service_list.inc b/secure_fw/services/tfm_service_list.inc
index c361ce8..a7c1e6a 100644
--- a/secure_fw/services/tfm_service_list.inc
+++ b/secure_fw/services/tfm_service_list.inc
@@ -58,6 +58,16 @@
},
+/******** TFM_SP_CRYPTO ********/
+{
+ "TFM_CRYPTO_SID",
+ TFM_SP_CRYPTO_ID,
+ TFM_CRYPTO_SIG,
+ 0x00004000,
+ true,
+ 1,
+ TFM_VERSION_POLICY_STRICT
+},
diff --git a/test/framework/non_secure_suites.c b/test/framework/non_secure_suites.c
index 1554650..bc8a731 100644
--- a/test/framework/non_secure_suites.c
+++ b/test/framework/non_secure_suites.c
@@ -41,6 +41,9 @@
{®ister_testsuite_ns_psa_ps_interface, 0, 0, 0},
+ /* Non-secure Crypto test cases */
+ {®ister_testsuite_ns_crypto_interface, 0, 0, 0},
+
#ifndef TFM_PSA_API
/*
* FixMe: skip below test cases temporary since target service is not
@@ -49,9 +52,6 @@
/* Non-secure Audit Logging test cases */
{®ister_testsuite_ns_audit_interface, 0, 0, 0},
- /* Non-secure Crypto test cases */
- {®ister_testsuite_ns_crypto_interface, 0, 0, 0},
-
/* Non-secure initial attestation service test cases */
{®ister_testsuite_ns_attestation_interface, 0, 0, 0},
diff --git a/test/framework/secure_suites.c b/test/framework/secure_suites.c
index b7426ec..80f7ee8 100644
--- a/test/framework/secure_suites.c
+++ b/test/framework/secure_suites.c
@@ -35,6 +35,9 @@
{®ister_testsuite_s_rollback_protection, 0, 0, 0},
#endif
+ /* Crypto test cases */
+ {®ister_testsuite_s_crypto_interface, 0, 0, 0},
+
#ifndef TFM_PSA_API
/*
* FixMe: since the following partitions haven't implement the IPC model,
@@ -43,9 +46,6 @@
/* Secure Audit Logging test cases */
{®ister_testsuite_s_audit_interface, 0, 0, 0},
- /* Crypto test cases */
- {®ister_testsuite_s_crypto_interface, 0, 0, 0},
-
/* Secure initial attestation service test cases */
{®ister_testsuite_s_attestation_interface, 0, 0, 0},
#endif