Crypto: Implement additional PSA Crypto APIs
This patch implements additional missing APIs available
in the PSA Crypto API headers.
Change-Id: I453f6829ed2c87a47546514becda599ecd1273a4
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/ConfigPsaApiTest.cmake b/ConfigPsaApiTest.cmake
index e66a821..a449aaf 100644
--- a/ConfigPsaApiTest.cmake
+++ b/ConfigPsaApiTest.cmake
@@ -49,7 +49,7 @@
#Service specific configuration for the PSA API Compliance test requirements
if(PSA_API_TEST_CRYPTO)
- set(CRYPTO_ENGINE_BUF_SIZE 3072)
+ set(CRYPTO_ENGINE_BUF_SIZE 20480)
endif()
include ("${CMAKE_CURRENT_LIST_DIR}/CommonConfig.cmake")
diff --git a/interface/include/tfm_crypto_defs.h b/interface/include/tfm_crypto_defs.h
index ec11613..436cc81 100644
--- a/interface/include/tfm_crypto_defs.h
+++ b/interface/include/tfm_crypto_defs.h
@@ -45,6 +45,7 @@
uint32_t op_handle; /*!< Frontend context handle associated to a
* multipart operation
*/
+ size_t capacity; /*!< Generator capacity */
struct tfm_crypto_aead_pack_input aead_in; /*!< FixMe: Temporarily used for
* AEAD until the API is
@@ -53,36 +54,55 @@
};
/**
- * \brief Define a numerical value for each SFID which can be used when
- * dispatching the requests to the service
+ * \brief Define a progressive numerical value for each SFID which can be used
+ * when dispatching the requests to the service
*/
-#define TFM_CRYPTO_ALLOCATE_KEY_SFID (0u)
-#define TFM_CRYPTO_IMPORT_KEY_SFID (1u)
-#define TFM_CRYPTO_DESTROY_KEY_SFID (2u)
-#define TFM_CRYPTO_GET_KEY_INFORMATION_SFID (3u)
-#define TFM_CRYPTO_EXPORT_KEY_SFID (4u)
-#define TFM_CRYPTO_SET_KEY_POLICY_SFID (5u)
-#define TFM_CRYPTO_GET_KEY_POLICY_SFID (6u)
-#define TFM_CRYPTO_GET_KEY_LIFETIME_SFID (7u)
-#define TFM_CRYPTO_CIPHER_SET_IV_SFID (8u)
-#define TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SFID (9u)
-#define TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SFID (10u)
-#define TFM_CRYPTO_CIPHER_UPDATE_SFID (11u)
-#define TFM_CRYPTO_CIPHER_ABORT_SFID (12u)
-#define TFM_CRYPTO_CIPHER_FINISH_SFID (13u)
-#define TFM_CRYPTO_HASH_SETUP_SFID (14u)
-#define TFM_CRYPTO_HASH_UPDATE_SFID (15u)
-#define TFM_CRYPTO_HASH_FINISH_SFID (16u)
-#define TFM_CRYPTO_HASH_VERIFY_SFID (17u)
-#define TFM_CRYPTO_HASH_ABORT_SFID (18u)
-#define TFM_CRYPTO_MAC_SIGN_SETUP_SFID (19u)
-#define TFM_CRYPTO_MAC_VERIFY_SETUP_SFID (20u)
-#define TFM_CRYPTO_MAC_UPDATE_SFID (21u)
-#define TFM_CRYPTO_MAC_SIGN_FINISH_SFID (22u)
-#define TFM_CRYPTO_MAC_VERIFY_FINISH_SFID (23u)
-#define TFM_CRYPTO_MAC_ABORT_SFID (24u)
-#define TFM_CRYPTO_AEAD_ENCRYPT_SFID (25u)
-#define TFM_CRYPTO_AEAD_DECRYPT_SFID (26u)
+enum {
+ TFM_CRYPTO_ALLOCATE_KEY_SFID = (0u),
+ TFM_CRYPTO_IMPORT_KEY_SFID,
+ TFM_CRYPTO_DESTROY_KEY_SFID,
+ TFM_CRYPTO_GET_KEY_INFORMATION_SFID,
+ TFM_CRYPTO_EXPORT_KEY_SFID,
+ TFM_CRYPTO_EXPORT_PUBLIC_KEY_SFID,
+ TFM_CRYPTO_COPY_KEY_SFID,
+ TFM_CRYPTO_SET_KEY_POLICY_SFID,
+ TFM_CRYPTO_GET_KEY_POLICY_SFID,
+ TFM_CRYPTO_GET_KEY_LIFETIME_SFID,
+ TFM_CRYPTO_CIPHER_GENERATE_IV_SFID,
+ TFM_CRYPTO_CIPHER_SET_IV_SFID,
+ TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SFID,
+ TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SFID,
+ TFM_CRYPTO_CIPHER_UPDATE_SFID,
+ TFM_CRYPTO_CIPHER_ABORT_SFID,
+ TFM_CRYPTO_CIPHER_FINISH_SFID,
+ TFM_CRYPTO_HASH_SETUP_SFID,
+ TFM_CRYPTO_HASH_UPDATE_SFID,
+ TFM_CRYPTO_HASH_FINISH_SFID,
+ TFM_CRYPTO_HASH_VERIFY_SFID,
+ TFM_CRYPTO_HASH_ABORT_SFID,
+ TFM_CRYPTO_HASH_CLONE_SFID,
+ TFM_CRYPTO_MAC_SIGN_SETUP_SFID,
+ TFM_CRYPTO_MAC_VERIFY_SETUP_SFID,
+ TFM_CRYPTO_MAC_UPDATE_SFID,
+ TFM_CRYPTO_MAC_SIGN_FINISH_SFID,
+ TFM_CRYPTO_MAC_VERIFY_FINISH_SFID,
+ TFM_CRYPTO_MAC_ABORT_SFID,
+ TFM_CRYPTO_AEAD_ENCRYPT_SFID,
+ TFM_CRYPTO_AEAD_DECRYPT_SFID,
+ TFM_CRYPTO_ASYMMETRIC_SIGN_SFID,
+ TFM_CRYPTO_ASYMMETRIC_VERIFY_SFID,
+ TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SFID,
+ TFM_CRYPTO_ASYMMETRIC_DECRYPT_SFID,
+ TFM_CRYPTO_GET_GENERATOR_CAPACITY_SFID,
+ TFM_CRYPTO_GENERATOR_READ_SFID,
+ TFM_CRYPTO_GENERATOR_IMPORT_KEY_SFID,
+ TFM_CRYPTO_GENERATOR_ABORT_SFID,
+ TFM_CRYPTO_KEY_DERIVATION_SFID,
+ TFM_CRYPTO_KEY_AGREEMENT_SFID,
+ TFM_CRYPTO_GENERATE_RANDOM_SFID,
+ TFM_CRYPTO_GENERATE_KEY_SFID,
+ TFM_CRYPTO_SFID_MAX,
+};
/**
* \brief Define the SID values and minor versions to match the ones defined in
@@ -92,10 +112,9 @@
#define TFM_CRYPTO_MIN_VER (0x0001)
/**
- * \brief Define the maximum value based on the previous list, and
- * an invalid value
+ * \brief Define an invalid value for an SFID
+ *
*/
-#define TFM_CRYPTO_SFID_MAX (TFM_CRYPTO_AEAD_DECRYPT_SFID + 1u)
#define TFM_CRYPTO_SFID_INVALID (~0x0u)
/**
diff --git a/interface/include/tfm_veneers.h b/interface/include/tfm_veneers.h
index b020acc..1bbaf76 100644
--- a/interface/include/tfm_veneers.h
+++ b/interface/include/tfm_veneers.h
@@ -36,9 +36,12 @@
psa_status_t tfm_tfm_crypto_destroy_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_get_key_information_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_export_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_export_public_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_copy_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_set_key_policy_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_get_key_policy_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_get_key_lifetime_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_cipher_generate_iv_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_set_iv_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_encrypt_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_decrypt_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
@@ -50,14 +53,27 @@
psa_status_t tfm_tfm_crypto_hash_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_hash_verify_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_hash_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_hash_clone_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_sign_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_verify_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_update_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_sign_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_verify_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
-psa_status_t tfm_tfm_crypto_aead_decrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_encrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_aead_decrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_asymmetric_sign_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_asymmetric_verify_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_asymmetric_encrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_asymmetric_decrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_get_generator_capacity_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_generator_read_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_generator_import_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_generator_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_key_derivation_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_key_agreement_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_generate_random_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_generate_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
/******** TFM_SP_PLATFORM ********/
psa_status_t tfm_platform_sp_system_reset_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
diff --git a/interface/src/tfm_crypto_api.c b/interface/src/tfm_crypto_api.c
index fe8a537..92d47d1 100644
--- a/interface/src/tfm_crypto_api.c
+++ b/interface/src/tfm_crypto_api.c
@@ -91,7 +91,7 @@
(void)id;
(void)handle;
- /* TODO: This API is not supported yet */
+ /* TODO: Persistent key APIs are not supported yet */
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -103,7 +103,7 @@
(void)id;
(void)handle;
- /* TODO: This API is not supported yet */
+ /* TODO: Persistent key APIs are not supported yet */
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -111,7 +111,7 @@
{
(void)handle;
- /* TODO: This API is not supported yet */
+ /* TODO: Persistent key APIs are not supported yet */
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -236,25 +236,62 @@
size_t data_size,
size_t *data_length)
{
- (void)handle;
- (void)data;
- (void)data_size;
- (void)data_length;
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SFID,
+ .key_handle = handle,
+ };
- /* TODO: This API is not supported yet */
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = data, .len = data_size}
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_export_public_key,
+ TFM_CRYPTO_EXPORT_PUBLIC_KEY);
+
+ *data_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
}
psa_status_t psa_copy_key(psa_key_handle_t source_handle,
psa_key_handle_t target_handle,
const psa_key_policy_t *constraint)
{
- (void)source_handle;
- (void)target_handle;
- (void)constraint;
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_COPY_KEY_SFID,
+ .key_handle = source_handle,
+ };
- /* TODO: This API is not supported yet */
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = &target_handle, .len = sizeof(psa_key_handle_t)},
+ {.base = constraint, .len = sizeof(psa_key_policy_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_copy_key,
+ TFM_CRYPTO_COPY_KEY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
}
void psa_key_policy_set_usage(psa_key_policy_t *policy,
@@ -365,13 +402,34 @@
size_t iv_size,
size_t *iv_length)
{
- (void) operation;
- (void) iv;
- (void) iv_size;
- (void) iv_length;
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_GENERATE_IV_SFID,
+ .op_handle = operation->handle,
+ };
- /* TODO: This API is not supported yet */
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = iv, .len = iv_size},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_generate_iv,
+ TFM_CRYPTO_CIPHER_GENERATE_IV);
+
+ *iv_length = out_vec[1].len;
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
}
psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
@@ -730,11 +788,30 @@
psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
psa_hash_operation_t *target_operation)
{
- (void)source_operation;
- (void)target_operation;
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_CLONE_SFID,
+ .op_handle = source_operation->handle,
+ };
- /* TODO: This API is not supported yet */
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = target_operation, .len = sizeof(psa_hash_operation_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_clone,
+ TFM_CRYPTO_HASH_CLONE);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
}
psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
@@ -947,6 +1024,11 @@
.aead_in = {.nonce = {0}, .nonce_length = nonce_length}
};
+ /* Sanitize the optional input */
+ if ((additional_data == NULL) && (additional_data_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
size_t idx = 0;
psa_invec in_vec[] = {
{.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -1012,6 +1094,11 @@
.aead_in = {.nonce = {0}, .nonce_length = nonce_length}
};
+ /* Sanitize the optional input */
+ if ((additional_data == NULL) && (additional_data_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
size_t idx = 0;
psa_invec in_vec[] = {
{.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -1056,3 +1143,491 @@
return status;
}
+
+psa_status_t psa_asymmetric_sign(psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_ASYMMETRIC_SIGN_SFID,
+ .key_handle = handle,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = hash, .len = hash_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = signature, .len = signature_size},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_asymmetric_sign,
+ TFM_CRYPTO_ASYMMETRIC_SIGN);
+
+ *signature_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_asymmetric_verify(psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ const uint8_t *signature,
+ size_t signature_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_ASYMMETRIC_VERIFY_SFID,
+ .key_handle = handle,
+ .alg = alg
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = hash, .len = hash_length},
+ {.base = signature, .len = signature_length}
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_asymmetric_verify,
+ TFM_CRYPTO_ASYMMETRIC_VERIFY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SFID,
+ .key_handle = handle,
+ .alg = alg
+ };
+
+ /* Sanitize the optional input */
+ if ((salt == NULL) && (salt_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = salt, .len = salt_length}
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = ARRAY_SIZE(in_vec);
+ if (salt == NULL) {
+ in_len--;
+ }
+ status = psa_call(ipc_handle, in_vec, in_len,
+ out_vec, ARRAY_SIZE(out_vec));
+#else
+ status = API_DISPATCH(tfm_crypto_asymmetric_encrypt,
+ TFM_CRYPTO_ASYMMETRIC_ENCRYPT);
+#endif
+
+ *output_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_asymmetric_decrypt(psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_ASYMMETRIC_DECRYPT_SFID,
+ .key_handle = handle,
+ .alg = alg
+ };
+
+ /* Sanitize the optional input */
+ if ((salt == NULL) && (salt_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = salt, .len = salt_length}
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = ARRAY_SIZE(in_vec);
+ if (salt == NULL) {
+ in_len--;
+ }
+ status = psa_call(ipc_handle, in_vec, in_len,
+ out_vec, ARRAY_SIZE(out_vec));
+#else
+ status = API_DISPATCH(tfm_crypto_asymmetric_decrypt,
+ TFM_CRYPTO_ASYMMETRIC_DECRYPT);
+#endif
+
+ *output_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
+ size_t *capacity)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_GENERATOR_CAPACITY_SFID,
+ .op_handle = generator->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = capacity, .len = sizeof(size_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_get_generator_capacity,
+ TFM_CRYPTO_GET_GENERATOR_CAPACITY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_generator_read(psa_crypto_generator_t *generator,
+ uint8_t *output,
+ size_t output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GENERATOR_READ_SFID,
+ .op_handle = generator->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_length},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_generator_read,
+ TFM_CRYPTO_GENERATOR_READ);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_generator_import_key(psa_key_handle_t handle,
+ psa_key_type_t type,
+ size_t bits,
+ psa_crypto_generator_t *generator)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GENERATOR_IMPORT_KEY_SFID,
+ .key_handle = handle,
+ .type = type,
+ .op_handle = generator->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = &bits, .len = sizeof(size_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_generator_import_key,
+ TFM_CRYPTO_GENERATOR_IMPORT_KEY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_generator_abort(psa_crypto_generator_t *generator)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GENERATOR_ABORT_SFID,
+ .op_handle = generator->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(generator->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_generator_abort,
+ TFM_CRYPTO_GENERATOR_ABORT);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_key_derivation(psa_crypto_generator_t *generator,
+ psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *salt,
+ size_t salt_length,
+ const uint8_t *label,
+ size_t label_length,
+ size_t capacity)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_SFID,
+ .key_handle = handle,
+ .alg = alg,
+ .op_handle = generator->handle,
+ .capacity = capacity,
+ };
+
+ /* Sanitize the optional input */
+ if ((salt == NULL) && (salt_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if ((label == NULL) && (label_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = salt, .len = salt_length},
+ {.base = label, .len = label_length},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(generator->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = ARRAY_SIZE(in_vec);
+ if (label == NULL) {
+ in_len--;
+ if (salt == NULL) {
+ in_len--;
+ }
+ }
+ status = psa_call(ipc_handle, in_vec, in_len,
+ out_vec, ARRAY_SIZE(out_vec));
+#else
+ status = API_DISPATCH(tfm_crypto_key_derivation,
+ TFM_CRYPTO_KEY_DERIVATION);
+#endif
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_key_agreement(psa_crypto_generator_t *generator,
+ psa_key_handle_t private_key,
+ const uint8_t *peer_key,
+ size_t peer_key_length,
+ psa_algorithm_t alg)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_AGREEMENT_SFID,
+ .key_handle = private_key,
+ .alg = alg,
+ .op_handle = generator->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = peer_key, .len = peer_key_length},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(generator->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_key_agreement,
+ TFM_CRYPTO_KEY_AGREEMENT);
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_generate_random(uint8_t *output,
+ size_t output_size)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GENERATE_RANDOM_SFID,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ if (output_size == 0) {
+ return PSA_SUCCESS;
+ }
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_generate_random,
+ TFM_CRYPTO_GENERATE_RANDOM);
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+psa_status_t psa_generate_key(psa_key_handle_t handle,
+ psa_key_type_t type,
+ size_t bits,
+ const void *extra,
+ size_t extra_size)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GENERATE_KEY_SFID,
+ .key_handle = handle,
+ .type = type,
+ };
+
+ /* Sanitize the optional input */
+ if ((extra == NULL) && (extra_size != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = &bits, .len = sizeof(size_t)},
+ {.base = extra, .len = extra_size},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = ARRAY_SIZE(in_vec);
+ if (extra == NULL) {
+ in_len--;
+ }
+
+ status = psa_call(ipc_handle, in_vec, in_len, NULL, 0);
+#else
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_generate_key,
+ TFM_CRYPTO_GENERATE_KEY);
+#endif
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
diff --git a/lib/t_cose/src/t_cose_psa_crypto_sign.c b/lib/t_cose/src/t_cose_psa_crypto_sign.c
index 19b29bd..85fb8f5 100644
--- a/lib/t_cose/src/t_cose_psa_crypto_sign.c
+++ b/lib/t_cose/src/t_cose_psa_crypto_sign.c
@@ -15,6 +15,15 @@
/* Avoid compiler warning due to unused argument */
#define ARG_UNUSED(arg) (void)(arg)
+/* FixMe: To be removed when the real Crypto API is used */
+psa_status_t psa_asymmetric_sign_stub(psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length);
+
enum t_cose_err_t
t_cose_crypto_pub_key_sign(int32_t cose_alg_id,
int32_t key_select,
@@ -44,13 +53,14 @@
return T_COSE_ERR_FAIL;
}
- psa_ret = psa_asymmetric_sign(key_handle_private,
- 0, /* FixMe: algorithm ID */
- hash_to_sign.ptr,
- hash_to_sign.len,
- signature_buffer.ptr, /* Sig buf */
- signature_buffer.len, /* Sig buf size */
- &(signature->len)); /* Sig length */
+ /* FixMe: To be removed when the real Crypto API is used */
+ psa_ret = psa_asymmetric_sign_stub(key_handle_private,
+ 0, /* FixMe: algorithm ID */
+ hash_to_sign.ptr,
+ hash_to_sign.len,
+ signature_buffer.ptr, /* Sig buf */
+ signature_buffer.len, /* Sig buf size */
+ &(signature->len)); /* Sig length */
if (psa_ret != PSA_SUCCESS) {
return T_COSE_ERR_FAIL;
diff --git a/secure_fw/ns_callable/tfm_veneers.c b/secure_fw/ns_callable/tfm_veneers.c
index 4621280..d1cb113 100644
--- a/secure_fw/ns_callable/tfm_veneers.c
+++ b/secure_fw/ns_callable/tfm_veneers.c
@@ -30,9 +30,12 @@
psa_status_t tfm_crypto_destroy_key(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_get_key_information(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_export_key(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_export_public_key(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_copy_key(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_set_key_policy(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_get_key_policy(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_get_key_lifetime(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_cipher_generate_iv(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_cipher_set_iv(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_cipher_encrypt_setup(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_cipher_decrypt_setup(psa_invec *, size_t, psa_outvec *, size_t);
@@ -44,14 +47,27 @@
psa_status_t tfm_crypto_hash_finish(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_hash_verify(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_hash_abort(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_hash_clone(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_mac_sign_setup(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_mac_verify_setup(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_mac_update(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_mac_sign_finish(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_mac_verify_finish(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_mac_abort(psa_invec *, size_t, psa_outvec *, size_t);
-psa_status_t tfm_crypto_aead_decrypt(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t tfm_crypto_aead_encrypt(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_aead_decrypt(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_asymmetric_sign(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_asymmetric_verify(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_asymmetric_encrypt(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_asymmetric_decrypt(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_get_generator_capacity(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_generator_read(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_generator_import_key(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_generator_abort(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_key_derivation(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_key_agreement(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_generate_random(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_generate_key(psa_invec *, size_t, psa_outvec *, size_t);
/******** TFM_SP_PLATFORM ********/
psa_status_t platform_sp_system_reset(psa_invec *, size_t, psa_outvec *, size_t);
@@ -122,9 +138,12 @@
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_destroy_key)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_get_key_information)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_export_key)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_export_public_key)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_copy_key)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_set_key_policy)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_get_key_policy)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_get_key_lifetime)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_cipher_generate_iv)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_cipher_set_iv)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_cipher_encrypt_setup)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_cipher_decrypt_setup)
@@ -136,14 +155,27 @@
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_hash_finish)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_hash_verify)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_hash_abort)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_hash_clone)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_sign_setup)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_verify_setup)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_update)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_sign_finish)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_verify_finish)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_abort)
-TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_aead_decrypt)
TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_aead_encrypt)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_aead_decrypt)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_asymmetric_sign)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_asymmetric_verify)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_asymmetric_encrypt)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_asymmetric_decrypt)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_get_generator_capacity)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_generator_read)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_generator_import_key)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_generator_abort)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_key_derivation)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_key_agreement)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_generate_random)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_generate_key)
/******** TFM_SP_PLATFORM ********/
TFM_VENEER_FUNCTION(TFM_SP_PLATFORM, platform_sp_system_reset)
diff --git a/secure_fw/services/crypto/CMakeLists.inc b/secure_fw/services/crypto/CMakeLists.inc
index f5910a8..fafbd30 100644
--- a/secure_fw/services/crypto/CMakeLists.inc
+++ b/secure_fw/services/crypto/CMakeLists.inc
@@ -48,6 +48,8 @@
"${CRYPTO_DIR}/crypto_mac.c"
"${CRYPTO_DIR}/crypto_key.c"
"${CRYPTO_DIR}/crypto_aead.c"
+ "${CRYPTO_DIR}/crypto_asymmetric.c"
+ "${CRYPTO_DIR}/crypto_generator.c"
"${CRYPTO_DIR}/tfm_crypto_secure_api.c"
)
diff --git a/secure_fw/services/crypto/crypto_alloc.c b/secure_fw/services/crypto/crypto_alloc.c
index ef0da17..db9c6af 100644
--- a/secure_fw/services/crypto/crypto_alloc.c
+++ b/secure_fw/services/crypto/crypto_alloc.c
@@ -29,9 +29,10 @@
uint32_t in_use; /*!< Indicates if the operation is in use */
enum tfm_crypto_operation_type type; /*!< Type of the operation */
union {
- psa_cipher_operation_t cipher; /*!< Cipher operation context */
- psa_mac_operation_t mac; /*!< MAC operation context */
- psa_hash_operation_t hash; /*!< Hash operation context */
+ psa_cipher_operation_t cipher; /*!< Cipher operation context */
+ psa_mac_operation_t mac; /*!< MAC operation context */
+ psa_hash_operation_t hash; /*!< Hash operation context */
+ psa_crypto_generator_t generator; /*!< Generator operation context */
} operation;
};
@@ -61,6 +62,9 @@
case TFM_CRYPTO_HASH_OPERATION:
mem_size = sizeof(psa_hash_operation_t);
break;
+ case TFM_CRYPTO_GENERATOR_OPERATION:
+ mem_size = sizeof(psa_crypto_generator_t);
+ break;
case TFM_CRYPTO_OPERATION_NONE:
default:
mem_size = 0;
@@ -117,6 +121,7 @@
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;
@@ -135,6 +140,7 @@
(handle < TFM_CRYPTO_CONC_OPER_NUM) &&
(operation[handle].in_use == TFM_CRYPTO_IN_USE) &&
(operation[handle].type == type) ) {
+
*ctx = (void *) &(operation[handle].operation);
return PSA_SUCCESS;
}
diff --git a/secure_fw/services/crypto/crypto_asymmetric.c b/secure_fw/services/crypto/crypto_asymmetric.c
new file mode 100644
index 0000000..3db7938
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_asymmetric.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.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.
+ */
+#include "tfm_mbedcrypto_include.h"
+
+#include "tfm_crypto_api.h"
+#include "tfm_crypto_defs.h"
+
+/*!
+ * \defgroup public_psa Public functions, PSA
+ *
+ */
+
+/*!@{*/
+psa_status_t tfm_crypto_asymmetric_sign(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ if ((in_len != 2) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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_handle_t handle = iov->key_handle;
+ psa_algorithm_t alg = iov->alg;
+ const uint8_t *hash = in_vec[1].base;
+ size_t hash_length = in_vec[1].len;
+ uint8_t *signature = out_vec[0].base;
+ size_t signature_size = out_vec[0].len;
+
+ return psa_asymmetric_sign(handle, alg, hash, hash_length,
+ signature, signature_size, &(out_vec[0].len));
+}
+
+psa_status_t tfm_crypto_asymmetric_verify(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ if ((in_len != 3) || (out_len != 0)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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_handle_t handle = iov->key_handle;
+ psa_algorithm_t alg = iov->alg;
+ const uint8_t *hash = in_vec[1].base;
+ size_t hash_length = in_vec[1].len;
+ const uint8_t *signature = in_vec[2].base;
+ size_t signature_length = in_vec[2].len;
+
+ return psa_asymmetric_verify(handle, alg, hash, hash_length,
+ signature, signature_length);
+}
+
+psa_status_t tfm_crypto_asymmetric_encrypt(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ if (!((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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_handle_t handle = iov->key_handle;
+ psa_algorithm_t alg = iov->alg;
+ const uint8_t *input = in_vec[1].base;
+ size_t input_length = in_vec[1].len;
+ const uint8_t *salt = NULL;
+ size_t salt_length = 0;
+ uint8_t *output = out_vec[0].base;
+ size_t output_size = out_vec[0].len;
+
+ if (in_len == 3) {
+ salt = in_vec[2].base;
+ salt_length = in_vec[2].len;
+ }
+
+ return psa_asymmetric_encrypt(handle, alg, input, input_length,
+ salt, salt_length,
+ output, output_size, &(out_vec[0].len));
+}
+
+psa_status_t tfm_crypto_asymmetric_decrypt(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ if (!((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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_handle_t handle = iov->key_handle;
+ psa_algorithm_t alg = iov->alg;
+ const uint8_t *input = in_vec[1].base;
+ size_t input_length = in_vec[1].len;
+ const uint8_t *salt = NULL;
+ size_t salt_length = 0;
+ uint8_t *output = out_vec[0].base;
+ size_t output_size = out_vec[0].len;
+
+ if (in_len == 3) {
+ salt = in_vec[2].base;
+ salt_length = in_vec[2].len;
+ }
+
+ return psa_asymmetric_decrypt(handle, alg, input, input_length,
+ salt, salt_length,
+ output, output_size, &(out_vec[0].len));
+}
+/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_cipher.c b/secure_fw/services/crypto/crypto_cipher.c
index e49b145..aa61025c 100644
--- a/secure_fw/services/crypto/crypto_cipher.c
+++ b/secure_fw/services/crypto/crypto_cipher.c
@@ -24,6 +24,52 @@
*/
/*!@{*/
+psa_status_t tfm_crypto_cipher_generate_iv(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ psa_status_t status = PSA_SUCCESS;
+ psa_cipher_operation_t *operation = NULL;
+
+ if ((in_len != 1) || (out_len != 2)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ unsigned char *iv = out_vec[1].base;
+ size_t iv_size = out_vec[1].len;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+ handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ *handle_out = handle;
+
+ status = psa_cipher_generate_iv(operation, iv, iv_size, &out_vec[1].len);
+ if (status != PSA_SUCCESS) {
+ /* Release the operation context, ignore if the operation fails. */
+ (void)tfm_crypto_operation_release(handle_out);
+ return status;
+ }
+
+ return status;
+}
+
psa_status_t tfm_crypto_cipher_set_iv(psa_invec in_vec[],
size_t in_len,
psa_outvec out_vec[],
@@ -67,11 +113,6 @@
return status;
}
-/**
- * TODO: psa_cipher_generate_iv(...)
- *
- */
-
psa_status_t tfm_crypto_cipher_encrypt_setup(psa_invec in_vec[],
size_t in_len,
psa_outvec out_vec[],
@@ -281,7 +322,8 @@
handle,
(void **)&operation);
if (status != PSA_SUCCESS) {
- return status;
+ /* Operation does not exist, so abort has no effect */
+ return PSA_SUCCESS;
}
status = psa_cipher_abort(operation);
diff --git a/secure_fw/services/crypto/crypto_generator.c b/secure_fw/services/crypto/crypto_generator.c
new file mode 100644
index 0000000..1cf138d
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_generator.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.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.
+ */
+#include "tfm_mbedcrypto_include.h"
+
+#include "tfm_crypto_api.h"
+#include "tfm_crypto_defs.h"
+
+/*!
+ * \defgroup public_psa Public functions, PSA
+ *
+ */
+
+/*!@{*/
+psa_status_t tfm_crypto_get_generator_capacity(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ psa_status_t status;
+ if ((in_len != 1) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(size_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+ uint32_t handle = iov->op_handle;
+ size_t *capacity = out_vec[0].base;
+ psa_crypto_generator_t *generator = NULL;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
+ handle,
+ (void **)&generator);
+ if (status != PSA_SUCCESS) {
+ *capacity = 0;
+ return status;
+ }
+
+ return psa_get_generator_capacity(generator, capacity);
+}
+
+psa_status_t tfm_crypto_generator_read(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ psa_status_t status;
+ if ((in_len != 1) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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;
+
+ uint32_t handle = iov->op_handle;
+ uint8_t *output = out_vec[0].base;
+ size_t output_length = out_vec[0].len;
+ psa_crypto_generator_t *generator = NULL;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
+ handle,
+ (void **)&generator);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ return psa_generator_read(generator, output, output_length);
+}
+
+psa_status_t tfm_crypto_generator_import_key(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ psa_status_t status;
+ if ((in_len != 2) || (out_len != 0)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (in_vec[1].len != sizeof(size_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+ uint32_t handle = iov->op_handle;
+ psa_key_handle_t key_handle = iov->key_handle;
+ psa_key_type_t type = iov->type;
+ size_t bits = *(size_t *)(in_vec[1].base);
+ psa_crypto_generator_t *generator = NULL;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
+ handle,
+ (void **)&generator);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ return psa_generator_import_key(key_handle, type, bits, generator);
+}
+
+psa_status_t tfm_crypto_generator_abort(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ psa_status_t status;
+ if ((in_len != 1) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ psa_crypto_generator_t *generator = NULL;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
+ handle,
+ (void **)&generator);
+ if (status != PSA_SUCCESS) {
+ /* Operation does not exist, so abort has no effect */
+ return PSA_SUCCESS;
+ }
+
+ *handle_out = handle;
+
+ status = psa_generator_abort(generator);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ status = tfm_crypto_operation_release(handle_out);
+
+ return status;
+}
+
+psa_status_t tfm_crypto_key_derivation(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ psa_status_t status;
+ if (!((in_len == 1) || (in_len == 2) || (in_len == 3)) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ psa_key_handle_t key_handle = iov->key_handle;
+ psa_algorithm_t alg = iov->alg;
+ const uint8_t *salt = NULL;
+ size_t salt_length = 0;
+ const uint8_t *label = NULL;
+ size_t label_length = 0;
+ size_t capacity = iov->capacity;
+ psa_crypto_generator_t *generator = NULL;
+
+ if (in_len > 1) {
+ salt = in_vec[2].base;
+ salt_length = in_vec[2].len;
+ }
+
+ if (in_len > 2) {
+ label = in_vec[3].base;
+ label_length = in_vec[3].len;
+ }
+
+ /* Allocate the generator context in the secure world */
+ status = tfm_crypto_operation_alloc(TFM_CRYPTO_GENERATOR_OPERATION,
+ &handle,
+ (void **)&generator);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ *handle_out = handle;
+
+ return psa_key_derivation(generator, key_handle, alg, salt, salt_length,
+ label, label_length, capacity);
+}
+
+psa_status_t tfm_crypto_key_agreement(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ psa_status_t status;
+ if ((in_len != 2) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ psa_key_handle_t private_key = iov->key_handle;
+ psa_algorithm_t alg = iov->alg;
+ const uint8_t *peer_key = in_vec[1].base;
+ size_t peer_key_length = in_vec[1].len;
+ psa_crypto_generator_t *generator = NULL;
+
+ /* Allocate the generator context in the secure world */
+ status = tfm_crypto_operation_alloc(TFM_CRYPTO_GENERATOR_OPERATION,
+ &handle,
+ (void **)&generator);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ *handle_out = handle;
+
+ return psa_key_agreement(generator, private_key,
+ peer_key, peer_key_length, alg);
+}
+
+psa_status_t tfm_crypto_generate_random(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ if ((in_len != 1) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+ uint8_t *output = out_vec[0].base;
+ size_t output_size = out_vec[0].len;
+
+ return psa_generate_random(output, output_size);
+}
+
+psa_status_t tfm_crypto_generate_key(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ if (!((in_len == 2) || (in_len == 3)) || (out_len != 0)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (in_vec[1].len != sizeof(size_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ psa_key_handle_t key_handle = iov->key_handle;
+ psa_key_type_t type = iov->type;
+ size_t bits = *((size_t *)(in_vec[1].base));
+ const void *extra = NULL;
+ size_t extra_size = 0;
+
+ if (in_len == 3) {
+ extra = in_vec[2].base;
+ extra_size = in_vec[2].len;
+ }
+
+ return psa_generate_key(key_handle, type, bits, extra, extra_size);
+}
+/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_hash.c b/secure_fw/services/crypto/crypto_hash.c
index 6468f0f..911227d 100644
--- a/secure_fw/services/crypto/crypto_hash.c
+++ b/secure_fw/services/crypto/crypto_hash.c
@@ -232,7 +232,8 @@
handle,
(void **)&operation);
if (status != PSA_SUCCESS) {
- return status;
+ /* Operation does not exist, so abort has no effect */
+ return PSA_SUCCESS;
}
status = psa_hash_abort(operation);
@@ -247,8 +248,50 @@
return status;
}
-/**
- * TODO: psa_hash_clone(...)
- *
- */
+psa_status_t tfm_crypto_hash_clone(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ psa_status_t status = PSA_SUCCESS;
+ psa_hash_operation_t *source_operation = NULL;
+ psa_hash_operation_t *target_operation = NULL;
+
+ if ((in_len != 1) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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 source_handle = iov->op_handle;
+ uint32_t *target_handle = out_vec[0].base;
+
+ /* Look up the corresponding source operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
+ source_handle,
+ (void **)&source_operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ /* Allocate the target operation context in the secure world */
+ status = tfm_crypto_operation_alloc(TFM_CRYPTO_HASH_OPERATION,
+ target_handle,
+ (void **)&target_operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ status = psa_hash_clone(source_operation, target_operation);
+ if (status != PSA_SUCCESS) {
+ /* Release the target operation context, ignore if it fails. */
+ (void)tfm_crypto_operation_release(target_handle);
+ return status;
+ }
+
+ return status;
+}
/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_init.c b/secure_fw/services/crypto/crypto_init.c
index 0144f02..a241f8a 100644
--- a/secure_fw/services/crypto/crypto_init.c
+++ b/secure_fw/services/crypto/crypto_init.c
@@ -26,33 +26,9 @@
* by the TF-M Crypto partition
*/
static const tfm_crypto_us_t sfid_func_table[TFM_CRYPTO_SFID_MAX] = {
- tfm_crypto_allocate_key,
- tfm_crypto_import_key,
- tfm_crypto_destroy_key,
- tfm_crypto_get_key_information,
- tfm_crypto_export_key,
- tfm_crypto_set_key_policy,
- tfm_crypto_get_key_policy,
- 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
+#define X(api_name) api_name,
+LIST_TFM_CRYPTO_UNIFORM_SIGNATURE_API
+#undef X
};
/**
diff --git a/secure_fw/services/crypto/crypto_key.c b/secure_fw/services/crypto/crypto_key.c
index 073203c..dc2d340 100644
--- a/secure_fw/services/crypto/crypto_key.c
+++ b/secure_fw/services/crypto/crypto_key.c
@@ -128,9 +128,8 @@
psa_key_handle_t key = iov->key_handle;
uint8_t *data = out_vec[0].base;
size_t data_size = out_vec[0].len;
- size_t *data_length = &(out_vec[0].len);
- return psa_export_key(key, data, data_size, data_length);
+ return psa_export_key(key, data, data_size, &(out_vec[0].len));
}
psa_status_t tfm_crypto_export_public_key(psa_invec in_vec[],
@@ -138,13 +137,45 @@
psa_outvec out_vec[],
size_t out_len)
{
- (void)in_vec;
- (void)in_len;
- (void)out_vec;
- (void)out_len;
+ if ((in_len != 1) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
- /* FIXME: This API is not supported yet */
- return PSA_ERROR_NOT_SUPPORTED;
+ 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_handle_t key = iov->key_handle;
+ uint8_t *data = out_vec[0].base;
+ size_t data_size = out_vec[0].len;
+
+ return psa_export_public_key(key, data, data_size, &(out_vec[0].len));
+}
+
+psa_status_t tfm_crypto_copy_key(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ (void)out_vec;
+
+ if ((in_len != 3) || (out_len != 0)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (in_vec[1].len != sizeof(psa_key_handle_t)) ||
+ (in_vec[2].len != sizeof(psa_key_policy_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+ psa_key_handle_t source_handle = iov->key_handle;
+ psa_key_handle_t target_handle = *((psa_key_handle_t *)in_vec[1].base);
+ const psa_key_policy_t *policy = in_vec[2].base;
+
+ return psa_copy_key(source_handle, target_handle, policy);
}
psa_status_t tfm_crypto_set_key_policy(psa_invec in_vec[],
diff --git a/secure_fw/services/crypto/crypto_mac.c b/secure_fw/services/crypto/crypto_mac.c
index c9218fe..625aacd 100644
--- a/secure_fw/services/crypto/crypto_mac.c
+++ b/secure_fw/services/crypto/crypto_mac.c
@@ -278,7 +278,8 @@
handle,
(void **)&operation);
if (status != PSA_SUCCESS) {
- return status;
+ /* Operation does not exist, so abort has no effect */
+ return PSA_SUCCESS;
}
status = psa_mac_abort(operation);
diff --git a/secure_fw/services/crypto/manifest.yaml b/secure_fw/services/crypto/manifest.yaml
index 688a919..67b679f 100644
--- a/secure_fw/services/crypto/manifest.yaml
+++ b/secure_fw/services/crypto/manifest.yaml
@@ -56,6 +56,22 @@
"minor_policy": "strict"
},
{
+ "sfid": "TFM_CRYPTO_EXPORT_PUBLIC_KEY_SFID",
+ "signal": "TFM_CRYPTO_EXPORT_PUBLIC_KEY",
+ "tfm_symbol": "tfm_crypto_export_public_key",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_COPY_KEY_SFID",
+ "signal": "TFM_CRYPTO_COPY_KEY",
+ "tfm_symbol": "tfm_crypto_copy_key",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
"sfid": "TFM_CRYPTO_SET_KEY_POLICY_SFID",
"signal": "TFM_CRYPTO_SET_KEY_POLICY",
"tfm_symbol": "tfm_crypto_set_key_policy",
@@ -80,6 +96,14 @@
"minor_policy": "strict"
},
{
+ "sfid": "TFM_CRYPTO_CIPHER_GENERATE_IV_SFID",
+ "signal": "TFM_CRYPTO_CIPHER_GENERATE_IV",
+ "tfm_symbol": "tfm_crypto_cipher_generate_iv",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
"sfid": "TFM_CRYPTO_CIPHER_SET_IV_SFID",
"signal": "TFM_CRYPTO_CIPHER_SET_IV",
"tfm_symbol": "tfm_crypto_cipher_set_iv",
@@ -168,6 +192,14 @@
"minor_policy": "strict"
},
{
+ "sfid": "TFM_CRYPTO_HASH_CLONE_SFID",
+ "signal": "TFM_CRYPTO_HASH_CLONE",
+ "tfm_symbol": "tfm_crypto_hash_clone",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
"sfid": "TFM_CRYPTO_MAC_SIGN_SETUP_SFID",
"signal": "TFM_CRYPTO_MAC_SIGN_SETUP",
"tfm_symbol": "tfm_crypto_mac_sign_setup",
@@ -216,6 +248,14 @@
"minor_policy": "strict"
},
{
+ "sfid": "TFM_CRYPTO_AEAD_ENCRYPT_SFID",
+ "signal": "TFM_CRYPTO_AEAD_ENCRYPT",
+ "tfm_symbol": "tfm_crypto_aead_encrypt",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
"sfid": "TFM_CRYPTO_AEAD_DECRYPT_SFID",
"signal": "TFM_CRYPTO_AEAD_DECRYPT",
"tfm_symbol": "tfm_crypto_aead_decrypt",
@@ -224,9 +264,97 @@
"minor_policy": "strict"
},
{
- "sfid": "TFM_CRYPTO_AEAD_ENCRYPT_SFID",
- "signal": "TFM_CRYPTO_AEAD_ENCRYPT",
- "tfm_symbol": "tfm_crypto_aead_encrypt",
+ "sfid": "TFM_CRYPTO_ASYMMETRIC_SIGN_SFID",
+ "signal": "TFM_CRYPTO_ASYMMETRIC_SIGN",
+ "tfm_symbol": "tfm_crypto_asymmetric_sign",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_ASYMMETRIC_VERIFY_SFID",
+ "signal": "TFM_CRYPTO_ASYMMETRIC_VERIFY",
+ "tfm_symbol": "tfm_crypto_asymmetric_verify",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SFID",
+ "signal": "TFM_CRYPTO_ASYMMETRIC_ENCRYPT",
+ "tfm_symbol": "tfm_crypto_asymmetric_encrypt",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_ASYMMETRIC_DECRYPT_SFID",
+ "signal": "TFM_CRYPTO_ASYMMETRIC_DECRYPT",
+ "tfm_symbol": "tfm_crypto_asymmetric_decrypt",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_GET_GENERATOR_CAPACITY_SFID",
+ "signal": "TFM_CRYPTO_GET_GENERATOR_CAPACITY",
+ "tfm_symbol": "tfm_crypto_get_generator_capacity",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_GENERATOR_READ_SFID",
+ "signal": "TFM_CRYPTO_GENERATOR_READ",
+ "tfm_symbol": "tfm_crypto_generator_read",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_GENERATOR_IMPORT_KEY_SFID",
+ "signal": "TFM_CRYPTO_GENERATOR_IMPORT_KEY",
+ "tfm_symbol": "tfm_crypto_generator_import_key",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_GENERATOR_ABORT_SFID",
+ "signal": "TFM_CRYPTO_GENERATOR_ABORT",
+ "tfm_symbol": "tfm_crypto_generator_abort",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_KEY_DERIVATION_SFID",
+ "signal": "TFM_CRYPTO_KEY_DERIVATION",
+ "tfm_symbol": "tfm_crypto_key_derivation",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_KEY_AGREEMENT_SFID",
+ "signal": "TFM_CRYPTO_KEY_AGREEMENT",
+ "tfm_symbol": "tfm_crypto_key_agreement",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_GENERATE_RANDOM_SFID",
+ "signal": "TFM_CRYPTO_GENERATE_RANDOM",
+ "tfm_symbol": "tfm_crypto_generate_random",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ },
+ {
+ "sfid": "TFM_CRYPTO_GENERATE_KEY_SFID",
+ "signal": "TFM_CRYPTO_GENERATE_KEY",
+ "tfm_symbol": "tfm_crypto_generate_key",
"non_secure_clients": true,
"minor_version": 1,
"minor_policy": "strict"
@@ -251,6 +379,8 @@
"crypto_engine.c",
"crypto_mac.c",
"crypto_aead.c",
+ "crypto_asymmetric.c",
+ "crypto_generator.c"
],
"tfm_linker_pattern": {
"library_list": [
diff --git a/secure_fw/services/crypto/tfm_crypto_api.h b/secure_fw/services/crypto/tfm_crypto_api.h
index 723e84a..e1d0f1d 100644
--- a/secure_fw/services/crypto/tfm_crypto_api.h
+++ b/secure_fw/services/crypto/tfm_crypto_api.h
@@ -40,6 +40,7 @@
TFM_CRYPTO_CIPHER_OPERATION = 1,
TFM_CRYPTO_MAC_OPERATION = 2,
TFM_CRYPTO_HASH_OPERATION = 3,
+ TFM_CRYPTO_GENERATOR_OPERATION = 4,
/* Used to force the enum size */
TFM_CRYPTO_OPERATION_TYPE_MAX = INT_MAX
@@ -94,36 +95,51 @@
void **ctx);
#define LIST_TFM_CRYPTO_UNIFORM_SIGNATURE_API \
- X(tfm_crypto_allocate_key); \
- X(tfm_crypto_import_key); \
- X(tfm_crypto_destroy_key); \
- X(tfm_crypto_get_key_information); \
- X(tfm_crypto_export_key); \
- X(tfm_crypto_export_public_key); \
- X(tfm_crypto_set_key_policy); \
- X(tfm_crypto_get_key_policy); \
- X(tfm_crypto_get_key_lifetime); \
- X(tfm_crypto_cipher_set_iv); \
- X(tfm_crypto_cipher_encrypt_setup); \
- X(tfm_crypto_cipher_decrypt_setup); \
- X(tfm_crypto_cipher_update); \
- X(tfm_crypto_cipher_finish); \
- X(tfm_crypto_cipher_abort); \
- X(tfm_crypto_hash_setup); \
- X(tfm_crypto_hash_update); \
- X(tfm_crypto_hash_finish); \
- X(tfm_crypto_hash_verify); \
- X(tfm_crypto_hash_abort); \
- X(tfm_crypto_mac_sign_setup); \
- X(tfm_crypto_mac_verify_setup); \
- X(tfm_crypto_mac_update); \
- X(tfm_crypto_mac_sign_finish); \
- X(tfm_crypto_mac_verify_finish); \
- X(tfm_crypto_mac_abort); \
- X(tfm_crypto_aead_encrypt); \
- X(tfm_crypto_aead_decrypt); \
+ X(tfm_crypto_allocate_key) \
+ X(tfm_crypto_import_key) \
+ X(tfm_crypto_destroy_key) \
+ X(tfm_crypto_get_key_information) \
+ X(tfm_crypto_export_key) \
+ X(tfm_crypto_export_public_key) \
+ X(tfm_crypto_copy_key) \
+ X(tfm_crypto_set_key_policy) \
+ X(tfm_crypto_get_key_policy) \
+ X(tfm_crypto_get_key_lifetime) \
+ X(tfm_crypto_cipher_generate_iv) \
+ X(tfm_crypto_cipher_set_iv) \
+ X(tfm_crypto_cipher_encrypt_setup) \
+ X(tfm_crypto_cipher_decrypt_setup) \
+ X(tfm_crypto_cipher_update) \
+ X(tfm_crypto_cipher_abort) \
+ X(tfm_crypto_cipher_finish) \
+ X(tfm_crypto_hash_setup) \
+ X(tfm_crypto_hash_update) \
+ X(tfm_crypto_hash_finish) \
+ X(tfm_crypto_hash_verify) \
+ X(tfm_crypto_hash_abort) \
+ X(tfm_crypto_hash_clone) \
+ X(tfm_crypto_mac_sign_setup) \
+ X(tfm_crypto_mac_verify_setup) \
+ X(tfm_crypto_mac_update) \
+ X(tfm_crypto_mac_sign_finish) \
+ X(tfm_crypto_mac_verify_finish) \
+ X(tfm_crypto_mac_abort) \
+ X(tfm_crypto_aead_encrypt) \
+ X(tfm_crypto_aead_decrypt) \
+ X(tfm_crypto_asymmetric_sign) \
+ X(tfm_crypto_asymmetric_verify) \
+ X(tfm_crypto_asymmetric_encrypt) \
+ X(tfm_crypto_asymmetric_decrypt) \
+ X(tfm_crypto_get_generator_capacity) \
+ X(tfm_crypto_generator_read) \
+ X(tfm_crypto_generator_import_key) \
+ X(tfm_crypto_generator_abort) \
+ X(tfm_crypto_key_derivation) \
+ X(tfm_crypto_key_agreement) \
+ X(tfm_crypto_generate_random) \
+ X(tfm_crypto_generate_key) \
-#define X(api_name) UNIFORM_SIGNATURE_API(api_name)
+#define X(api_name) UNIFORM_SIGNATURE_API(api_name);
LIST_TFM_CRYPTO_UNIFORM_SIGNATURE_API
#undef X
diff --git a/secure_fw/services/crypto/tfm_crypto_secure_api.c b/secure_fw/services/crypto/tfm_crypto_secure_api.c
index 857a473..8c3fd47 100644
--- a/secure_fw/services/crypto/tfm_crypto_secure_api.c
+++ b/secure_fw/services/crypto/tfm_crypto_secure_api.c
@@ -93,7 +93,7 @@
(void)id;
(void)handle;
- /* TODO: This API is not supported yet */
+ /* TODO: Persistent key APIs are not supported yet */
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -106,7 +106,7 @@
(void)id;
(void)handle;
- /* TODO: This API is not supported yet */
+ /* TODO: Persistent key APIs are not supported yet */
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -115,7 +115,7 @@
{
(void)handle;
- /* TODO: This API is not supported yet */
+ /* TODO: Persistent key APIs are not supported yet */
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -245,13 +245,33 @@
size_t data_size,
size_t *data_length)
{
- (void)handle;
- (void)data;
- (void)data_size;
- (void)data_length;
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SFID,
+ .key_handle = handle,
+ };
- /* TODO: This API is not supported yet */
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = data, .len = data_size}
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_export_public_key,
+ TFM_CRYPTO_EXPORT_PUBLIC_KEY);
+
+ *data_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
}
__attribute__((section("SFN")))
@@ -259,12 +279,29 @@
psa_key_handle_t target_handle,
const psa_key_policy_t *constraint)
{
- (void)source_handle;
- (void)target_handle;
- (void)constraint;
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_COPY_KEY_SFID,
+ .key_handle = source_handle,
+ };
- /* TODO: This API is not supported yet */
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = &target_handle, .len = sizeof(psa_key_handle_t)},
+ {.base = constraint, .len = sizeof(psa_key_policy_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_copy_key,
+ TFM_CRYPTO_COPY_KEY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
}
__attribute__((section("SFN")))
@@ -382,13 +419,34 @@
size_t iv_size,
size_t *iv_length)
{
- (void) operation;
- (void) iv;
- (void) iv_size;
- (void) iv_length;
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_CIPHER_GENERATE_IV_SFID,
+ .op_handle = operation->handle,
+ };
- /* TODO: This API is not supported yet */
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = iv, .len = iv_size},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_cipher_generate_iv,
+ TFM_CRYPTO_CIPHER_GENERATE_IV);
+
+ *iv_length = out_vec[1].len;
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
}
__attribute__((section("SFN")))
@@ -759,11 +817,30 @@
psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
psa_hash_operation_t *target_operation)
{
- (void)source_operation;
- (void)target_operation;
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_HASH_CLONE_SFID,
+ .op_handle = source_operation->handle,
+ };
- /* TODO: This API is not supported yet */
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = target_operation, .len = sizeof(psa_hash_operation_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_hash_clone,
+ TFM_CRYPTO_HASH_CLONE);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
}
__attribute__((section("SFN")))
@@ -983,6 +1060,11 @@
.aead_in = {.nonce = {0}, .nonce_length = nonce_length}
};
+ /* Sanitize the optional input */
+ if ((additional_data == NULL) && (additional_data_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
size_t idx = 0;
psa_invec in_vec[] = {
{.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -1049,6 +1131,11 @@
.aead_in = {.nonce = {0}, .nonce_length = nonce_length}
};
+ /* Sanitize the optional input */
+ if ((additional_data == NULL) && (additional_data_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
size_t idx = 0;
psa_invec in_vec[] = {
{.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -1093,3 +1180,503 @@
return status;
}
+
+__attribute__((section("SFN")))
+psa_status_t psa_asymmetric_sign(psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_ASYMMETRIC_SIGN_SFID,
+ .key_handle = handle,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = hash, .len = hash_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = signature, .len = signature_size},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_asymmetric_sign,
+ TFM_CRYPTO_ASYMMETRIC_SIGN);
+
+ *signature_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_asymmetric_verify(psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ const uint8_t *signature,
+ size_t signature_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_ASYMMETRIC_VERIFY_SFID,
+ .key_handle = handle,
+ .alg = alg
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = hash, .len = hash_length},
+ {.base = signature, .len = signature_length}
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_asymmetric_verify,
+ TFM_CRYPTO_ASYMMETRIC_VERIFY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SFID,
+ .key_handle = handle,
+ .alg = alg
+ };
+
+ /* Sanitize the optional input */
+ if ((salt == NULL) && (salt_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = salt, .len = salt_length}
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = ARRAY_SIZE(in_vec);
+ if (salt == NULL) {
+ in_len--;
+ }
+ status = psa_call(ipc_handle, in_vec, in_len,
+ out_vec, ARRAY_SIZE(out_vec));
+#else
+ status = API_DISPATCH(tfm_crypto_asymmetric_encrypt,
+ TFM_CRYPTO_ASYMMETRIC_ENCRYPT);
+#endif
+
+ *output_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_asymmetric_decrypt(psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_ASYMMETRIC_DECRYPT_SFID,
+ .key_handle = handle,
+ .alg = alg
+ };
+
+ /* Sanitize the optional input */
+ if ((salt == NULL) && (salt_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = salt, .len = salt_length}
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = ARRAY_SIZE(in_vec);
+ if (salt == NULL) {
+ in_len--;
+ }
+ status = psa_call(ipc_handle, in_vec, in_len,
+ out_vec, ARRAY_SIZE(out_vec));
+#else
+ status = API_DISPATCH(tfm_crypto_asymmetric_decrypt,
+ TFM_CRYPTO_ASYMMETRIC_DECRYPT);
+#endif
+
+ *output_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
+ size_t *capacity)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GET_GENERATOR_CAPACITY_SFID,
+ .op_handle = generator->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = capacity, .len = sizeof(size_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_get_generator_capacity,
+ TFM_CRYPTO_GET_GENERATOR_CAPACITY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_generator_read(psa_crypto_generator_t *generator,
+ uint8_t *output,
+ size_t output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GENERATOR_READ_SFID,
+ .op_handle = generator->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_length},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_generator_read,
+ TFM_CRYPTO_GENERATOR_READ);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_generator_import_key(psa_key_handle_t handle,
+ psa_key_type_t type,
+ size_t bits,
+ psa_crypto_generator_t *generator)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GENERATOR_IMPORT_KEY_SFID,
+ .key_handle = handle,
+ .type = type,
+ .op_handle = generator->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = &bits, .len = sizeof(size_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_generator_import_key,
+ TFM_CRYPTO_GENERATOR_IMPORT_KEY);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_generator_abort(psa_crypto_generator_t *generator)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GENERATOR_ABORT_SFID,
+ .op_handle = generator->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(generator->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_generator_abort,
+ TFM_CRYPTO_GENERATOR_ABORT);
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_key_derivation(psa_crypto_generator_t *generator,
+ psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *salt,
+ size_t salt_length,
+ const uint8_t *label,
+ size_t label_length,
+ size_t capacity)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_SFID,
+ .key_handle = handle,
+ .alg = alg,
+ .op_handle = generator->handle,
+ .capacity = capacity,
+ };
+
+ /* Sanitize the optional input */
+ if ((salt == NULL) && (salt_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if ((label == NULL) && (label_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = salt, .len = salt_length},
+ {.base = label, .len = label_length},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(generator->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = ARRAY_SIZE(in_vec);
+ if (label == NULL) {
+ in_len--;
+ if (salt == NULL) {
+ in_len--;
+ }
+ }
+ status = psa_call(ipc_handle, in_vec, in_len,
+ out_vec, ARRAY_SIZE(out_vec));
+#else
+ status = API_DISPATCH(tfm_crypto_key_derivation,
+ TFM_CRYPTO_KEY_DERIVATION);
+#endif
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_key_agreement(psa_crypto_generator_t *generator,
+ psa_key_handle_t private_key,
+ const uint8_t *peer_key,
+ size_t peer_key_length,
+ psa_algorithm_t alg)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_KEY_AGREEMENT_SFID,
+ .key_handle = private_key,
+ .alg = alg,
+ .op_handle = generator->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = peer_key, .len = peer_key_length},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(generator->handle), .len = sizeof(uint32_t)},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_key_agreement,
+ TFM_CRYPTO_KEY_AGREEMENT);
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_generate_random(uint8_t *output,
+ size_t output_size)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GENERATE_RANDOM_SFID,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ if (output_size == 0) {
+ return PSA_SUCCESS;
+ }
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+ status = API_DISPATCH(tfm_crypto_generate_random,
+ TFM_CRYPTO_GENERATE_RANDOM);
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_generate_key(psa_key_handle_t handle,
+ psa_key_type_t type,
+ size_t bits,
+ const void *extra,
+ size_t extra_size)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_GENERATE_KEY_SFID,
+ .key_handle = handle,
+ .type = type,
+ };
+
+ /* Sanitize the optional input */
+ if ((extra == NULL) && (extra_size != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = &bits, .len = sizeof(size_t)},
+ {.base = extra, .len = extra_size},
+ };
+
+#ifdef TFM_PSA_API
+ PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+ size_t in_len = ARRAY_SIZE(in_vec);
+ if (extra == NULL) {
+ in_len--;
+ }
+
+ status = psa_call(ipc_handle, in_vec, in_len, NULL, 0);
+#else
+ status = API_DISPATCH_NO_OUTVEC(tfm_crypto_generate_key,
+ TFM_CRYPTO_GENERATE_KEY);
+#endif
+
+#ifdef TFM_PSA_API
+ PSA_CLOSE();
+#endif
+
+ return status;
+}
diff --git a/secure_fw/services/initial_attestation/attestation_crypto_stub.c b/secure_fw/services/initial_attestation/attestation_crypto_stub.c
index 6848ff8..65e84cc 100644
--- a/secure_fw/services/initial_attestation/attestation_crypto_stub.c
+++ b/secure_fw/services/initial_attestation/attestation_crypto_stub.c
@@ -15,13 +15,13 @@
* simulates a real ECDSA P-256 over SHA256 signature generation. The size of
* the signature will be equal with a real one.
*/
-psa_status_t psa_asymmetric_sign(psa_key_handle_t handle,
- psa_algorithm_t alg,
- const uint8_t *hash,
- size_t hash_length,
- uint8_t *signature,
- size_t signature_size,
- size_t *signature_length)
+psa_status_t psa_asymmetric_sign_stub(psa_key_handle_t handle,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length)
{
if (2 * hash_length > signature_size) {
return PSA_ERROR_BUFFER_TOO_SMALL;