blob: 9726fa0a1fb551576ce43d66424d04b1d88bfa6f [file] [log] [blame]
/*
* Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <limits.h>
#include "tfm_crypto_defs.h"
#include "psa_crypto.h"
#include "tfm_crypto_api.h"
#include "tfm_crypto_struct.h"
#include "secure_fw/core/tfm_memory_utils.h"
/**
* \def TFM_CRYPTO_CONC_OPER_NUM
*
* \brief This value defines the maximum number of simultaneous operations
* supported by this implementation.
*/
#define TFM_CRYPTO_CONC_OPER_NUM (8)
struct tfm_crypto_operation_s {
uint32_t in_use; /*!< Indicates if the operation is in use */
enum tfm_crypto_operation_type type; /*!< Type of the operation */
union {
struct tfm_cipher_operation_s cipher; /*!< Cipher operation context */
struct tfm_mac_operation_s mac; /*!< MAC operation context */
struct tfm_hash_operation_s hash; /*!< Hash operation context */
} operation;
};
static struct tfm_crypto_operation_s operation[TFM_CRYPTO_CONC_OPER_NUM] ={{0}};
/*
* \brief Function used to clear the memory associated to a backend context
*
* \param[in] index Numerical index in the database of the backend contexts
*
* \return None
*
*/
static void memset_operation_context(uint32_t index)
{
uint32_t mem_size;
uint8_t *mem_ptr = (uint8_t *) &(operation[index].operation);
switch(operation[index].type) {
case TFM_CRYPTO_CIPHER_OPERATION:
mem_size = sizeof(struct tfm_cipher_operation_s);
break;
case TFM_CRYPTO_MAC_OPERATION:
mem_size = sizeof(struct tfm_mac_operation_s);
break;
case TFM_CRYPTO_HASH_OPERATION:
mem_size = sizeof(struct tfm_hash_operation_s);
break;
case TFM_CRYPTO_OPERATION_NONE:
default:
mem_size = 0;
break;
}
/* Clear the contents of the backend context */
(void)tfm_memset(mem_ptr, 0, mem_size);
}
/*!
* \defgroup public Public functions
*
*/
/*!@{*/
psa_status_t tfm_crypto_init_alloc(void)
{
/* Clear the contents of the local contexts */
(void)tfm_memset(operation, 0, sizeof(operation));
return PSA_SUCCESS;
}
psa_status_t tfm_crypto_operation_alloc(enum tfm_crypto_operation_type type,
uint32_t *handle,
void **ctx)
{
uint32_t i = 0;
/* Init to invalid values */
if (ctx == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
*ctx = NULL;
for (i=0; i<TFM_CRYPTO_CONC_OPER_NUM; i++) {
if (operation[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
operation[i].in_use = TFM_CRYPTO_IN_USE;
operation[i].type = type;
*handle = i;
*ctx = (void *) &(operation[i].operation);
return PSA_SUCCESS;
}
}
*handle = TFM_CRYPTO_INVALID_HANDLE;
return PSA_ERROR_NOT_PERMITTED;
}
psa_status_t tfm_crypto_operation_release(uint32_t *handle)
{
uint32_t h_val = *handle;
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;
*handle = TFM_CRYPTO_INVALID_HANDLE;
return PSA_SUCCESS;
}
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_status_t tfm_crypto_operation_lookup(enum tfm_crypto_operation_type type,
uint32_t handle,
void **ctx)
{
if ( (handle != TFM_CRYPTO_INVALID_HANDLE) &&
(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;
}
return PSA_ERROR_BAD_STATE;
}
/*!@}*/