blob: f8fa055e28131997321f7e915f7181bfe9bed165 [file] [log] [blame]
/*
* 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_aead_encrypt(psa_invec in_vec[],
size_t in_len,
psa_outvec out_vec[],
size_t out_len)
{
psa_status_t status = PSA_SUCCESS;
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;
const struct tfm_crypto_aead_pack_input *aead_pack_input = &iov->aead_in;
psa_key_handle_t key_handle = iov->key_handle;
psa_algorithm_t alg = iov->alg;
const uint8_t *nonce = aead_pack_input->nonce;
size_t nonce_length = aead_pack_input->nonce_length;
const uint8_t *plaintext = in_vec[1].base;
size_t plaintext_length = in_vec[1].len;
uint8_t *ciphertext = out_vec[0].base;
size_t ciphertext_size = out_vec[0].len;
const uint8_t *additional_data = NULL;
size_t additional_data_length = 0;
/* Check if additional data has been passed and initialise it */
if (in_len == 3) {
additional_data = in_vec[2].base;
additional_data_length = in_vec[2].len;
}
/* Initialise ciphertext_length to zero */
out_vec[0].len = 0;
status = tfm_crypto_check_handle_owner(key_handle, NULL);
if (status == PSA_SUCCESS) {
status = psa_aead_encrypt(key_handle, alg, nonce, nonce_length,
additional_data, additional_data_length,
plaintext, plaintext_length,
ciphertext, ciphertext_size, &out_vec[0].len);
}
return status;
}
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;
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;
const struct tfm_crypto_aead_pack_input *aead_pack_input = &iov->aead_in;
psa_key_handle_t key_handle = iov->key_handle;
psa_algorithm_t alg = iov->alg;
const uint8_t *nonce = aead_pack_input->nonce;
size_t nonce_length = aead_pack_input->nonce_length;
const uint8_t *ciphertext = in_vec[1].base;
size_t ciphertext_length = in_vec[1].len;
uint8_t *plaintext = out_vec[0].base;
size_t plaintext_size = out_vec[0].len;
const uint8_t *additional_data = NULL;
size_t additional_data_length = 0;
/* Check if additional data has been passed and initialise it */
if (in_len == 3) {
additional_data = in_vec[2].base;
additional_data_length = in_vec[2].len;
}
/* Initialise plaintext_length to zero */
out_vec[0].len = 0;
status = tfm_crypto_check_handle_owner(key_handle, NULL);
if (status == PSA_SUCCESS) {
status = psa_aead_decrypt(key_handle, alg, nonce, nonce_length,
additional_data, additional_data_length,
ciphertext, ciphertext_length,
plaintext, plaintext_size, &out_vec[0].len);
}
return status;
}
/*!@}*/