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_cipher.c b/secure_fw/services/crypto/crypto_cipher.c
index 9f6ae9d..05d8285 100644
--- a/secure_fw/services/crypto/crypto_cipher.c
+++ b/secure_fw/services/crypto/crypto_cipher.c
@@ -5,18 +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"
/**
* \def CRYPTO_CIPHER_MAX_KEY_LENGTH
@@ -28,6 +19,23 @@
#define CRYPTO_CIPHER_MAX_KEY_LENGTH (32)
#endif
+static psa_status_t _psa_get_key_information(psa_key_slot_t key,
+ psa_key_type_t *type,
+ size_t *bits)
+{
+ psa_invec in_vec[] = {
+ {.base = &key, .len = sizeof(psa_key_slot_t)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = type, .len = sizeof(psa_key_type_t)},
+ {.base = bits, .len = sizeof(size_t)}
+ };
+
+ return tfm_crypto_get_key_information(
+ in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
+ out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
+}
+
/**
* \brief Release all resources associated with a cipher operation.
*
@@ -36,69 +44,53 @@
*
* \return Return values as described in \ref tfm_crypto_err_t
*/
-static enum tfm_crypto_err_t tfm_crypto_cipher_release(
+static psa_status_t tfm_crypto_cipher_release(
psa_cipher_operation_t *operation,
struct tfm_cipher_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_cipher_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_CIPHER_OPERATION, operation);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
- }
-
- return TFM_CRYPTO_ERR_PSA_SUCCESS;
+ return tfm_crypto_operation_release(TFM_CRYPTO_CIPHER_OPERATION, operation);
}
-static enum tfm_crypto_err_t tfm_crypto_cipher_setup(
- psa_cipher_operation_t *operation,
- psa_key_slot_t key,
- psa_algorithm_t alg,
- enum engine_cipher_mode_t c_mode)
+static psa_status_t tfm_crypto_cipher_setup(psa_cipher_operation_t *operation,
+ psa_key_slot_t key,
+ psa_algorithm_t alg,
+ enum engine_cipher_mode_t c_mode)
{
uint8_t key_data[CRYPTO_CIPHER_MAX_KEY_LENGTH];
size_t key_size;
psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
psa_status_t status = PSA_SUCCESS;
- enum tfm_crypto_err_t err;
struct tfm_cipher_operation_s *ctx = NULL;
struct cipher_engine_info engine_info;
psa_key_usage_t usage;
- /* Validate pointers */
- err = tfm_crypto_memory_check(operation,
- sizeof(psa_cipher_operation_t),
- TFM_MEMORY_ACCESS_RW);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
- }
-
if (!PSA_ALG_IS_CIPHER(alg)) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ return PSA_ERROR_INVALID_ARGUMENT;
}
/* Access the key module to retrieve key related information */
- err = tfm_crypto_get_key_information(key, &key_type, &key_size);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = _psa_get_key_information(key, &key_type, &key_size);
+ if (status != PSA_SUCCESS) {
+ return status;
}
/* Check if it's a raw data key type */
if (key_type == PSA_KEY_TYPE_RAW_DATA) {
- return TFM_CRYPTO_ERR_PSA_ERROR_NOT_PERMITTED;
+ return PSA_ERROR_NOT_PERMITTED;
}
/* Check compatibility between key and algorithm */
if ((key_type == PSA_KEY_TYPE_ARC4) && (alg != PSA_ALG_ARC4)) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ return PSA_ERROR_INVALID_ARGUMENT;
}
/* Setup the algorithm on the crypto engine */
@@ -108,15 +100,15 @@
c_mode,
&engine_info);
if (status != PSA_SUCCESS) {
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
/* Allocate the operation context in the secure world */
- err = tfm_crypto_operation_alloc(TFM_CRYPTO_CIPHER_OPERATION,
- operation,
- (void **)&ctx);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_operation_alloc(TFM_CRYPTO_CIPHER_OPERATION,
+ operation,
+ (void **)&ctx);
+ if (status != PSA_SUCCESS) {
+ return status;
}
/* Set the proper cipher mode (encrypt/decrypt) in the operation context */
@@ -130,7 +122,7 @@
if (status != PSA_SUCCESS) {
/* Release the operation context, ignore if this operation fails. */
(void)tfm_crypto_cipher_release(operation, ctx);
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
/* Set the key usage based on the cipher mode */
@@ -138,16 +130,16 @@
: PSA_KEY_USAGE_ENCRYPT;
/* Access the crypto service key module to retrieve key data */
- err = tfm_crypto_get_key(key,
- usage,
- alg,
- key_data,
- CRYPTO_CIPHER_MAX_KEY_LENGTH,
- &key_size);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+ status = tfm_crypto_get_key(key,
+ usage,
+ alg,
+ key_data,
+ CRYPTO_CIPHER_MAX_KEY_LENGTH,
+ &key_size);
+ if (status != PSA_SUCCESS) {
/* Release the operation context, ignore if this operation fails. */
(void)tfm_crypto_cipher_release(operation, ctx);
- return err;
+ return status;
}
/* Set the key on the engine */
@@ -158,7 +150,7 @@
if (status != PSA_SUCCESS) {
/* Release the operation context, ignore if this operation fails. */
(void)tfm_crypto_cipher_release(operation, ctx);
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
/* Bind the key to the cipher operation */
@@ -173,7 +165,7 @@
if (status != PSA_SUCCESS) {
/* Release the operation context, ignore if this operation fails. */
(void)tfm_crypto_cipher_release(operation, ctx);
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
}
@@ -181,7 +173,7 @@
ctx->iv_required = 1;
ctx->block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type);
- return TFM_CRYPTO_ERR_PSA_SUCCESS;
+ return PSA_SUCCESS;
}
/*!
@@ -190,43 +182,42 @@
*/
/*!@{*/
-enum tfm_crypto_err_t tfm_crypto_cipher_set_iv(
- psa_cipher_operation_t *operation,
- const unsigned char *iv,
- size_t iv_length)
+psa_status_t tfm_crypto_cipher_set_iv(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_cipher_operation_s *ctx = NULL;
- /* Validate pointers */
- err = tfm_crypto_memory_check(operation,
- sizeof(psa_cipher_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 *)iv, iv_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_cipher_operation_t)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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;
+
/* Look up the corresponding operation context */
- err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
- operation,
- (void **)&ctx);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+ operation,
+ (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);
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ return PSA_ERROR_INVALID_ARGUMENT;
}
if ((ctx->iv_set == 1) || (ctx->iv_required == 0)) {
(void)tfm_crypto_cipher_release(operation, ctx);
- return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
+ return PSA_ERROR_BAD_STATE;
}
/* Set the IV on the crypto engine */
@@ -235,84 +226,112 @@
iv_length);
if (status != PSA_SUCCESS) {
(void)tfm_crypto_cipher_release(operation, ctx);
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
ctx->iv_set = 1;
ctx->iv_size = iv_length;
- return TFM_CRYPTO_ERR_PSA_SUCCESS;
+ return PSA_SUCCESS;
}
-enum tfm_crypto_err_t tfm_crypto_cipher_encrypt_setup(
- psa_cipher_operation_t *operation,
- psa_key_slot_t key,
- psa_algorithm_t alg)
+static psa_status_t _psa_cipher_set_iv(psa_cipher_operation_t *operation,
+ const unsigned char *iv,
+ size_t iv_length)
{
+ psa_status_t status;
+ psa_invec in_vec[] = {
+ {.base = iv, .len = iv_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = operation, .len = sizeof(psa_cipher_operation_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)) {
+ 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))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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);
}
-enum tfm_crypto_err_t tfm_crypto_cipher_decrypt_setup(
- psa_cipher_operation_t *operation,
- psa_key_slot_t key,
- psa_algorithm_t alg)
+psa_status_t tfm_crypto_cipher_decrypt_setup(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 ((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))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ 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);
}
-enum tfm_crypto_err_t tfm_crypto_cipher_update(
- psa_cipher_operation_t *operation,
- const uint8_t *input,
- size_t input_length,
- unsigned char *output,
- size_t output_size,
- size_t *output_length)
+psa_status_t tfm_crypto_cipher_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_cipher_operation_s *ctx = NULL;
- /* Validate pointers */
- err = tfm_crypto_memory_check(operation,
- sizeof(psa_cipher_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;
- }
- err = tfm_crypto_memory_check(output,
- output_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(output_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 != 1) || (out_len != 2)) {
+ return PSA_CONNECTION_REFUSED;
}
- /* Initialise the output length to zero */
- *output_length = 0;
+ if ((out_vec[0].len != sizeof(psa_cipher_operation_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;
+ unsigned char *output = out_vec[1].base;
+ size_t output_size = out_vec[1].len;
+
+ /* Initialise the output_length to zero */
+ out_vec[1].len = 0;
/* Look up the corresponding operation context */
- err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
- operation,
- (void **)&ctx);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+ operation,
+ (void **)&ctx);
+ if (status != PSA_SUCCESS) {
+ return status;
}
/* If the IV is required and it's not been set yet */
@@ -320,17 +339,17 @@
if (ctx->cipher_mode != ENGINE_CIPHER_MODE_DECRYPT) {
(void)tfm_crypto_cipher_release(operation, ctx);
- return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
+ return PSA_ERROR_BAD_STATE;
}
/* This call is used to set the IV on the object */
- return tfm_crypto_cipher_set_iv(operation, input, input_length);
+ return _psa_cipher_set_iv(operation, 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);
- return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
+ return PSA_ERROR_BAD_STATE;
}
/* FIXME: The implementation currently expects to work only on blocks
@@ -338,7 +357,7 @@
*/
if (input_length > output_size) {
(void)tfm_crypto_cipher_release(operation, ctx);
- return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
+ return PSA_ERROR_BUFFER_TOO_SMALL;
}
/* Update the cipher output with the input chunk on the engine */
@@ -346,51 +365,44 @@
input,
input_length,
output,
- (uint32_t *)output_length);
+ (uint32_t *)&(out_vec[1].len));
if (status != PSA_SUCCESS) {
(void)tfm_crypto_cipher_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_cipher_finish(
- psa_cipher_operation_t *operation,
- uint8_t *output,
- size_t output_size,
- size_t *output_length)
+psa_status_t tfm_crypto_cipher_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_cipher_operation_s *ctx = NULL;
- /* Validate pointers */
- err = tfm_crypto_memory_check(operation,
- sizeof(psa_cipher_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(output,
- output_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(output_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_cipher_operation_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ psa_cipher_operation_t *operation = out_vec[0].base;
+ unsigned char *output = out_vec[1].base;
+ size_t output_size = out_vec[1].len;
+
+ /* Initialise the output_length to zero */
+ out_vec[1].len = 0;
+
/* Look up the corresponding operation context */
- err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
- operation,
- (void **)&ctx);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+ operation,
+ (void **)&ctx);
+ if (status != PSA_SUCCESS) {
+ return status;
}
/* Check that the output buffer is large enough for up to one block size of
@@ -398,41 +410,46 @@
*/
if (output_size < ctx->block_size) {
(void)tfm_crypto_cipher_release(operation, ctx);
- return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
+ return PSA_ERROR_BUFFER_TOO_SMALL;
}
/* Finalise the operation on the crypto engine */
status = tfm_crypto_engine_cipher_finish(&(ctx->engine_ctx),
output,
- (uint32_t *)output_length);
+ (uint32_t *)&(out_vec[1].len));
if (status != PSA_SUCCESS) {
- *output_length = 0;
+ out_vec[1].len = 0;
(void)tfm_crypto_cipher_release(operation, ctx);
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
return tfm_crypto_cipher_release(operation, ctx);
}
-enum tfm_crypto_err_t tfm_crypto_cipher_abort(psa_cipher_operation_t *operation)
+psa_status_t tfm_crypto_cipher_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_cipher_operation_s *ctx = NULL;
- /* Validate pointers */
- err = tfm_crypto_memory_check(operation,
- sizeof(psa_cipher_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_cipher_operation_t))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ psa_cipher_operation_t *operation = out_vec[0].base;
+
/* Look up the corresponding operation context */
- err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
- operation,
- (void **)&ctx);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+ operation,
+ (void **)&ctx);
+ if (status != PSA_SUCCESS) {
+ return status;
}
return tfm_crypto_cipher_release(operation, ctx);