Crypto: Use uniform signatures
This patch amends the Crypto service to use the
Uniform Signatures interfaces supported by TF-M.
Change-Id: Ia1e269075bf94e1d60281da789dd43bb2be3f265
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/secure_fw/services/crypto/crypto_hash.c b/secure_fw/services/crypto/crypto_hash.c
index 7dc6582..cd546b9 100644
--- a/secure_fw/services/crypto/crypto_hash.c
+++ b/secure_fw/services/crypto/crypto_hash.c
@@ -5,16 +5,9 @@
*
*/
-#include <limits.h>
-
-#include "tfm_crypto_defs.h"
-#include "crypto_engine.h"
-#include "psa_crypto.h"
-
-#include "tfm_crypto_struct.h"
-
#include "tfm_crypto_api.h"
-#include "crypto_utils.h"
+#include "crypto_engine.h"
+#include "tfm_crypto_struct.h"
/**
* \brief Release all resources associated with a hash operation.
@@ -24,26 +17,19 @@
*
* \return Return values as described in \ref tfm_crypto_err_t
*/
-static enum tfm_crypto_err_t tfm_crypto_hash_release(
- psa_hash_operation_t *operation,
- struct tfm_hash_operation_s *ctx)
+static psa_status_t tfm_crypto_hash_release(psa_hash_operation_t *operation,
+ struct tfm_hash_operation_s *ctx)
{
- psa_status_t status;
- enum tfm_crypto_err_t err;
+ psa_status_t status = PSA_SUCCESS;
/* Release resources in the engine */
status = tfm_crypto_engine_hash_release(&(ctx->engine_ctx));
if (status != PSA_SUCCESS) {
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
/* Release the operation context */
- err = tfm_crypto_operation_release(TFM_CRYPTO_HASH_OPERATION, operation);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
- }
-
- return TFM_CRYPTO_ERR_PSA_SUCCESS;
+ return tfm_crypto_operation_release(TFM_CRYPTO_HASH_OPERATION, operation);
}
/*!
@@ -52,38 +38,43 @@
*/
/*!@{*/
-enum tfm_crypto_err_t tfm_crypto_hash_setup(psa_hash_operation_t *operation,
- psa_algorithm_t alg)
+psa_status_t tfm_crypto_hash_setup(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
{
psa_status_t status = PSA_SUCCESS;
- enum tfm_crypto_err_t err;
struct tfm_hash_operation_s *ctx = NULL;
struct hash_engine_info engine_info;
- /* Validate pointers */
- err = tfm_crypto_memory_check(operation,
- sizeof(psa_hash_operation_t),
- TFM_MEMORY_ACCESS_RW);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ if ((in_len != 1) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
}
+ if ((out_vec[0].len != sizeof(psa_hash_operation_t)) ||
+ (in_vec[0].len != sizeof(psa_algorithm_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ psa_hash_operation_t *operation = out_vec[0].base;
+ psa_algorithm_t alg = *((psa_algorithm_t *)in_vec[0].base);
+
if (PSA_ALG_IS_HASH(alg) == 0) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ return PSA_ERROR_INVALID_ARGUMENT;
}
/* Setup the engine for the requested algorithm */
status = tfm_crypto_engine_hash_setup(alg, &engine_info);
if (status != PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+ return PSA_ERROR_NOT_SUPPORTED;
}
/* Allocate the operation context in the secure world */
- err = tfm_crypto_operation_alloc(TFM_CRYPTO_HASH_OPERATION,
- operation,
- (void **)&ctx);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_operation_alloc(TFM_CRYPTO_HASH_OPERATION,
+ operation,
+ (void **)&ctx);
+ if (status != PSA_SUCCESS) {
+ return status;
}
/* Bind the algorithm to the hash context */
@@ -94,40 +85,38 @@
if (status != PSA_SUCCESS) {
/* Release the operation context, ignore if the operation fails. */
(void)tfm_crypto_hash_release(operation, ctx);
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
- return TFM_CRYPTO_ERR_PSA_SUCCESS;
+ return PSA_SUCCESS;
}
-enum tfm_crypto_err_t tfm_crypto_hash_update(psa_hash_operation_t *operation,
- const uint8_t *input,
- size_t input_length)
+psa_status_t tfm_crypto_hash_update(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
{
psa_status_t status = PSA_SUCCESS;
- enum tfm_crypto_err_t err;
struct tfm_hash_operation_s *ctx = NULL;
- /* Validate pointers */
- err = tfm_crypto_memory_check(operation,
- sizeof(psa_hash_operation_t),
- TFM_MEMORY_ACCESS_RW);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
- }
- err = tfm_crypto_memory_check((void *)input,
- input_length,
- TFM_MEMORY_ACCESS_RO);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ if ((in_len != 1) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
}
+ if ((out_vec[0].len != sizeof(psa_hash_operation_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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;
+
/* Look up the corresponding operation context */
- err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
- operation,
- (void **)&ctx);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
+ operation,
+ (void **)&ctx);
+ if (status != PSA_SUCCESS) {
+ return status;
}
/* Process the input chunk with the engine */
@@ -136,92 +125,114 @@
input_length);
if (status != PSA_SUCCESS) {
(void)tfm_crypto_hash_release(operation, ctx);
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
- return TFM_CRYPTO_ERR_PSA_SUCCESS;
+ return PSA_SUCCESS;
}
-enum tfm_crypto_err_t tfm_crypto_hash_finish(psa_hash_operation_t *operation,
- uint8_t *hash,
- size_t hash_size,
- size_t *hash_length)
+psa_status_t tfm_crypto_hash_finish(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
{
psa_status_t status = PSA_SUCCESS;
- enum tfm_crypto_err_t err;
struct tfm_hash_operation_s *ctx = NULL;
- /* Validate pointers */
- err = tfm_crypto_memory_check(operation,
- sizeof(psa_hash_operation_t),
- TFM_MEMORY_ACCESS_RW);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
- }
- err = tfm_crypto_memory_check(hash,
- hash_size,
- TFM_MEMORY_ACCESS_RW);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
- }
- err = tfm_crypto_memory_check(hash_length,
- sizeof(size_t),
- TFM_MEMORY_ACCESS_RW);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ if ((in_len != 0) || (out_len != 2)) {
+ return PSA_CONNECTION_REFUSED;
}
+ if ((out_vec[0].len != sizeof(psa_hash_operation_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ psa_hash_operation_t *operation = out_vec[0].base;
+ uint8_t *hash = out_vec[1].base;
+ size_t hash_size = out_vec[1].len;
+
+ /* Initialise hash_length to zero */
+ out_vec[1].len = 0;
+
/* Look up the corresponding operation context */
- err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
- operation,
- (void **)&ctx);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
+ operation,
+ (void **)&ctx);
+ if (status != PSA_SUCCESS) {
+ return status;
}
if (hash_size < PSA_HASH_SIZE(ctx->alg)) {
(void)tfm_crypto_hash_release(operation, ctx);
- return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
+ 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);
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
/* Set the length of the hash that has been produced */
- *hash_length = PSA_HASH_SIZE(ctx->alg);
+ out_vec[1].len = PSA_HASH_SIZE(ctx->alg);
return tfm_crypto_hash_release(operation, ctx);
}
-enum tfm_crypto_err_t tfm_crypto_hash_verify(psa_hash_operation_t *operation,
- const uint8_t *hash,
- size_t hash_length)
+static psa_status_t _psa_hash_finish(psa_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length)
{
- enum tfm_crypto_err_t err;
+ psa_status_t status;
+ psa_outvec out_vec[] = {
+ {.base = operation, .len = sizeof(psa_hash_operation_t)},
+ {.base = hash, .len = hash_size},
+ };
+
+ status = tfm_crypto_hash_finish(NULL, 0,
+ out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+ *hash_length = out_vec[1].len;
+
+ return status;
+}
+
+psa_status_t tfm_crypto_hash_verify(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
+{
+ psa_status_t status = PSA_SUCCESS;
uint8_t digest[PSA_HASH_MAX_SIZE] = {0};
size_t digest_length;
uint32_t idx, comp_mismatch = 0;
- /* Validate pointers */
- err = tfm_crypto_memory_check(operation,
- sizeof(psa_hash_operation_t),
- TFM_MEMORY_ACCESS_RW);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ if ((in_len != 1) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
}
- /* Finalise the hash operation */
- err = tfm_crypto_hash_finish(operation,
- digest,
- PSA_HASH_MAX_SIZE,
- &digest_length);
+ if ((out_vec[0].len != sizeof(psa_hash_operation_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ 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;
+
+ /* Finalise the hash operation */
+ status = _psa_hash_finish(operation,
+ digest,
+ PSA_HASH_MAX_SIZE,
+ &digest_length);
+
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ /* Check that the computed hash has the same legnth as the provided one */
+ if (hash_length != digest_length) {
+ return PSA_ERROR_INVALID_SIGNATURE;
}
/* Verify that the computed hash matches the provided one */
@@ -232,31 +243,36 @@
}
if (comp_mismatch == 1) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE;
+ return PSA_ERROR_INVALID_SIGNATURE;
}
- return TFM_CRYPTO_ERR_PSA_SUCCESS;
+ return PSA_SUCCESS;
}
-enum tfm_crypto_err_t tfm_crypto_hash_abort(psa_hash_operation_t *operation)
+psa_status_t tfm_crypto_hash_abort(psa_invec in_vec[],
+ size_t in_len,
+ psa_outvec out_vec[],
+ size_t out_len)
{
- enum tfm_crypto_err_t err;
+ psa_status_t status = PSA_SUCCESS;
struct tfm_hash_operation_s *ctx = NULL;
- /* Validate pointers */
- err = tfm_crypto_memory_check(operation,
- sizeof(psa_hash_operation_t),
- TFM_MEMORY_ACCESS_RW);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ if ((in_len != 0) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
}
+ if ((out_vec[0].len != sizeof(psa_hash_operation_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ psa_hash_operation_t *operation = out_vec[0].base;
+
/* Look up the corresponding operation context */
- err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
- operation,
- (void **)&ctx);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
+ operation,
+ (void **)&ctx);
+ if (status != PSA_SUCCESS) {
+ return status;
}
return tfm_crypto_hash_release(operation, ctx);