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_aead.c b/secure_fw/services/crypto/crypto_aead.c
index 1698fd0..7978d7f 100644
--- a/secure_fw/services/crypto/crypto_aead.c
+++ b/secure_fw/services/crypto/crypto_aead.c
@@ -14,7 +14,6 @@
#include "psa_crypto.h"
#include "tfm_crypto_api.h"
-#include "crypto_utils.h"
/**
* \def CRYPTO_AEAD_MAX_KEY_LENGTH
@@ -26,108 +25,102 @@
#define CRYPTO_AEAD_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]));
+}
+
/*!
* \defgroup public_psa Public functions, PSA
*
*/
/*!@{*/
-enum tfm_crypto_err_t tfm_crypto_aead_encrypt(psa_key_slot_t key,
- psa_algorithm_t alg,
- const uint8_t *nonce,
- size_t nonce_length,
- const uint8_t *additional_data,
- size_t additional_data_length,
- const uint8_t *plaintext,
- size_t plaintext_length,
- uint8_t *ciphertext,
- size_t ciphertext_size,
- size_t *ciphertext_length)
+psa_status_t tfm_crypto_aead_encrypt(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;
uint8_t key_data[CRYPTO_AEAD_MAX_KEY_LENGTH];
uint32_t key_size;
psa_key_type_t key_type;
+ if ((in_len != 3) || (out_len != 1)) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ if ((in_vec[0].len < (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))) ||
+ (in_vec[0].len > (TFM_CRYPTO_MAX_NONCE_LENGTH
+ + (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ const struct tfm_crypto_aead_pack_input *input_s = in_vec[0].base;
+ psa_key_slot_t key = input_s->key;
+ psa_algorithm_t alg = input_s->alg;
+ const uint8_t *nonce = input_s->nonce;
+ size_t nonce_length = in_vec[0].len - sizeof(psa_key_slot_t)
+ - sizeof(psa_algorithm_t);
+ const uint8_t *additional_data = in_vec[1].base;
+ size_t additional_data_length = in_vec[1].len;
+ const uint8_t *plaintext = in_vec[2].base;
+ size_t plaintext_length = in_vec[2].len;
+ uint8_t *ciphertext = out_vec[0].base;
+ size_t ciphertext_size = out_vec[0].len;
+
/* Initialise ciphertext_length to zero */
- *ciphertext_length = 0;
+ out_vec[0].len = 0;
if (PSA_ALG_IS_AEAD(alg) == 0) {
- return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+ return PSA_ERROR_NOT_SUPPORTED;
}
if (PSA_AEAD_TAG_SIZE(alg) == 0) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ return PSA_ERROR_INVALID_ARGUMENT;
}
if (PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) > ciphertext_size) {
- return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
+ return PSA_ERROR_BUFFER_TOO_SMALL;
}
if ((nonce_length == 0) ||
((additional_data_length == 0) && (additional_data != NULL))) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
- }
-
- /* Validate pointers */
- err = tfm_crypto_memory_check((void *)nonce,
- nonce_length,
- TFM_MEMORY_ACCESS_RO);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
- }
-
- if ((additional_data != NULL) || (additional_data_length != 0)) {
- err = tfm_crypto_memory_check((void *)additional_data,
- additional_data_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((void *)plaintext,
- plaintext_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((void *)ciphertext,
- ciphertext_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((void *)ciphertext_length,
- sizeof(size_t),
- TFM_MEMORY_ACCESS_RW);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ return PSA_ERROR_INVALID_ARGUMENT;
}
/* Access the key data */
- err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = _psa_get_key_information(key, &key_type, (size_t *)&key_size);
+ if (status != PSA_SUCCESS) {
+ return status;
}
/* Support only AES based AEAD */
if (key_type != PSA_KEY_TYPE_AES) {
- return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+ return PSA_ERROR_NOT_SUPPORTED;
}
/* Access the crypto service key module to retrieve key data */
- err = tfm_crypto_get_key(key,
- PSA_KEY_USAGE_ENCRYPT,
- alg,
- key_data,
- CRYPTO_AEAD_MAX_KEY_LENGTH,
- (size_t *)&key_size);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_get_key(key,
+ PSA_KEY_USAGE_ENCRYPT,
+ alg,
+ key_data,
+ CRYPTO_AEAD_MAX_KEY_LENGTH,
+ (size_t *)&key_size);
+ if (status != PSA_SUCCESS) {
+ return status;
}
/* Request AEAD encryption on the crypto engine */
@@ -143,115 +136,88 @@
plaintext_length,
ciphertext,
ciphertext_size,
- (uint32_t *)ciphertext_length);
+ (uint32_t *)&(out_vec[0].len));
if (status == PSA_SUCCESS) {
/* The ciphertext_length needs to take into account the tag length */
- *ciphertext_length += PSA_AEAD_TAG_SIZE(alg);
+ out_vec[0].len += PSA_AEAD_TAG_SIZE(alg);
} else {
/* In case of failure set the ciphertext_length to zero */
- *ciphertext_length = 0;
+ out_vec[0].len = 0;
}
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
-enum tfm_crypto_err_t tfm_crypto_aead_decrypt(psa_key_slot_t key,
- psa_algorithm_t alg,
- const uint8_t *nonce,
- size_t nonce_length,
- const uint8_t *additional_data,
- size_t additional_data_length,
- const uint8_t *ciphertext,
- size_t ciphertext_length,
- uint8_t *plaintext,
- size_t plaintext_size,
- size_t *plaintext_length)
+psa_status_t tfm_crypto_aead_decrypt(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;
uint8_t key_data[CRYPTO_AEAD_MAX_KEY_LENGTH];
uint32_t key_size;
psa_key_type_t key_type;
+ if ((in_vec[0].len < (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))) ||
+ (in_vec[0].len > (TFM_CRYPTO_MAX_NONCE_LENGTH
+ + (sizeof(psa_key_slot_t) + sizeof(psa_algorithm_t))))) {
+ return PSA_CONNECTION_REFUSED;
+ }
+
+ const struct tfm_crypto_aead_pack_input *input_s = in_vec[0].base;
+ psa_key_slot_t key = input_s->key;
+ psa_algorithm_t alg = input_s->alg;
+ const uint8_t *nonce = input_s->nonce;
+ size_t nonce_length = in_vec[0].len - sizeof(psa_key_slot_t)
+ - sizeof(psa_algorithm_t);
+ const uint8_t *additional_data = in_vec[1].base;
+ size_t additional_data_length = in_vec[1].len;
+ const uint8_t *ciphertext = in_vec[2].base;
+ size_t ciphertext_length = in_vec[2].len;
+ uint8_t *plaintext = out_vec[0].base;
+ size_t plaintext_size = out_vec[0].len;
+
/* Initialise plaintext_length to zero */
- *plaintext_length = 0;
+ out_vec[0].len = 0;
if (PSA_ALG_IS_AEAD(alg) == 0) {
- return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+ return PSA_ERROR_NOT_SUPPORTED;
}
if ((PSA_AEAD_TAG_SIZE(alg) == 0) ||
(ciphertext_length < PSA_AEAD_TAG_SIZE(alg))) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ return PSA_ERROR_INVALID_ARGUMENT;
}
if (PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg,ciphertext_length) > plaintext_size) {
- return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
+ return PSA_ERROR_BUFFER_TOO_SMALL;
}
if ((nonce_length == 0) ||
((additional_data_length == 0) && (additional_data != NULL))) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
- }
-
- /* Validate pointers */
- err = tfm_crypto_memory_check((void *)nonce,
- nonce_length,
- TFM_MEMORY_ACCESS_RO);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
- }
-
- if ((additional_data != NULL) || (additional_data_length != 0)) {
- err = tfm_crypto_memory_check((void *)additional_data,
- additional_data_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((void *)ciphertext,
- ciphertext_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((void *)plaintext,
- plaintext_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((void *)plaintext_length,
- sizeof(size_t),
- TFM_MEMORY_ACCESS_RW);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
+ return PSA_ERROR_INVALID_ARGUMENT;
}
/* Access the key data */
- err = tfm_crypto_get_key_information(key, &key_type, (size_t *)&key_size);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = _psa_get_key_information(key, &key_type, (size_t *)&key_size);
+ if (status != PSA_SUCCESS) {
+ return status;
}
/* Support only AES based AEAD */
if (key_type != PSA_KEY_TYPE_AES) {
- return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+ return PSA_ERROR_NOT_SUPPORTED;
}
/* Access the crypto service key module to retrieve key data */
- err = tfm_crypto_get_key(key,
- PSA_KEY_USAGE_DECRYPT,
- alg,
- key_data,
- CRYPTO_AEAD_MAX_KEY_LENGTH,
- (size_t *)&key_size);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ status = tfm_crypto_get_key(key,
+ PSA_KEY_USAGE_DECRYPT,
+ alg,
+ key_data,
+ CRYPTO_AEAD_MAX_KEY_LENGTH,
+ (size_t *)&key_size);
+ if (status != PSA_SUCCESS) {
+ return status;
}
/* Request AEAD decryption on the crypto engine */
@@ -267,11 +233,11 @@
ciphertext_length,
plaintext,
plaintext_size,
- (uint32_t *)plaintext_length);
+ (uint32_t *)&(out_vec[0].len));
if (status != PSA_SUCCESS) {
- *plaintext_length = 0;
+ out_vec[0].len = 0;
}
- return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ return status;
}
/*!@}*/