Merge pull request #13358 from RaymondNgun/topic/cytfm_064b0s2_4343w

Add CYTFM_064B0S2 4343W Target
pull/13415/head
Anna Bridge 2020-08-11 10:52:39 +01:00 committed by GitHub
commit 88d931384f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
154 changed files with 36242 additions and 2 deletions

View File

@ -0,0 +1,304 @@
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
* Copyright (c) 2019, Cypress Semiconductor Corporation. All rights reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* -------------------------------------- Includes ----------------------------------- */
#include <limits.h>
#include <string.h>
#include "cmsis_compiler.h"
#include "cy_ipc_drv.h"
#include "cy_sysint.h"
#include "cy_ipc_sema.h"
#include "ns_ipc_config.h"
#include "tfm_ns_mailbox.h"
#include "platform_multicore.h"
#include "cmsis_os2.h"
static uint8_t saved_irq_state = 1;
/* -------------------------------------- HAL API ------------------------------------ */
static void mailbox_ipc_init(void)
{
Cy_IPC_Drv_SetInterruptMask(Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT),
0, IPC_RX_INT_MASK);
}
static void mailbox_ipc_config(void)
{
NVIC_SetPriority(PSA_CLIENT_REPLY_NVIC_IRQn, PSA_CLIENT_REPLY_IRQ_PRIORITY);
NVIC_EnableIRQ(PSA_CLIENT_REPLY_NVIC_IRQn);
}
int32_t tfm_ns_mailbox_hal_notify_peer(void)
{
cy_en_ipcdrv_status_t status;
status = Cy_IPC_Drv_SendMsgWord(Cy_IPC_Drv_GetIpcBaseAddress(IPC_TX_CHAN),
IPC_TX_NOTIFY_MASK,
PSA_CLIENT_CALL_REQ_MAGIC);
if (status == CY_IPC_DRV_SUCCESS) {
return MAILBOX_SUCCESS;
} else {
return MAILBOX_CHAN_BUSY;
}
}
static int32_t mailbox_sema_init(void)
{
#if defined(CY_IPC_DEFAULT_CFG_DISABLE)
/* semaphore data */
static uint32_t tfm_sema __attribute__((section("TFM_SHARED_DATA")));
if (Cy_IPC_Sema_Init(PLATFORM_MAILBOX_IPC_CHAN_SEMA,
sizeof(tfm_sema) * CHAR_BIT,
&tfm_sema) != CY_IPC_SEMA_SUCCESS) {
return PLATFORM_MAILBOX_INIT_ERROR;
}
#endif
return PLATFORM_MAILBOX_SUCCESS;
}
int32_t tfm_ns_mailbox_hal_init(struct ns_mailbox_queue_t *queue)
{
uint32_t stage;
if (!queue) {
return MAILBOX_INVAL_PARAMS;
}
/* Init semaphores used for critical sections */
if (mailbox_sema_init() != PLATFORM_MAILBOX_SUCCESS)
return MAILBOX_INIT_ERROR;
/*
* FIXME
* Further verification of mailbox queue address may be required according
* to diverse NSPE implementations.
*/
mailbox_ipc_init();
/*
* Wait until SPE mailbox library is ready to receive NSPE mailbox queue
* address.
*/
while (1) {
platform_mailbox_wait_for_notify();
platform_mailbox_fetch_msg_data(&stage);
if (stage == NS_MAILBOX_INIT_ENABLE) {
break;
}
}
/* Send out the address */
platform_mailbox_send_msg_ptr(queue);
/* Wait until SPE mailbox service is ready */
while (1) {
platform_mailbox_wait_for_notify();
platform_mailbox_fetch_msg_data(&stage);
if (stage == S_MAILBOX_READY) {
break;
}
}
mailbox_ipc_config();
return MAILBOX_SUCCESS;
}
const void *tfm_ns_mailbox_get_task_handle(void)
{
return osThreadGetId();;
}
void tfm_ns_mailbox_hal_wait_reply(mailbox_msg_handle_t handle)
{
osThreadFlagsWait(handle, osFlagsWaitAll, osWaitForever);
}
static cy_en_ipcsema_status_t mailbox_raw_spin_lock(uint32_t ipc_channel,
uint32_t sema_num)
{
uint32_t semaIndex;
uint32_t semaMask;
cy_stc_ipc_sema_t *semaStruct;
cy_en_ipcdrv_status_t acqStatus;
cy_en_ipcsema_status_t ret = CY_IPC_SEMA_BAD_PARAM;
bool is_lock = false;
IPC_STRUCT_Type *semaIpcStruct;
/* Get IPC register structure */
semaIpcStruct = Cy_IPC_Drv_GetIpcBaseAddress(ipc_channel);
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(semaIpcStruct);
if (sema_num < semaStruct->maxSema) {
semaIndex = sema_num / CY_IPC_SEMA_PER_WORD;
semaMask = (uint32_t)(1ul << (sema_num - \
(semaIndex * CY_IPC_SEMA_PER_WORD)));
while (!is_lock) {
/* Check to make sure the IPC channel is released
If so, check if specific channel can be locked. */
do {
acqStatus = Cy_IPC_Drv_LockAcquire(semaIpcStruct);
} while (acqStatus != CY_IPC_DRV_SUCCESS);
if ((semaStruct->arrayPtr[semaIndex] & semaMask) == 0ul) {
semaStruct->arrayPtr[semaIndex] |= semaMask;
is_lock = true;
}
/* Release, but do not trigger a release event */
(void)Cy_IPC_Drv_LockRelease(semaIpcStruct,
CY_IPC_NO_NOTIFICATION);
if (!is_lock) {
/*
* The secure core is occupying this lock. Insert a small delay
* to give the secure core a chance to acquire the IPC channel
* and release the lock.
* Otherwise, the secure core may not be able to release the
* lock if non-secure core has higher CPU frequency. It will
* generate a deadlock.
* This delay won't harm performance too much since non-secure
* core has to busy wait here anyway.
* Alternatively, non-secure core can wait for release
* notification event from secure core. However, it is more
* complex and requires more code and more modifications.
*/
volatile uint32_t count = 1000;
while(count > 0) {
count--;
}
Cy_IPC_Sema_Status(sema_num);
}
}
ret = CY_IPC_SEMA_SUCCESS;
}
return ret;
}
static cy_en_ipcsema_status_t mailbox_raw_spin_unlock(uint32_t ipc_channel,
uint32_t sema_num)
{
uint32_t semaIndex;
uint32_t semaMask;
cy_stc_ipc_sema_t *semaStruct;
cy_en_ipcdrv_status_t acqStatus;
cy_en_ipcsema_status_t ret = CY_IPC_SEMA_BAD_PARAM;
bool is_unlock = false;
IPC_STRUCT_Type *semaIpcStruct;
/* Get IPC register structure */
semaIpcStruct = Cy_IPC_Drv_GetIpcBaseAddress(ipc_channel);
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(semaIpcStruct);
if (sema_num < semaStruct->maxSema) {
semaIndex = sema_num / CY_IPC_SEMA_PER_WORD;
semaMask = (uint32_t)(1ul << (sema_num - \
(semaIndex * CY_IPC_SEMA_PER_WORD)));
while (!is_unlock) {
/* Check to make sure the IPC channel is released
If so, check if specific channel can be locked. */
do {
acqStatus = Cy_IPC_Drv_LockAcquire(semaIpcStruct);
} while (acqStatus != CY_IPC_DRV_SUCCESS);
if ((semaStruct->arrayPtr[semaIndex] & semaMask) != 0ul) {
semaStruct->arrayPtr[semaIndex] &= ~semaMask;
is_unlock = true;
}
/* Release, but do not trigger a release event */
(void)Cy_IPC_Drv_LockRelease(semaIpcStruct,
CY_IPC_NO_NOTIFICATION);
}
ret = CY_IPC_SEMA_SUCCESS;
}
return ret;
}
void tfm_ns_mailbox_hal_enter_critical(void)
{
saved_irq_state = Cy_SysLib_EnterCriticalSection();
mailbox_raw_spin_lock(CY_IPC_CHAN_SEMA, MAILBOX_SEMAPHORE_NUM);
}
void tfm_ns_mailbox_hal_exit_critical(void)
{
mailbox_raw_spin_unlock(CY_IPC_CHAN_SEMA, MAILBOX_SEMAPHORE_NUM);
Cy_SysLib_ExitCriticalSection(saved_irq_state);
}
void tfm_ns_mailbox_hal_enter_critical_isr(void)
{
mailbox_raw_spin_lock(CY_IPC_CHAN_SEMA, MAILBOX_SEMAPHORE_NUM);
}
void tfm_ns_mailbox_hal_exit_critical_isr(void)
{
mailbox_raw_spin_unlock(CY_IPC_CHAN_SEMA, MAILBOX_SEMAPHORE_NUM);
}
static bool mailbox_clear_intr(void)
{
uint32_t status;
status = Cy_IPC_Drv_GetInterruptStatusMasked(
Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT));
status >>= CY_IPC_NOTIFY_SHIFT;
if ((status & IPC_RX_INT_MASK) == 0) {
return false;
}
Cy_IPC_Drv_ClearInterrupt(Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT),
0, IPC_RX_INT_MASK);
return true;
}
void cpuss_interrupts_ipc_8_IRQHandler(void)
{
uint32_t magic;
mailbox_msg_handle_t handle;
osThreadId_t task_handle;
if (!mailbox_clear_intr())
return;
platform_mailbox_fetch_msg_data(&magic);
if (magic == PSA_CLIENT_CALL_REPLY_MAGIC) {
/* Handle all the pending replies */
while (1) {
handle = tfm_ns_mailbox_fetch_reply_msg_isr();
if (handle == MAILBOX_MSG_NULL_HANDLE) {
break;
}
task_handle = (osThreadId_t)tfm_ns_mailbox_get_msg_owner(handle);
if (task_handle) {
osThreadFlagsSet(task_handle, handle);
}
}
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "tfm_api.h"
#include "tfm_mailbox.h"
#include "tfm_multi_core_api.h"
#include "cmsis_os2.h"
#include "mbed_rtos_storage.h"
#define MAX_SEMAPHORE_COUNT NUM_MAILBOX_QUEUE_SLOT
static void *ns_lock_handle = NULL;
static mbed_rtos_storage_semaphore_t tfm_ns_sema_obj;
__attribute__((weak))
enum tfm_status_e tfm_ns_interface_init(void)
{
osSemaphoreAttr_t sema_attrib = {
.name = "tfm_ns_lock",
.attr_bits = 0,
.cb_size = sizeof(tfm_ns_sema_obj),
.cb_mem = &tfm_ns_sema_obj
};
ns_lock_handle = osSemaphoreNew(MAX_SEMAPHORE_COUNT,
MAX_SEMAPHORE_COUNT,
&sema_attrib);
if (!ns_lock_handle) {
return TFM_ERROR_GENERIC;
}
return TFM_SUCCESS;
}
int32_t tfm_ns_wait_for_s_cpu_ready(void)
{
return tfm_platform_ns_wait_for_s_cpu_ready();
}
uint32_t tfm_ns_multi_core_lock_acquire(void)
{
return osSemaphoreAcquire(ns_lock_handle, osWaitForever);
}
uint32_t tfm_ns_multi_core_lock_release(void)
{
return osSemaphoreRelease(ns_lock_handle);
}

View File

@ -0,0 +1,224 @@
/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "psa/client.h"
#include "psa/error.h"
#include "tfm_api.h"
#include "tfm_multi_core_api.h"
#include "tfm_ns_mailbox.h"
/*
* TODO
* Currently, force all the non-secure client to share the same ID.
*
* It requires a more clear mechanism to synchronize the non-secure client
* ID with SPE in dual core scenario.
* In current design, the value is transferred to SPE via mailbox message.
* A dedicated routine to receive the non-secure client information in
* TF-M core/SPM in dual core scenario should be added besides current
* implementation for single Armv8-M.
* The non-secure client identification is shared with SPE in
* single Armv8-M scenario via CMSIS TrustZone context management API,
* which may not work in dual core scenario.
*/
#define NON_SECURE_CLIENT_ID (1)
/*
* TODO
* Require a formal definition of errors related to mailbox in PSA client call.
*/
#define PSA_INTER_CORE_COMM_ERR (INT32_MIN + 0xFF)
static void mailbox_wait_reply(mailbox_msg_handle_t handle)
{
/*
* If the system can support multiple outstanding NS PSA Client calls, call
* tfm_ns_mailbox_wait_reply() to sleep and wait for reply. The NS side
* should implement tfm_ns_mailbox_hal_wait_reply() and wake-up mechanism.
* Otherwise, by default, call tfm_ns_mailbox_is_msg_replied() to simply
* poll the reply status of the mailbox message of current thread.
*/
#ifdef TFM_MULTI_CORE_MULTI_CLIENT_CALL
tfm_ns_mailbox_wait_reply(handle);
#else
while (!tfm_ns_mailbox_is_msg_replied(handle)) {
}
#endif
}
/**** API functions ****/
uint32_t psa_framework_version(void)
{
struct psa_client_params_t params;
mailbox_msg_handle_t handle;
uint32_t version;
int32_t ret;
if (tfm_ns_multi_core_lock_acquire() != 0) {
return PSA_VERSION_NONE;
}
handle = tfm_ns_mailbox_tx_client_req(MAILBOX_PSA_FRAMEWORK_VERSION,
&params, NON_SECURE_CLIENT_ID);
if (handle < 0) {
tfm_ns_multi_core_lock_release();
return PSA_VERSION_NONE;
}
mailbox_wait_reply(handle);
ret = tfm_ns_mailbox_rx_client_reply(handle, (int32_t *)&version);
if (ret != MAILBOX_SUCCESS) {
version = PSA_VERSION_NONE;
}
if (tfm_ns_multi_core_lock_release() != 0) {
return PSA_VERSION_NONE;
}
return version;
}
uint32_t psa_version(uint32_t sid)
{
struct psa_client_params_t params;
mailbox_msg_handle_t handle;
uint32_t version;
int32_t ret;
params.psa_version_params.sid = sid;
if (tfm_ns_multi_core_lock_acquire() != 0) {
return PSA_VERSION_NONE;
}
handle = tfm_ns_mailbox_tx_client_req(MAILBOX_PSA_VERSION, &params,
NON_SECURE_CLIENT_ID);
if (handle < 0) {
tfm_ns_multi_core_lock_release();
return PSA_VERSION_NONE;
}
mailbox_wait_reply(handle);
ret = tfm_ns_mailbox_rx_client_reply(handle, (int32_t *)&version);
if (ret != MAILBOX_SUCCESS) {
version = PSA_VERSION_NONE;
}
if (tfm_ns_multi_core_lock_release() != 0) {
return PSA_VERSION_NONE;
}
return version;
}
psa_handle_t psa_connect(uint32_t sid, uint32_t version)
{
struct psa_client_params_t params;
mailbox_msg_handle_t handle;
psa_handle_t psa_handle;
int32_t ret;
params.psa_connect_params.sid = sid;
params.psa_connect_params.version = version;
if (tfm_ns_multi_core_lock_acquire() != 0) {
return PSA_NULL_HANDLE;
}
handle = tfm_ns_mailbox_tx_client_req(MAILBOX_PSA_CONNECT, &params,
NON_SECURE_CLIENT_ID);
if (handle < 0) {
tfm_ns_multi_core_lock_release();
return PSA_NULL_HANDLE;
}
mailbox_wait_reply(handle);
ret = tfm_ns_mailbox_rx_client_reply(handle, (int32_t *)&psa_handle);
if (ret != MAILBOX_SUCCESS) {
psa_handle = PSA_NULL_HANDLE;
}
if (tfm_ns_multi_core_lock_release() != 0) {
return PSA_NULL_HANDLE;
}
return psa_handle;
}
psa_status_t psa_call(psa_handle_t handle, int32_t type,
const psa_invec *in_vec, size_t in_len,
psa_outvec *out_vec, size_t out_len)
{
struct psa_client_params_t params;
mailbox_msg_handle_t msg_handle;
int32_t ret;
psa_status_t status;
params.psa_call_params.handle = handle;
params.psa_call_params.type = type;
params.psa_call_params.in_vec = in_vec;
params.psa_call_params.in_len = in_len;
params.psa_call_params.out_vec = out_vec;
params.psa_call_params.out_len = out_len;
if (tfm_ns_multi_core_lock_acquire() != 0) {
return PSA_ERROR_GENERIC_ERROR;
}
msg_handle = tfm_ns_mailbox_tx_client_req(MAILBOX_PSA_CALL, &params,
NON_SECURE_CLIENT_ID);
if (msg_handle < 0) {
tfm_ns_multi_core_lock_release();
return PSA_INTER_CORE_COMM_ERR;
}
mailbox_wait_reply(msg_handle);
ret = tfm_ns_mailbox_rx_client_reply(msg_handle, (int32_t *)&status);
if (ret != MAILBOX_SUCCESS) {
status = PSA_INTER_CORE_COMM_ERR;
}
if (tfm_ns_multi_core_lock_release() != 0) {
return PSA_ERROR_GENERIC_ERROR;
}
return status;
}
void psa_close(psa_handle_t handle)
{
struct psa_client_params_t params;
mailbox_msg_handle_t msg_handle;
int32_t reply;
params.psa_close_params.handle = handle;
if (tfm_ns_multi_core_lock_acquire() != 0) {
return;
}
msg_handle = tfm_ns_mailbox_tx_client_req(MAILBOX_PSA_CLOSE, &params,
NON_SECURE_CLIENT_ID);
if (msg_handle < 0) {
tfm_ns_multi_core_lock_release();
return;
}
mailbox_wait_reply(msg_handle);
(void)tfm_ns_mailbox_rx_client_reply(msg_handle, &reply);
tfm_ns_multi_core_lock_release();
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
* Copyright (c) 2019, Cypress Semiconductor Corporation. All rights reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef _TFM_PLATFORM_MULTICORE_
#define _TFM_PLATFORM_MULTICORE_
#include <stdint.h>
#include "cy_device_headers.h"
#define IPC_PSA_CLIENT_CALL_CHAN (8)
#define IPC_PSA_CLIENT_CALL_INTR_STRUCT (6)
#define IPC_PSA_CLIENT_CALL_INTR_MASK (1 << IPC_PSA_CLIENT_CALL_CHAN)
#define IPC_PSA_CLIENT_CALL_NOTIFY_MASK (1 << IPC_PSA_CLIENT_CALL_INTR_STRUCT)
#define IPC_PSA_CLIENT_CALL_IPC_INTR cpuss_interrupts_ipc_6_IRQn
#define IPC_PSA_CLIENT_REPLY_CHAN (9)
#define IPC_PSA_CLIENT_REPLY_INTR_STRUCT (8)
#define IPC_PSA_CLIENT_REPLY_INTR_MASK (1 << IPC_PSA_CLIENT_REPLY_CHAN)
#define IPC_PSA_CLIENT_REPLY_NOTIFY_MASK (1 << IPC_PSA_CLIENT_REPLY_INTR_STRUCT)
#define IPC_PSA_CLIENT_REPLY_IPC_INTR cpuss_interrupts_ipc_8_IRQn
#define IPC_RX_RELEASE_MASK (0)
#define CY_IPC_NOTIFY_SHIFT (16)
#define PSA_CLIENT_CALL_REQ_MAGIC (0xA5CF50C6)
#define PSA_CLIENT_CALL_REPLY_MAGIC (0xC605FC5A)
#define NS_MAILBOX_INIT_ENABLE (0xAE)
#define S_MAILBOX_READY (0xC3)
#define PLATFORM_MAILBOX_SUCCESS (0x0)
#define PLATFORM_MAILBOX_INVAL_PARAMS (INT32_MIN + 1)
#define PLATFORM_MAILBOX_TX_ERROR (INT32_MIN + 2)
#define PLATFORM_MAILBOX_RX_ERROR (INT32_MIN + 3)
#define PLATFORM_MAILBOX_INIT_ERROR (INT32_MIN + 4)
/* Inter-Processor Communication (IPC) data channel for the Semaphores */
#define PLATFORM_MAILBOX_IPC_CHAN_SEMA CY_IPC_CHAN_SEMA
#define MAILBOX_SEMAPHORE_NUM (16)
#define IPC_SYNC_MAGIC 0x7DADE011
/**
* \brief Fetch a pointer from mailbox message
*
* \param[out] msg_ptr The address to write the pointer value to.
*
* \retval 0 The operation succeeds.
* \retval else The operation fails.
*/
int platform_mailbox_fetch_msg_ptr(void **msg_ptr);
/**
* \brief Fetch a data value from mailbox message
*
* \param[out] data_ptr The address to write the pointer value to.
*
* \retval 0 The operation succeeds.
* \retval else The operation fails.
*/
int platform_mailbox_fetch_msg_data(uint32_t *data_ptr);
/**
* \brief Send a pointer via mailbox message
*
* \param[in] msg_ptr The pointer value to be sent.
*
* \retval 0 The operation succeeds.
* \retval else The operation fails.
*/
int platform_mailbox_send_msg_ptr(const void *msg_ptr);
/**
* \brief Send a data value via mailbox message
*
* \param[in] data The data value to be sent
*
* \retval 0 The operation succeeds.
* \retval else The operation fails.
*/
int platform_mailbox_send_msg_data(uint32_t data);
/**
* \brief Wait for a mailbox notify event.
*/
void platform_mailbox_wait_for_notify(void);
/**
* \brief IPC initialization
*
* \retval 0 The operation succeeds.
* \retval else The operation fails.
*/
int platform_ns_ipc_init(void);
#endif

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/**
* \file psa/crypto_extra.h
*
* \brief PSA cryptography module: vendor extensions
*
* \note This file may not be included directly. Applications must
* include psa/crypto.h.
*
* This file is reserved for vendor-specific definitions.
*/
#ifndef PSA_CRYPTO_EXTRA_H
#define PSA_CRYPTO_EXTRA_H
#include "psa/crypto_compat.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \brief Declare the enrollment algorithm for a key.
*
* An operation on a key may indifferently use the algorithm set with
* psa_set_key_algorithm() or with this function.
*
* \param[out] attributes The attribute structure to write to.
* \param alg2 A second algorithm that the key may be used
* for, in addition to the algorithm set with
* psa_set_key_algorithm().
*
* \warning Setting an enrollment algorithm is not recommended, because
* using the same key with different algorithms can allow some
* attacks based on arithmetic relations between different
* computations made with the same key, or can escalate harmless
* side channels into exploitable ones. Use this function only
* if it is necessary to support a protocol for which it has been
* verified that the usage of the key with multiple algorithms
* is safe.
*/
static inline void psa_set_key_enrollment_algorithm(
psa_key_attributes_t *attributes,
psa_algorithm_t alg2)
{
attributes->core.policy.alg2 = alg2;
}
#ifdef __cplusplus
}
#endif
#endif /* PSA_CRYPTO_EXTRA_H */

View File

@ -0,0 +1,301 @@
/*
* Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/**
* \file psa/crypto_struct.h
*
* \brief PSA cryptography module: structured type implementations
*
* \note This file may not be included directly. Applications must
* include psa/crypto.h.
*
* This file contains the definitions of some data structures with
* implementation-specific definitions.
*
* In implementations with isolation between the application and the
* cryptography module, it is expected that the front-end and the back-end
* would have different versions of this file.
*/
#ifndef PSA_CRYPTO_STRUCT_H
#define PSA_CRYPTO_STRUCT_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Note that the below structures are different from the decalrations in
* mbed-crypto. This is because TF-M maintains 'front-end' and 'back-end'
* versions of this header. In the front-end version, exported to NS
* clients in interface/include/psa, a crypto operation is defined as an
* opaque handle to a context in the Crypto service. The back-end
* version, directly included from the mbed-crypto repo by the Crypto
* service, contains the full definition of the operation structs.
*
* One of the functions of the Crypto service is to allocate the back-end
* operation contexts in its own partition memory (in crypto_alloc.c),
* and then do the mapping between front-end operation handles passed by
* NS clients and the corresponding back-end operation contexts. The
* advantage of doing it this way is that internal mbed-crypto state is never
* exposed to the NS client.
*/
struct psa_hash_operation_s
{
uint32_t handle;
};
#define PSA_HASH_OPERATION_INIT {0}
static inline struct psa_hash_operation_s psa_hash_operation_init( void )
{
const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT;
return( v );
}
struct psa_mac_operation_s
{
uint32_t handle;
};
#define PSA_MAC_OPERATION_INIT {0}
static inline struct psa_mac_operation_s psa_mac_operation_init( void )
{
const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT;
return( v );
}
struct psa_cipher_operation_s
{
uint32_t handle;
};
#define PSA_CIPHER_OPERATION_INIT {0}
static inline struct psa_cipher_operation_s psa_cipher_operation_init( void )
{
const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT;
return( v );
}
struct psa_aead_operation_s
{
uint32_t handle;
};
#define PSA_AEAD_OPERATION_INIT {0}
static inline struct psa_aead_operation_s psa_aead_operation_init( void )
{
const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT;
return( v );
}
struct psa_key_derivation_s
{
uint32_t handle;
};
#define PSA_KEY_DERIVATION_OPERATION_INIT {0}
static inline struct psa_key_derivation_s psa_key_derivation_operation_init( void )
{
const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT;
return( v );
}
struct psa_key_policy_s
{
psa_key_usage_t usage;
psa_algorithm_t alg;
psa_algorithm_t alg2;
};
typedef struct psa_key_policy_s psa_key_policy_t;
#define PSA_KEY_POLICY_INIT {0, 0, 0}
static inline struct psa_key_policy_s psa_key_policy_init( void )
{
const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT;
return( v );
}
/* The type used internally for key sizes.
* Public interfaces use size_t, but internally we use a smaller type. */
typedef uint16_t psa_key_bits_t;
/* The maximum value of the type used to represent bit-sizes.
* This is used to mark an invalid key size. */
#define PSA_KEY_BITS_TOO_LARGE ( (psa_key_bits_t) ( -1 ) )
/* The maximum size of a key in bits.
* Currently defined as the maximum that can be represented, rounded down
* to a whole number of bytes.
* This is an uncast value so that it can be used in preprocessor
* conditionals. */
#define PSA_MAX_KEY_BITS 0xfff8
/** A mask of flags that can be stored in key attributes.
*
* This type is also used internally to store flags in slots. Internal
* flags are defined in library/psa_crypto_core.h. Internal flags may have
* the same value as external flags if they are properly handled during
* key creation and in psa_get_key_attributes.
*/
typedef uint16_t psa_key_attributes_flag_t;
#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER \
( (psa_key_attributes_flag_t) 0x0001 )
/* A mask of key attribute flags used externally only.
* Only meant for internal checks inside the library. */
#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \
MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER | \
0 )
/* A mask of key attribute flags used both internally and externally.
* Currently there aren't any. */
#define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \
0 )
typedef struct
{
psa_key_type_t type;
psa_key_lifetime_t lifetime;
psa_key_id_t id;
psa_key_policy_t policy;
psa_key_bits_t bits;
psa_key_attributes_flag_t flags;
} psa_core_key_attributes_t;
#define PSA_CORE_KEY_ATTRIBUTES_INIT {0, 0, PSA_KEY_ID_INIT, PSA_KEY_POLICY_INIT, 0, 0}
struct psa_key_attributes_s
{
psa_core_key_attributes_t core;
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
psa_key_slot_number_t slot_number;
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
void *domain_parameters;
size_t domain_parameters_size;
};
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, 0, NULL, 0}
#else
#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0}
#endif
static inline struct psa_key_attributes_s psa_key_attributes_init( void )
{
const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT;
return( v );
}
static inline void psa_set_key_id(psa_key_attributes_t *attributes,
psa_key_id_t id)
{
attributes->core.id = id;
if( attributes->core.lifetime == PSA_KEY_LIFETIME_VOLATILE )
attributes->core.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
}
static inline psa_key_id_t psa_get_key_id(
const psa_key_attributes_t *attributes)
{
return( attributes->core.id );
}
static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
psa_key_lifetime_t lifetime)
{
attributes->core.lifetime = lifetime;
if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
{
#ifdef MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
attributes->core.id.key_id = 0;
attributes->core.id.owner = 0;
#else
attributes->core.id = 0;
#endif
}
}
static inline psa_key_lifetime_t psa_get_key_lifetime(
const psa_key_attributes_t *attributes)
{
return( attributes->core.lifetime );
}
static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
psa_key_usage_t usage_flags)
{
attributes->core.policy.usage = usage_flags;
}
static inline psa_key_usage_t psa_get_key_usage_flags(
const psa_key_attributes_t *attributes)
{
return( attributes->core.policy.usage );
}
static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
psa_algorithm_t alg)
{
attributes->core.policy.alg = alg;
}
static inline psa_algorithm_t psa_get_key_algorithm(
const psa_key_attributes_t *attributes)
{
return( attributes->core.policy.alg );
}
/* This function is declared in crypto_extra.h, which comes after this
* header file, but we need the function here, so repeat the declaration. */
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
psa_key_type_t type,
const uint8_t *data,
size_t data_length);
static inline void psa_set_key_type(psa_key_attributes_t *attributes,
psa_key_type_t type)
{
if( attributes->domain_parameters == NULL )
{
/* Common case: quick path */
attributes->core.type = type;
}
else
{
/* Call the bigger function to free the old domain paramteres.
* Ignore any errors which may arise due to type requiring
* non-default domain parameters, since this function can't
* report errors. */
(void) psa_set_key_domain_parameters( attributes, type, NULL, 0 );
}
}
static inline psa_key_type_t psa_get_key_type(
const psa_key_attributes_t *attributes)
{
return( attributes->core.type );
}
static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
size_t bits)
{
if( bits > PSA_MAX_KEY_BITS )
attributes->core.bits = PSA_KEY_BITS_TOO_LARGE;
else
attributes->core.bits = (psa_key_bits_t) bits;
}
static inline size_t psa_get_key_bits(
const psa_key_attributes_t *attributes)
{
return( attributes->core.bits );
}
#ifdef __cplusplus
}
#endif
#endif /* PSA_CRYPTO_STRUCT_H */

View File

@ -0,0 +1,313 @@
/*
* Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/**
* \file psa/crypto_types.h
*
* \brief PSA cryptography module: type aliases.
*
* \note This file may not be included directly. Applications must
* include psa/crypto.h. Drivers must include the appropriate driver
* header file.
*
* This file contains portable definitions of integral types for properties
* of cryptographic keys, designations of cryptographic algorithms, and
* error codes returned by the library.
*
* This header file does not declare any function.
*/
#ifndef PSA_CRYPTO_TYPES_H
#define PSA_CRYPTO_TYPES_H
#include <stdint.h>
/** \defgroup error Error codes
* @{
*/
/**
* \brief Function return status.
*
* This is either #PSA_SUCCESS (which is zero), indicating success,
* or a small negative value indicating that an error occurred. Errors are
* encoded as one of the \c PSA_ERROR_xxx values defined here. */
/* If #PSA_SUCCESS is already defined, it means that #psa_status_t
* is also defined in an external header, so prevent its multiple
* definition.
*/
#ifndef PSA_SUCCESS
typedef int32_t psa_status_t;
#endif
/**@}*/
/** \defgroup crypto_types Key and algorithm types
* @{
*/
/** \brief Encoding of a key type.
*/
typedef uint32_t psa_key_type_t;
/** The type of PSA elliptic curve identifiers.
*
* The curve identifier is required to create an ECC key using the
* PSA_KEY_TYPE_ECC_KEY_PAIR() or PSA_KEY_TYPE_ECC_PUBLIC_KEY()
* macros.
*
* The encoding of curve identifiers is taken from the
* TLS Supported Groups Registry (formerly known as the
* TLS EC Named Curve Registry)
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
*
* This specification defines identifiers for some of the curves in the IANA
* registry. Implementations that support other curves that are in the IANA
* registry should use the IANA value and a implementation-specific identifier.
* Implemenations that support non-IANA curves should use one of the following
* approaches for allocating a key type:
*
* 1. Select a ::psa_ecc_curve_t value in the range #PSA_ECC_CURVE_VENDOR_MIN to
* #PSA_ECC_CURVE_VENDOR_MAX, which is a subset of the IANA private use
* range.
* 2. Use a ::psa_key_type_t value that is vendor-defined.
*
* The first option is recommended.
*/
typedef uint16_t psa_ecc_curve_t;
/** The type of PSA Diffie-Hellman group identifiers.
*
* The group identifier is required to create an Diffie-Hellman key using the
* PSA_KEY_TYPE_DH_KEY_PAIR() or PSA_KEY_TYPE_DH_PUBLIC_KEY()
* macros.
*
* The encoding of group identifiers is taken from the
* TLS Supported Groups Registry (formerly known as the
* TLS EC Named Curve Registry)
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
*
* This specification defines identifiers for some of the groups in the IANA
* registry. Implementations that support other groups that are in the IANA
* registry should use the IANA value and a implementation-specific identifier.
* Implemenations that support non-IANA groups should use one of the following
* approaches for allocating a key type:
*
* 1. Select a ::psa_dh_group_t value in the range #PSA_DH_GROUP_VENDOR_MIN to
* #PSA_DH_GROUP_VENDOR_MAX, which is a subset of the IANA private use
* range.
* 2. Select a ::psa_dh_group_t value from the named groups allocated for
* GREASE in the IETF draft specification. The GREASE specification and
* values are listed below.
* 3. Use a ::psa_key_type_t value that is vendor-defined.
*
* Option 1 or 2 are recommended.
*
* The current draft of the GREASE specification is
* https://datatracker.ietf.org/doc/draft-ietf-tls-grease
*
* The following GREASE values are allocated for named groups:
* \code
* 0x0A0A
* 0x1A1A
* 0x2A2A
* 0x3A3A
* 0x4A4A
* 0x5A5A
* 0x6A6A
* 0x7A7A
* 0x8A8A
* 0x9A9A
* 0xAAAA
* 0xBABA
* 0xCACA
* 0xDADA
* 0xEAEA
* 0xFAFA
* \endcode
*/
typedef uint16_t psa_dh_group_t;
/** \brief Encoding of a cryptographic algorithm.
*
* For algorithms that can be applied to multiple key types, this type
* does not encode the key type. For example, for symmetric ciphers
* based on a block cipher, #psa_algorithm_t encodes the block cipher
* mode and the padding mode while the block cipher itself is encoded
* via #psa_key_type_t.
*/
typedef uint32_t psa_algorithm_t;
/**@}*/
/** \defgroup key_lifetimes Key lifetimes
* @{
*/
/** Encoding of key lifetimes.
*
* The lifetime of a key indicates where it is stored and what system actions
* may create and destroy it.
*
* Keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE are automatically
* destroyed when the application terminates or on a power reset.
*
* Keys with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE are said
* to be _persistent_.
* Persistent keys are preserved if the application or the system restarts.
* Persistent keys have a key identifier of type #psa_key_id_t.
* The application can call psa_open_key() to open a persistent key that
* it created previously.
*/
typedef uint32_t psa_key_lifetime_t;
/** Encoding of identifiers of persistent keys.
*
* - Applications may freely choose key identifiers in the range
* #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX.
* - Implementations may define additional key identifiers in the range
* #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX.
* - 0 is reserved as an invalid key identifier.
* - Key identifiers outside these ranges are reserved for future use.
*/
typedef uint32_t psa_key_id_t;
#define PSA_KEY_ID_INIT 0
/**@}*/
/** \defgroup policy Key policies
* @{
*/
/** \brief Encoding of permitted usage on a key. */
typedef uint32_t psa_key_usage_t;
/**@}*/
/** \defgroup attributes Key attributes
* @{
*/
/** The type of a structure containing key attributes.
*
* This is an opaque structure that can represent the metadata of a key
* object. Metadata that can be stored in attributes includes:
* - The location of the key in storage, indicated by its key identifier
* and its lifetime.
* - The key's policy, comprising usage flags and a specification of
* the permitted algorithm(s).
* - Information about the key itself: the key type and its size.
* - Implementations may define additional attributes.
*
* The actual key material is not considered an attribute of a key.
* Key attributes do not contain information that is generally considered
* highly confidential.
*
* An attribute structure can be a simple data structure where each function
* `psa_set_key_xxx` sets a field and the corresponding function
* `psa_get_key_xxx` retrieves the value of the corresponding field.
* However, implementations may report values that are equivalent to the
* original one, but have a different encoding. For example, an
* implementation may use a more compact representation for types where
* many bit-patterns are invalid or not supported, and store all values
* that it does not support as a special marker value. In such an
* implementation, after setting an invalid value, the corresponding
* get function returns an invalid value which may not be the one that
* was originally stored.
*
* An attribute structure may contain references to auxiliary resources,
* for example pointers to allocated memory or indirect references to
* pre-calculated values. In order to free such resources, the application
* must call psa_reset_key_attributes(). As an exception, calling
* psa_reset_key_attributes() on an attribute structure is optional if
* the structure has only been modified by the following functions
* since it was initialized or last reset with psa_reset_key_attributes():
* - psa_set_key_id()
* - psa_set_key_lifetime()
* - psa_set_key_type()
* - psa_set_key_bits()
* - psa_set_key_usage_flags()
* - psa_set_key_algorithm()
*
* Before calling any function on a key attribute structure, the application
* must initialize it by any of the following means:
* - Set the structure to all-bits-zero, for example:
* \code
* psa_key_attributes_t attributes;
* memset(&attributes, 0, sizeof(attributes));
* \endcode
* - Initialize the structure to logical zero values, for example:
* \code
* psa_key_attributes_t attributes = {0};
* \endcode
* - Initialize the structure to the initializer #PSA_KEY_ATTRIBUTES_INIT,
* for example:
* \code
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
* \endcode
* - Assign the result of the function psa_key_attributes_init()
* to the structure, for example:
* \code
* psa_key_attributes_t attributes;
* attributes = psa_key_attributes_init();
* \endcode
*
* A freshly initialized attribute structure contains the following
* values:
*
* - lifetime: #PSA_KEY_LIFETIME_VOLATILE.
* - key identifier: 0 (which is not a valid key identifier).
* - type: \c 0 (meaning that the type is unspecified).
* - key size: \c 0 (meaning that the size is unspecified).
* - usage flags: \c 0 (which allows no usage except exporting a public key).
* - algorithm: \c 0 (which allows no cryptographic usage, but allows
* exporting).
*
* A typical sequence to create a key is as follows:
* -# Create and initialize an attribute structure.
* -# If the key is persistent, call psa_set_key_id().
* Also call psa_set_key_lifetime() to place the key in a non-default
* location.
* -# Set the key policy with psa_set_key_usage_flags() and
* psa_set_key_algorithm().
* -# Set the key type with psa_set_key_type().
* Skip this step if copying an existing key with psa_copy_key().
* -# When generating a random key with psa_generate_key() or deriving a key
* with psa_key_derivation_output_key(), set the desired key size with
* psa_set_key_bits().
* -# Call a key creation function: psa_import_key(), psa_generate_key(),
* psa_key_derivation_output_key() or psa_copy_key(). This function reads
* the attribute structure, creates a key with these attributes, and
* outputs a handle to the newly created key.
* -# The attribute structure is now no longer necessary.
* You may call psa_reset_key_attributes(), although this is optional
* with the workflow presented here because the attributes currently
* defined in this specification do not require any additional resources
* beyond the structure itself.
*
* A typical sequence to query a key's attributes is as follows:
* -# Call psa_get_key_attributes().
* -# Call `psa_get_key_xxx` functions to retrieve the attribute(s) that
* you are interested in.
* -# Call psa_reset_key_attributes() to free any resources that may be
* used by the attribute structure.
*
* Once a key has been created, it is impossible to change its attributes.
*/
typedef struct psa_key_attributes_s psa_key_attributes_t;
/**@}*/
/** \defgroup derivation Key derivation
* @{
*/
/** \brief Encoding of the step of a key derivation. */
typedef uint16_t psa_key_derivation_step_t;
/**@}*/
#endif /* PSA_CRYPTO_TYPES_H */

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/*********** WARNING: This is an auto-generated file. Do not edit! ***********/
#ifndef __PSA_MANIFEST_SID_H__
#define __PSA_MANIFEST_SID_H__
#ifdef __cplusplus
extern "C" {
#endif
/******** TFM_SP_STORAGE ********/
#define TFM_SST_SET_SID (0x00000060U)
#define TFM_SST_SET_VERSION (1U)
#define TFM_SST_GET_SID (0x00000061U)
#define TFM_SST_GET_VERSION (1U)
#define TFM_SST_GET_INFO_SID (0x00000062U)
#define TFM_SST_GET_INFO_VERSION (1U)
#define TFM_SST_REMOVE_SID (0x00000063U)
#define TFM_SST_REMOVE_VERSION (1U)
#define TFM_SST_GET_SUPPORT_SID (0x00000064U)
#define TFM_SST_GET_SUPPORT_VERSION (1U)
/******** TFM_SP_ITS ********/
#define TFM_ITS_SET_SID (0x00000070U)
#define TFM_ITS_SET_VERSION (1U)
#define TFM_ITS_GET_SID (0x00000071U)
#define TFM_ITS_GET_VERSION (1U)
#define TFM_ITS_GET_INFO_SID (0x00000072U)
#define TFM_ITS_GET_INFO_VERSION (1U)
#define TFM_ITS_REMOVE_SID (0x00000073U)
#define TFM_ITS_REMOVE_VERSION (1U)
/******** TFM_SP_CRYPTO ********/
#define TFM_CRYPTO_SID (0x00000080U)
#define TFM_CRYPTO_VERSION (1U)
/******** TFM_SP_PLATFORM ********/
#define TFM_SP_PLATFORM_SYSTEM_RESET_SID (0x00000040U)
#define TFM_SP_PLATFORM_SYSTEM_RESET_VERSION (1U)
#define TFM_SP_PLATFORM_IOCTL_SID (0x00000041U)
#define TFM_SP_PLATFORM_IOCTL_VERSION (1U)
#define TFM_SP_PLATFORM_NV_COUNTER_SID (0x00000042U)
#define TFM_SP_PLATFORM_NV_COUNTER_VERSION (1U)
/******** TFM_SP_INITIAL_ATTESTATION ********/
#define TFM_ATTEST_GET_TOKEN_SID (0x00000020U)
#define TFM_ATTEST_GET_TOKEN_VERSION (1U)
#define TFM_ATTEST_GET_TOKEN_SIZE_SID (0x00000021U)
#define TFM_ATTEST_GET_TOKEN_SIZE_VERSION (1U)
#define TFM_ATTEST_GET_PUBLIC_KEY_SID (0x00000022U)
#define TFM_ATTEST_GET_PUBLIC_KEY_VERSION (1U)
/******** TFM_SP_CORE_TEST ********/
#define SPM_CORE_TEST_INIT_SUCCESS_SID (0x0000F020U)
#define SPM_CORE_TEST_INIT_SUCCESS_VERSION (1U)
#define SPM_CORE_TEST_DIRECT_RECURSION_SID (0x0000F021U)
#define SPM_CORE_TEST_DIRECT_RECURSION_VERSION (1U)
#define SPM_CORE_TEST_MPU_ACCESS_SID (0x0000F022U)
#define SPM_CORE_TEST_MPU_ACCESS_VERSION (1U)
#define SPM_CORE_TEST_MEMORY_PERMISSIONS_SID (0x0000F023U)
#define SPM_CORE_TEST_MEMORY_PERMISSIONS_VERSION (1U)
#define SPM_CORE_TEST_SS_TO_SS_SID (0x0000F024U)
#define SPM_CORE_TEST_SS_TO_SS_VERSION (1U)
#define SPM_CORE_TEST_SS_TO_SS_BUFFER_SID (0x0000F025U)
#define SPM_CORE_TEST_SS_TO_SS_BUFFER_VERSION (1U)
#define SPM_CORE_TEST_OUTVEC_WRITE_SID (0x0000F026U)
#define SPM_CORE_TEST_OUTVEC_WRITE_VERSION (1U)
#define SPM_CORE_TEST_PERIPHERAL_ACCESS_SID (0x0000F027U)
#define SPM_CORE_TEST_PERIPHERAL_ACCESS_VERSION (1U)
#define SPM_CORE_TEST_GET_CALLER_CLIENT_ID_SID (0x0000F028U)
#define SPM_CORE_TEST_GET_CALLER_CLIENT_ID_VERSION (1U)
#define SPM_CORE_TEST_SPM_REQUEST_SID (0x0000F029U)
#define SPM_CORE_TEST_SPM_REQUEST_VERSION (1U)
#define SPM_CORE_TEST_BLOCK_SID (0x0000F02AU)
#define SPM_CORE_TEST_BLOCK_VERSION (1U)
#define SPM_CORE_TEST_NS_THREAD_SID (0x0000F02BU)
#define SPM_CORE_TEST_NS_THREAD_VERSION (1U)
/******** TFM_SP_CORE_TEST_2 ********/
#define SPM_CORE_TEST_2_SLAVE_SERVICE_SID (0x0000F040U)
#define SPM_CORE_TEST_2_SLAVE_SERVICE_VERSION (1U)
#define SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SID (0x0000F041U)
#define SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_VERSION (1U)
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID (0x0000F042U)
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_VERSION (1U)
#define SPM_CORE_TEST_2_INVERT_SID (0x0000F043U)
#define SPM_CORE_TEST_2_INVERT_VERSION (1U)
#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SID (0x0000F044U)
#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_VERSION (1U)
#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SID (0x0000F045U)
#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_VERSION (1U)
/******** TFM_SP_SECURE_TEST_PARTITION ********/
#define TFM_SECURE_CLIENT_SFN_RUN_TESTS_SID (0x0000F000U)
#define TFM_SECURE_CLIENT_SFN_RUN_TESTS_VERSION (1U)
/******** TFM_SP_IPC_SERVICE_TEST ********/
#define IPC_SERVICE_TEST_BASIC_SID (0x0000F080U)
#define IPC_SERVICE_TEST_BASIC_VERSION (1U)
#define IPC_SERVICE_TEST_PSA_ACCESS_APP_MEM_SID (0x0000F081U)
#define IPC_SERVICE_TEST_PSA_ACCESS_APP_MEM_VERSION (1U)
#define IPC_SERVICE_TEST_PSA_ACCESS_APP_READ_ONLY_MEM_SID (0x0000F082U)
#define IPC_SERVICE_TEST_PSA_ACCESS_APP_READ_ONLY_MEM_VERSION (1U)
#define IPC_SERVICE_TEST_APP_ACCESS_PSA_MEM_SID (0x0000F083U)
#define IPC_SERVICE_TEST_APP_ACCESS_PSA_MEM_VERSION (1U)
#define IPC_SERVICE_TEST_CLIENT_PROGRAMMER_ERROR_SID (0x0000F084U)
#define IPC_SERVICE_TEST_CLIENT_PROGRAMMER_ERROR_VERSION (1U)
/******** TFM_SP_IPC_CLIENT_TEST ********/
#define IPC_CLIENT_TEST_BASIC_SID (0x0000F060U)
#define IPC_CLIENT_TEST_BASIC_VERSION (1U)
#define IPC_CLIENT_TEST_PSA_ACCESS_APP_MEM_SID (0x0000F061U)
#define IPC_CLIENT_TEST_PSA_ACCESS_APP_MEM_VERSION (1U)
#define IPC_CLIENT_TEST_PSA_ACCESS_APP_READ_ONLY_MEM_SID (0x0000F062U)
#define IPC_CLIENT_TEST_PSA_ACCESS_APP_READ_ONLY_MEM_VERSION (1U)
#define IPC_CLIENT_TEST_APP_ACCESS_PSA_MEM_SID (0x0000F063U)
#define IPC_CLIENT_TEST_APP_ACCESS_PSA_MEM_VERSION (1U)
#define IPC_CLIENT_TEST_MEM_CHECK_SID (0x0000F064U)
#define IPC_CLIENT_TEST_MEM_CHECK_VERSION (1U)
/******** TFM_IRQ_TEST_1 ********/
#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SID (0x0000F0A0U)
#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_VERSION (1U)
#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SID (0x0000F0A1U)
#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_VERSION (1U)
/******** TFM_SP_SST_TEST ********/
#define TFM_SST_TEST_PREPARE_SID (0x0000F0C0U)
#define TFM_SST_TEST_PREPARE_VERSION (1U)
/******** TFM_SP_SECURE_CLIENT_2 ********/
#define TFM_SECURE_CLIENT_2_SID (0x0000F0E0U)
#define TFM_SECURE_CLIENT_2_VERSION (1U)
/******** TFM_SP_MULTI_CORE_TEST ********/
#define MULTI_CORE_MULTI_CLIENT_CALL_TEST_0_SID (0x0000F100U)
#define MULTI_CORE_MULTI_CLIENT_CALL_TEST_0_VERSION (1U)
#define MULTI_CORE_MULTI_CLIENT_CALL_TEST_1_SID (0x0000F101U)
#define MULTI_CORE_MULTI_CLIENT_CALL_TEST_1_VERSION (1U)
#ifdef __cplusplus
}
#endif
#endif /* __PSA_MANIFEST_SID_H__ */

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __TFM_CRYPTO_DEFS_H__
#define __TFM_CRYPTO_DEFS_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <limits.h>
#include "tfm_api.h"
#include "psa/crypto.h"
/**
* \brief This type is used to overcome a limitation in the number of maximum
* IOVECs that can be used especially in psa_aead_encrypt and
* psa_aead_decrypt. To be removed in case the AEAD APIs number of
* parameters passed gets restructured
*/
#define TFM_CRYPTO_MAX_NONCE_LENGTH (16u)
struct tfm_crypto_aead_pack_input {
uint8_t nonce[TFM_CRYPTO_MAX_NONCE_LENGTH];
uint32_t nonce_length;
};
/**
* \brief Structure used to pack non-pointer types in a call
*
*/
struct tfm_crypto_pack_iovec {
uint32_t sfn_id; /*!< Secure function ID used to dispatch the
* request
*/
uint16_t step; /*!< Key derivation step */
psa_key_handle_t key_handle; /*!< Key handle */
psa_algorithm_t alg; /*!< Algorithm */
uint32_t op_handle; /*!< Frontend context handle associated to a
* multipart operation
*/
size_t capacity; /*!< Key derivation capacity */
struct tfm_crypto_aead_pack_input aead_in; /*!< FixMe: Temporarily used for
* AEAD until the API is
* restructured
*/
};
/**
* \brief Define a progressive numerical value for each SID which can be used
* when dispatching the requests to the service
*/
enum {
TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID = (0u),
TFM_CRYPTO_RESET_KEY_ATTRIBUTES_SID,
TFM_CRYPTO_OPEN_KEY_SID,
TFM_CRYPTO_CLOSE_KEY_SID,
TFM_CRYPTO_IMPORT_KEY_SID,
TFM_CRYPTO_DESTROY_KEY_SID,
TFM_CRYPTO_EXPORT_KEY_SID,
TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID,
TFM_CRYPTO_COPY_KEY_SID,
TFM_CRYPTO_HASH_COMPUTE_SID,
TFM_CRYPTO_HASH_COMPARE_SID,
TFM_CRYPTO_HASH_SETUP_SID,
TFM_CRYPTO_HASH_UPDATE_SID,
TFM_CRYPTO_HASH_FINISH_SID,
TFM_CRYPTO_HASH_VERIFY_SID,
TFM_CRYPTO_HASH_ABORT_SID,
TFM_CRYPTO_HASH_CLONE_SID,
TFM_CRYPTO_MAC_COMPUTE_SID,
TFM_CRYPTO_MAC_VERIFY_SID,
TFM_CRYPTO_MAC_SIGN_SETUP_SID,
TFM_CRYPTO_MAC_VERIFY_SETUP_SID,
TFM_CRYPTO_MAC_UPDATE_SID,
TFM_CRYPTO_MAC_SIGN_FINISH_SID,
TFM_CRYPTO_MAC_VERIFY_FINISH_SID,
TFM_CRYPTO_MAC_ABORT_SID,
TFM_CRYPTO_CIPHER_ENCRYPT_SID,
TFM_CRYPTO_CIPHER_DECRYPT_SID,
TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID,
TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID,
TFM_CRYPTO_CIPHER_GENERATE_IV_SID,
TFM_CRYPTO_CIPHER_SET_IV_SID,
TFM_CRYPTO_CIPHER_UPDATE_SID,
TFM_CRYPTO_CIPHER_FINISH_SID,
TFM_CRYPTO_CIPHER_ABORT_SID,
TFM_CRYPTO_AEAD_ENCRYPT_SID,
TFM_CRYPTO_AEAD_DECRYPT_SID,
TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID,
TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID,
TFM_CRYPTO_AEAD_GENERATE_NONCE_SID,
TFM_CRYPTO_AEAD_SET_NONCE_SID,
TFM_CRYPTO_AEAD_SET_LENGTHS_SID,
TFM_CRYPTO_AEAD_UPDATE_AD_SID,
TFM_CRYPTO_AEAD_UPDATE_SID,
TFM_CRYPTO_AEAD_FINISH_SID,
TFM_CRYPTO_AEAD_VERIFY_SID,
TFM_CRYPTO_AEAD_ABORT_SID,
TFM_CRYPTO_SIGN_HASH_SID,
TFM_CRYPTO_VERIFY_HASH_SID,
TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SID,
TFM_CRYPTO_ASYMMETRIC_DECRYPT_SID,
TFM_CRYPTO_KEY_DERIVATION_SETUP_SID,
TFM_CRYPTO_KEY_DERIVATION_GET_CAPACITY_SID,
TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY_SID,
TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES_SID,
TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY_SID,
TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_SID,
TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES_SID,
TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY_SID,
TFM_CRYPTO_KEY_DERIVATION_ABORT_SID,
TFM_CRYPTO_RAW_KEY_AGREEMENT_SID,
TFM_CRYPTO_GENERATE_RANDOM_SID,
TFM_CRYPTO_GENERATE_KEY_SID,
TFM_CRYPTO_SET_KEY_DOMAIN_PARAMETERS_SID,
TFM_CRYPTO_GET_KEY_DOMAIN_PARAMETERS_SID,
TFM_CRYPTO_SID_MAX,
};
/**
* \brief Define an invalid value for an SID
*
*/
#define TFM_CRYPTO_SID_INVALID (~0x0u)
/**
* \brief This value is used to mark an handle as invalid.
*
*/
#define TFM_CRYPTO_INVALID_HANDLE (0x0u)
/**
* \brief The persistent key identifier that refers to the hardware unique key.
*
*/
#define TFM_CRYPTO_KEY_ID_HUK (0xFFFF815Bu)
/**
* \brief The algorithm identifier that refers to key derivation from the
* hardware unique key.
*
*/
#define TFM_CRYPTO_ALG_HUK_DERIVATION ((psa_algorithm_t)0xB0000F00)
/**
* \brief Define miscellaneous literal constants that are used in the service
*
*/
enum {
TFM_CRYPTO_NOT_IN_USE = 0,
TFM_CRYPTO_IN_USE = 1
};
#ifdef __cplusplus
}
#endif
#endif /* __TFM_CRYPTO_DEFS_H__ */

View File

@ -0,0 +1,236 @@
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/* Data types and API definitions in NSPE mailbox library */
#ifndef __TFM_NS_MAILBOX_H__
#define __TFM_NS_MAILBOX_H__
#include <stdbool.h>
#include <stdint.h>
#include "tfm_mailbox.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef TFM_MULTI_CORE_TEST
/**
* \brief The structure to hold the statistics result of NSPE mailbox
*/
struct ns_mailbox_stats_res_t {
uint8_t avg_nr_slots; /* The value before the decimal point
* in the average number of NSPE
* mailbox slots in use.
*/
uint8_t avg_nr_slots_tenths; /* The first digit value after the
* decimal point in the average
* number of NSPE mailbox slots in use.
*/
};
#endif
/**
* \brief Prepare and send PSA client request to SPE via mailbox.
*
* \param[in] call_type PSA client call type
* \param[in] params Parmaters used for PSA client call
* \param[in] client_id Optional client ID of non-secure caller.
* It is required to identify the non-secure caller
* when NSPE OS enforces non-secure task isolation.
*
* \retval >= 0 The handle to the mailbox message assigned.
* \retval < 0 Operation failed with an error code.
*/
mailbox_msg_handle_t tfm_ns_mailbox_tx_client_req(uint32_t call_type,
const struct psa_client_params_t *params,
int32_t client_id);
/**
* \brief Fetch PSA client return result.
*
* \param[in] handle The handle to the mailbox message
* \param[out] reply The address to be written with return result.
*
* \retval MAILBOX_SUCCESS Successfully get PSA client call return result.
* \retval Other return code Operation failed with an error code.
*/
int32_t tfm_ns_mailbox_rx_client_reply(mailbox_msg_handle_t handle,
int32_t *reply);
/**
* \brief Check whether a specific mailbox message has been replied.
*
* \param[in] handle The handle to the mailbox message
*
* \retval true The PSA client call return value is replied.
* \retval false The PSA client call return value is not
* replied yet.
*/
bool tfm_ns_mailbox_is_msg_replied(mailbox_msg_handle_t handle);
/**
* \brief NSPE mailbox initialization
*
* \param[in] queue The base address of NSPE mailbox queue to be
* initialized.
*
* \retval MAILBOX_SUCCESS Operation succeeded.
* \retval Other return code Operation failed with an error code.
*/
int32_t tfm_ns_mailbox_init(struct ns_mailbox_queue_t *queue);
#ifdef TFM_MULTI_CORE_MULTI_CLIENT_CALL
/**
* \brief Get the handle of the current non-secure task executing mailbox
* functionalities
*
* \note This function should be implemented according to platform, NS OS
* and actual use scenario.
* This function can be ignored or return NULL if sleep/wake-up mechanism
* is not required in PSA Client API implementation.
*
* \return Return the handle of task.
*/
const void *tfm_ns_mailbox_get_task_handle(void);
#else
static inline const void *tfm_ns_mailbox_get_task_handle(void)
{
return NULL;
}
#endif
/**
* \brief Fetch the handle to the first replied mailbox message in the NSPE
* mailbox queue.
* This function is intended to be called inside platform specific
* notification IRQ handler.
*
* \note The replied status of the fetched mailbox message will be cleaned after
* the message is fetched. When this function is called again, it fetches
* the next replied mailbox message from the NSPE mailbox queue.
*
* \return Return the handle to the first replied mailbox message in the
* queue.
* Return \ref MAILBOX_MSG_NULL_HANDLE if no mailbox message is replied.
*/
mailbox_msg_handle_t tfm_ns_mailbox_fetch_reply_msg_isr(void);
/**
* \brief Return the handle of owner task of a mailbox message according to the
* \ref mailbox_msg_handle_t
*
* \param[in] handle The handle of mailbox message.
*
* \return Return the handle value of the owner task.
*/
const void *tfm_ns_mailbox_get_msg_owner(mailbox_msg_handle_t handle);
#ifdef TFM_MULTI_CORE_MULTI_CLIENT_CALL
/**
* \brief Wait for the reply returned from SPE to the mailbox message specified
* by handle
*
* \param[in] handle The handle of mailbox message.
*
* \retval MAILBOX_SUCCESS Return from waiting successfully.
* \retval Other return code Failed to wait with an error code.
*/
int32_t tfm_ns_mailbox_wait_reply(mailbox_msg_handle_t handle);
#endif
/**
* \brief Platform specific NSPE mailbox initialization.
* Invoked by \ref tfm_ns_mailbox_init().
*
* \param[in] queue The base address of NSPE mailbox queue to be
* initialized.
*
* \retval MAILBOX_SUCCESS Operation succeeded.
* \retval Other return code Operation failed with an error code.
*/
int32_t tfm_ns_mailbox_hal_init(struct ns_mailbox_queue_t *queue);
/**
* \brief Notify SPE to deal with the PSA client call sent via mailbox
*
* \note The implementation depends on platform specific hardware and use case.
*
* \retval MAILBOX_SUCCESS Operation succeeded.
* \retval Other return code Operation failed with an error code.
*/
int32_t tfm_ns_mailbox_hal_notify_peer(void);
/**
* \brief Enter critical section of NSPE mailbox.
*
* \note The implementation depends on platform specific hardware and use case.
*/
void tfm_ns_mailbox_hal_enter_critical(void);
/**
* \brief Exit critical section of NSPE mailbox.
*
* \note The implementation depends on platform specific hardware and use case.
*/
void tfm_ns_mailbox_hal_exit_critical(void);
/**
* \brief Enter critical section of NSPE mailbox in IRQ handler.
*
* \note The implementation depends on platform specific hardware and use case.
*/
void tfm_ns_mailbox_hal_enter_critical_isr(void);
/**
* \brief Enter critical section of NSPE mailbox in IRQ handler
*
* \note The implementation depends on platform specific hardware and use case.
*/
void tfm_ns_mailbox_hal_exit_critical_isr(void);
#ifdef TFM_MULTI_CORE_MULTI_CLIENT_CALL
/**
* \brief Performs platform and NS OS specific waiting mechanism to wait for
* the reply of the specified mailbox message to be returned from SPE.
*
* \note This function is implemented by platform and NS OS specific waiting
* mechanism accroding to use scenario.
*
* \param[in] handle The handle of mailbox message.
*/
void tfm_ns_mailbox_hal_wait_reply(mailbox_msg_handle_t handle);
#endif
#ifdef TFM_MULTI_CORE_TEST
/**
* \brief Initialize the statistics module in TF-M NSPE mailbox.
*
* \note This function is only available when multi-core tests are enabled.
*/
void tfm_ns_mailbox_tx_stats_init(void);
/**
* \brief Calculate the average number of used NS mailbox queue slots each time
* NS task requires a queue slot to submit mailbox message, which is
* recorded in NS mailbox statisitics module.
*
* \note This function is only available when multi-core tests are enabled.
*
* \param[in] stats_res The buffer to be written with
* \ref ns_mailbox_stats_res_t.
*
* \return Return the calculation result.
*/
void tfm_ns_mailbox_stats_avg_slot(struct ns_mailbox_stats_res_t *stats_res);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __TFM_NS_MAILBOX_H__ */

View File

@ -0,0 +1,180 @@
/*
* Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/*********** WARNING: This is an auto-generated file. Do not edit! ***********/
#ifndef __TFM_VENEERS_H__
#define __TFM_VENEERS_H__
#include "tfm_api.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef TFM_PARTITION_SECURE_STORAGE
/******** TFM_SP_STORAGE ********/
psa_status_t tfm_tfm_sst_set_req_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_sst_get_req_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_sst_get_info_req_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_sst_remove_req_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_sst_get_support_req_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_SECURE_STORAGE */
#ifdef TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
/******** TFM_SP_ITS ********/
psa_status_t tfm_tfm_its_set_req_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_its_get_req_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_its_get_info_req_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_its_remove_req_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_INTERNAL_TRUSTED_STORAGE */
#ifdef TFM_PARTITION_AUDIT_LOG
/******** TFM_SP_AUDIT_LOG ********/
psa_status_t tfm_audit_core_retrieve_record_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_audit_core_add_record_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_audit_core_get_info_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_audit_core_get_record_info_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_audit_core_delete_record_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_AUDIT_LOG */
#ifdef TFM_PARTITION_CRYPTO
/******** TFM_SP_CRYPTO ********/
psa_status_t tfm_tfm_crypto_get_key_attributes_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_open_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_close_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_reset_key_attributes_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_import_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_destroy_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_export_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_export_public_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_copy_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_hash_compute_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_hash_compare_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_hash_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_hash_update_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_hash_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_hash_verify_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_hash_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_hash_clone_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_compute_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_verify_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_sign_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_verify_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_update_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_sign_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_verify_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_mac_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_encrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_decrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_encrypt_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_decrypt_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_generate_iv_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_set_iv_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_update_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_cipher_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_encrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_decrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_encrypt_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_decrypt_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_generate_nonce_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_set_nonce_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_set_lengths_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_update_ad_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_update_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_verify_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_aead_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_sign_hash_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_verify_hash_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_asymmetric_encrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_asymmetric_decrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_key_derivation_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_key_derivation_get_capacity_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_key_derivation_set_capacity_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_key_derivation_input_bytes_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_key_derivation_input_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_key_derivation_key_agreement_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_key_derivation_output_bytes_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_key_derivation_output_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_key_derivation_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_raw_key_agreement_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_generate_random_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_tfm_crypto_generate_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_CRYPTO */
#ifdef TFM_PARTITION_PLATFORM
/******** TFM_SP_PLATFORM ********/
psa_status_t tfm_platform_sp_system_reset_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_platform_sp_ioctl_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_platform_sp_nv_counter_read_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_platform_sp_nv_counter_increment_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_PLATFORM */
#ifdef TFM_PARTITION_INITIAL_ATTESTATION
/******** TFM_SP_INITIAL_ATTESTATION ********/
psa_status_t tfm_initial_attest_get_token_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_initial_attest_get_token_size_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_initial_attest_get_public_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_INITIAL_ATTESTATION */
#ifdef TFM_PARTITION_TEST_CORE
/******** TFM_SP_CORE_TEST ********/
psa_status_t tfm_spm_core_test_sfn_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_spm_core_test_sfn_init_success_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_spm_core_test_sfn_direct_recursion_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_TEST_CORE */
#ifdef TFM_PARTITION_TEST_CORE
/******** TFM_SP_CORE_TEST_2 ********/
psa_status_t tfm_spm_core_test_2_slave_service_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_spm_core_test_2_sfn_invert_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_spm_core_test_2_check_caller_client_id_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_spm_core_test_2_get_every_second_byte_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_spm_core_test_2_prepare_test_scenario_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_spm_core_test_2_execute_test_scenario_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_TEST_CORE */
#ifdef TFM_PARTITION_TEST_SECURE_SERVICES
/******** TFM_SP_SECURE_TEST_PARTITION ********/
psa_status_t tfm_tfm_secure_client_service_sfn_run_tests_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_TEST_SECURE_SERVICES */
#ifdef TFM_PARTITION_TEST_CORE_IPC
/******** TFM_SP_IPC_SERVICE_TEST ********/
#endif /* TFM_PARTITION_TEST_CORE_IPC */
#ifdef TFM_PARTITION_TEST_CORE_IPC
/******** TFM_SP_IPC_CLIENT_TEST ********/
#endif /* TFM_PARTITION_TEST_CORE_IPC */
#ifdef TFM_ENABLE_IRQ_TEST
/******** TFM_IRQ_TEST_1 ********/
psa_status_t tfm_spm_irq_test_1_prepare_test_scenario_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_spm_irq_test_1_execute_test_scenario_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_ENABLE_IRQ_TEST */
#ifdef TFM_PARTITION_TEST_SST
/******** TFM_SP_SST_TEST ********/
psa_status_t tfm_tfm_sst_test_prepare_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_TEST_SST */
#ifdef TFM_PARTITION_TEST_SECURE_SERVICES
/******** TFM_SP_SECURE_CLIENT_2 ********/
psa_status_t tfm_tfm_secure_client_2_call_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_TEST_SECURE_SERVICES */
#ifdef TFM_MULTI_CORE_TEST
/******** TFM_SP_MULTI_CORE_TEST ********/
#endif /* TFM_MULTI_CORE_TEST */
#ifdef __cplusplus
}
#endif
#endif /* __TFM_VENEERS_H__ */

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) 2017-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "psa/protected_storage.h"
#include "tfm_ns_interface.h"
#include "psa_manifest/sid.h"
#define IOVEC_LEN(x) (uint32_t)(sizeof(x)/sizeof(x[0]))
psa_status_t psa_ps_set(psa_storage_uid_t uid,
size_t data_length,
const void *p_data,
psa_storage_create_flags_t create_flags)
{
psa_status_t status;
psa_handle_t handle;
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) },
{ .base = p_data, .len = data_length },
{ .base = &create_flags, .len = sizeof(create_flags) }
};
handle = psa_connect(TFM_SST_SET_SID, TFM_SST_SET_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_ERROR_GENERIC_ERROR;
}
status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec),
NULL, 0);
psa_close(handle);
/* A parameter with a buffer pointer pointer that has data length longer
* than maximum permitted is treated as a secure violation.
* TF-M framework rejects the request with TFM_ERROR_INVALID_PARAMETER.
*/
if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return status;
}
psa_status_t psa_ps_get(psa_storage_uid_t uid,
size_t data_offset,
size_t data_size,
void *p_data,
size_t *p_data_length)
{
psa_status_t status;
psa_handle_t handle;
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) },
{ .base = &data_offset, .len = sizeof(data_offset) }
};
psa_outvec out_vec[] = {
{ .base = p_data, .len = data_size }
};
if (p_data_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
handle = psa_connect(TFM_SST_GET_SID, TFM_SST_GET_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_ERROR_GENERIC_ERROR;
}
status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), out_vec,
IOVEC_LEN(out_vec));
psa_close(handle);
*p_data_length = out_vec[0].len;
return status;
}
psa_status_t psa_ps_get_info(psa_storage_uid_t uid,
struct psa_storage_info_t *p_info)
{
psa_status_t status;
psa_handle_t handle;
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) }
};
psa_outvec out_vec[] = {
{ .base = p_info, .len = sizeof(*p_info) }
};
handle = psa_connect(TFM_SST_GET_INFO_SID, TFM_SST_GET_INFO_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_ERROR_GENERIC_ERROR;
}
status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), out_vec,
IOVEC_LEN(out_vec));
psa_close(handle);
return status;
}
psa_status_t psa_ps_remove(psa_storage_uid_t uid)
{
psa_status_t status;
psa_handle_t handle;
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) }
};
handle = psa_connect(TFM_SST_REMOVE_SID, TFM_SST_REMOVE_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_ERROR_GENERIC_ERROR;
}
status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec),
NULL, 0);
psa_close(handle);
return status;
}
psa_status_t psa_ps_create(psa_storage_uid_t uid, size_t size,
psa_storage_create_flags_t create_flags)
{
(void)uid;
(void)size;
(void)create_flags;
return PSA_ERROR_NOT_SUPPORTED;
}
psa_status_t psa_ps_set_extended(psa_storage_uid_t uid, size_t data_offset,
size_t data_length, const void *p_data)
{
(void)uid;
(void)data_offset;
(void)data_length;
(void)p_data;
return PSA_ERROR_NOT_SUPPORTED;
}
uint32_t psa_ps_get_support(void)
{
/* Initialise support_flags to a sensible default, to avoid returning an
* uninitialised value in case the secure function fails.
*/
uint32_t support_flags = 0;
psa_handle_t handle;
psa_outvec out_vec[] = {
{ .base = &support_flags, .len = sizeof(support_flags) }
};
/* The PSA API does not return an error, so any error from TF-M is
* ignored.
*/
handle = psa_connect(TFM_SST_GET_SUPPORT_SID, TFM_SST_GET_SUPPORT_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return support_flags;
}
(void)psa_call(handle, PSA_IPC_CALL, NULL, 0, out_vec, IOVEC_LEN(out_vec));
psa_close(handle);
return support_flags;
}

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2019 Arm Limited. All rights reserved.
* Copyright (c) 2019 Cypress Semiconductor Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "cmsis_compiler.h"
#include "platform_multicore.h"
#include "tfm_multi_core_api.h"
#include "tfm_ns_mailbox.h"
#include "cy_ipc_drv.h"
#include "cy_sysint.h"
#if CY_SYSTEM_CPU_CM0P
#include "spe_ipc_config.h"
#else
#include "ns_ipc_config.h"
#endif
int platform_mailbox_fetch_msg_ptr(void **msg_ptr)
{
cy_en_ipcdrv_status_t status;
if (!msg_ptr) {
return PLATFORM_MAILBOX_INVAL_PARAMS;
}
status = Cy_IPC_Drv_ReadMsgPtr(Cy_IPC_Drv_GetIpcBaseAddress(IPC_RX_CHAN),
msg_ptr);
if (status != CY_IPC_DRV_SUCCESS) {
return PLATFORM_MAILBOX_RX_ERROR;
}
Cy_IPC_Drv_ReleaseNotify(Cy_IPC_Drv_GetIpcBaseAddress(IPC_RX_CHAN),
IPC_RX_RELEASE_MASK);
return PLATFORM_MAILBOX_SUCCESS;
}
int platform_mailbox_fetch_msg_data(uint32_t *data_ptr)
{
cy_en_ipcdrv_status_t status;
if (!data_ptr) {
return PLATFORM_MAILBOX_INVAL_PARAMS;
}
status = Cy_IPC_Drv_ReadMsgWord(Cy_IPC_Drv_GetIpcBaseAddress(IPC_RX_CHAN),
data_ptr);
if (status != CY_IPC_DRV_SUCCESS) {
return PLATFORM_MAILBOX_RX_ERROR;
}
Cy_IPC_Drv_ReleaseNotify(Cy_IPC_Drv_GetIpcBaseAddress(IPC_RX_CHAN),
IPC_RX_RELEASE_MASK);
return PLATFORM_MAILBOX_SUCCESS;
}
int platform_mailbox_send_msg_ptr(const void *msg_ptr)
{
cy_en_ipcdrv_status_t status;
if (!msg_ptr)
return PLATFORM_MAILBOX_INVAL_PARAMS;
status = Cy_IPC_Drv_SendMsgPtr(Cy_IPC_Drv_GetIpcBaseAddress(IPC_TX_CHAN),
IPC_TX_NOTIFY_MASK, msg_ptr);
if (status != CY_IPC_DRV_SUCCESS) {
return PLATFORM_MAILBOX_TX_ERROR;
}
return PLATFORM_MAILBOX_SUCCESS;
}
int platform_mailbox_send_msg_data(uint32_t data)
{
cy_en_ipcdrv_status_t status;
status = Cy_IPC_Drv_SendMsgWord(Cy_IPC_Drv_GetIpcBaseAddress(IPC_TX_CHAN),
IPC_TX_NOTIFY_MASK, data);
if (status != CY_IPC_DRV_SUCCESS) {
return PLATFORM_MAILBOX_TX_ERROR;
}
return PLATFORM_MAILBOX_SUCCESS;
}
void platform_mailbox_wait_for_notify(void)
{
uint32_t status;
while (1) {
status = Cy_IPC_Drv_GetInterruptStatusMasked(
Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT));
status >>= CY_IPC_NOTIFY_SHIFT;
if (status & IPC_RX_INT_MASK) {
break;
}
}
Cy_IPC_Drv_ClearInterrupt(Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT),
0, IPC_RX_INT_MASK);
}
int platform_ns_ipc_init(void)
{
Cy_IPC_Drv_SetInterruptMask(Cy_IPC_Drv_GetIntrBaseAddr(IPC_RX_INTR_STRUCT),
0, IPC_RX_INT_MASK);
return PLATFORM_MAILBOX_SUCCESS;
}
int32_t tfm_platform_ns_wait_for_s_cpu_ready(void)
{
uint32_t data = 0;
if (platform_ns_ipc_init() != PLATFORM_MAILBOX_SUCCESS) {
return PLATFORM_MAILBOX_INVAL_PARAMS;
}
while(data != IPC_SYNC_MAGIC)
{
platform_mailbox_wait_for_notify();
platform_mailbox_fetch_msg_data(&data);
}
if (platform_mailbox_send_msg_data(~IPC_SYNC_MAGIC) !=
PLATFORM_MAILBOX_SUCCESS) {
return PLATFORM_MAILBOX_RX_ERROR;
}
return PLATFORM_MAILBOX_SUCCESS;
}

View File

@ -0,0 +1,67 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_error.h"
#include "tfm_multi_core_api.h"
#include "tfm_ns_mailbox.h"
#include "platform_multicore.h"
#include "tfm_ns_interface.h"
static struct ns_mailbox_queue_t ns_mailbox_queue;
void mbed_tfm_init(void)
{
/*
* In case the of dual CPU, we need to initialize IPC, mailbox
* and NS interface after the RTOS has started to enable
* communication from Secure and Non-Secure cores.
*/
int32_t ret;
ret = tfm_ns_wait_for_s_cpu_ready();
/*
* Normally would expect "TFM_SUCCESS" returned here by TF-M, as this
* isn't a mailbox function. There may be some platforms other than PSoC6,
* which doesn't require tfm_ns_wait_for_s_cpu_ready() implementation.
* "PLATFORM_MAILBOX_SUCCESS" is a low-level error code and should be
* replaced by "TFM_SUCCESS".
* As the function definition has been imported from the TF-M, therefore
* a issue has been raised - https://developer.trustedfirmware.org/T660
*/
if (ret != PLATFORM_MAILBOX_SUCCESS) {
/* Avoid undefined behavior after multi-core sync-up failed */
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM,
MBED_ERROR_CODE_INITIALIZATION_FAILED),
"Failed to sync-up multi-core");
}
ret = tfm_ns_mailbox_init(&ns_mailbox_queue);
if (ret != MAILBOX_SUCCESS) {
/* Avoid undefined behavior after NS mailbox initialization failed */
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM,
MBED_ERROR_CODE_INITIALIZATION_FAILED),
"Failed to initialize NS mailbox");
}
ret = tfm_ns_interface_init();
if (ret != TFM_SUCCESS) {
/* Avoid undefined behavior after NS interface initialization failed */
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM,
MBED_ERROR_CODE_INITIALIZATION_FAILED),
"Failed to initialize NS interface");
}
}

View File

@ -0,0 +1,425 @@
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <string.h>
#include "tfm_ns_mailbox.h"
/* The pointer to NSPE mailbox queue */
static struct ns_mailbox_queue_t *mailbox_queue_ptr = NULL;
static inline void clear_queue_slot_empty(uint8_t idx)
{
if (idx < NUM_MAILBOX_QUEUE_SLOT) {
mailbox_queue_ptr->empty_slots &= ~(1 << idx);
}
}
static inline void set_queue_slot_empty(uint8_t idx)
{
if (idx < NUM_MAILBOX_QUEUE_SLOT) {
mailbox_queue_ptr->empty_slots |= (1 << idx);
}
}
static inline void set_queue_slot_pend(uint8_t idx)
{
if (idx < NUM_MAILBOX_QUEUE_SLOT) {
mailbox_queue_ptr->pend_slots |= (1 << idx);
}
}
static inline int32_t get_mailbox_msg_handle(uint8_t idx,
mailbox_msg_handle_t *handle)
{
if ((idx >= NUM_MAILBOX_QUEUE_SLOT) || !handle) {
return MAILBOX_INVAL_PARAMS;
}
*handle = (mailbox_msg_handle_t)(idx + 1);
return MAILBOX_SUCCESS;
}
static inline int32_t get_mailbox_msg_idx(mailbox_msg_handle_t handle,
uint8_t *idx)
{
if ((handle == MAILBOX_MSG_NULL_HANDLE) || !idx) {
return MAILBOX_INVAL_PARAMS;
}
*idx = (uint8_t)(handle - 1);
return MAILBOX_SUCCESS;
}
static inline void clear_queue_slot_replied(uint8_t idx)
{
if (idx < NUM_MAILBOX_QUEUE_SLOT) {
mailbox_queue_ptr->replied_slots &= ~(1 << idx);
}
}
static inline void set_queue_slot_woken(uint8_t idx)
{
if (idx < NUM_MAILBOX_QUEUE_SLOT) {
mailbox_queue_ptr->queue[idx].is_woken = true;
}
}
static inline bool is_queue_slot_woken(uint8_t idx)
{
if (idx < NUM_MAILBOX_QUEUE_SLOT) {
return mailbox_queue_ptr->queue[idx].is_woken;
}
return false;
}
static inline void clear_queue_slot_woken(uint8_t idx)
{
if (idx < NUM_MAILBOX_QUEUE_SLOT) {
mailbox_queue_ptr->queue[idx].is_woken = false;
}
}
static uint8_t acquire_empty_slot(const struct ns_mailbox_queue_t *queue)
{
uint8_t idx;
mailbox_queue_status_t status;
tfm_ns_mailbox_hal_enter_critical();
status = queue->empty_slots;
if (!status) {
/* No empty slot */
tfm_ns_mailbox_hal_exit_critical();
return NUM_MAILBOX_QUEUE_SLOT;
}
for (idx = 0; idx < NUM_MAILBOX_QUEUE_SLOT; idx++) {
if (status & (1 << idx)) {
break;
}
}
clear_queue_slot_empty(idx);
tfm_ns_mailbox_hal_exit_critical();
return idx;
}
static void set_msg_owner(uint8_t idx, const void *owner)
{
if (idx < NUM_MAILBOX_QUEUE_SLOT) {
mailbox_queue_ptr->queue[idx].owner = owner;
}
}
#ifdef TFM_MULTI_CORE_TEST
void tfm_ns_mailbox_tx_stats_init(void)
{
if (!mailbox_queue_ptr) {
return;
}
tfm_ns_mailbox_hal_enter_critical();
mailbox_queue_ptr->nr_tx = 0;
mailbox_queue_ptr->nr_used_slots = 0;
tfm_ns_mailbox_hal_exit_critical();
}
static void mailbox_tx_stats_update(struct ns_mailbox_queue_t *ns_queue)
{
mailbox_queue_status_t empty_status;
uint8_t idx, nr_empty = 0;
if (!ns_queue) {
return;
}
tfm_ns_mailbox_hal_enter_critical();
ns_queue->nr_tx++;
/* Count the number of used slots when this tx arrives */
empty_status = ns_queue->empty_slots;
tfm_ns_mailbox_hal_exit_critical();
if (empty_status) {
for (idx = 0; idx < NUM_MAILBOX_QUEUE_SLOT; idx++) {
if (empty_status & (0x1UL << idx)) {
nr_empty++;
}
}
}
tfm_ns_mailbox_hal_enter_critical();
ns_queue->nr_used_slots += (NUM_MAILBOX_QUEUE_SLOT - nr_empty);
tfm_ns_mailbox_hal_exit_critical();
}
void tfm_ns_mailbox_stats_avg_slot(struct ns_mailbox_stats_res_t *stats_res)
{
uint32_t nr_used_slots, nr_tx;
if (!mailbox_queue_ptr || !stats_res) {
return;
}
tfm_ns_mailbox_hal_enter_critical();
nr_used_slots = mailbox_queue_ptr->nr_used_slots;
nr_tx = mailbox_queue_ptr->nr_tx;
tfm_ns_mailbox_hal_exit_critical();
stats_res->avg_nr_slots = nr_used_slots / nr_tx;
nr_used_slots %= nr_tx;
stats_res->avg_nr_slots_tenths = nr_used_slots * 10 / nr_tx;
}
#endif
mailbox_msg_handle_t tfm_ns_mailbox_tx_client_req(uint32_t call_type,
const struct psa_client_params_t *params,
int32_t client_id)
{
uint8_t idx;
struct mailbox_msg_t *msg_ptr;
mailbox_msg_handle_t handle;
const void *task_handle;
if (!mailbox_queue_ptr) {
return MAILBOX_MSG_NULL_HANDLE;
}
if (!params) {
return MAILBOX_MSG_NULL_HANDLE;
}
idx = acquire_empty_slot(mailbox_queue_ptr);
if (idx >= NUM_MAILBOX_QUEUE_SLOT) {
return MAILBOX_QUEUE_FULL;
}
#ifdef TFM_MULTI_CORE_TEST
mailbox_tx_stats_update(mailbox_queue_ptr);
#endif
/* Fill the mailbox message */
msg_ptr = &mailbox_queue_ptr->queue[idx].msg;
msg_ptr->call_type = call_type;
memcpy(&msg_ptr->params, params, sizeof(msg_ptr->params));
msg_ptr->client_id = client_id;
/*
* Fetch the current task handle. The task will be woken up according the
* handle value set in the owner field.
*/
task_handle = tfm_ns_mailbox_get_task_handle();
set_msg_owner(idx, task_handle);
get_mailbox_msg_handle(idx, &handle);
tfm_ns_mailbox_hal_enter_critical();
set_queue_slot_pend(idx);
tfm_ns_mailbox_hal_exit_critical();
tfm_ns_mailbox_hal_notify_peer();
return handle;
}
int32_t tfm_ns_mailbox_rx_client_reply(mailbox_msg_handle_t handle,
int32_t *reply)
{
uint8_t idx;
int32_t ret;
if (!mailbox_queue_ptr) {
return MAILBOX_INVAL_PARAMS;
}
if ((handle == MAILBOX_MSG_NULL_HANDLE) || (!reply)) {
return MAILBOX_INVAL_PARAMS;
}
ret = get_mailbox_msg_idx(handle, &idx);
if (ret != MAILBOX_SUCCESS) {
return ret;
}
*reply = mailbox_queue_ptr->queue[idx].reply.return_val;
/* Clear up the owner field */
set_msg_owner(idx, NULL);
tfm_ns_mailbox_hal_enter_critical();
clear_queue_slot_replied(idx);
clear_queue_slot_woken(idx);
/*
* Make sure that the empty flag is set after all the other status flags are
* re-initialized.
*/
set_queue_slot_empty(idx);
tfm_ns_mailbox_hal_exit_critical();
return MAILBOX_SUCCESS;
}
bool tfm_ns_mailbox_is_msg_replied(mailbox_msg_handle_t handle)
{
uint8_t idx;
int32_t ret;
mailbox_queue_status_t status;
if (!mailbox_queue_ptr) {
return false;
}
if (handle == MAILBOX_MSG_NULL_HANDLE) {
return false;
}
ret = get_mailbox_msg_idx(handle, &idx);
if (ret != MAILBOX_SUCCESS) {
return false;
}
tfm_ns_mailbox_hal_enter_critical();
status = mailbox_queue_ptr->replied_slots;
tfm_ns_mailbox_hal_exit_critical();
if (status & (1 << idx)) {
return true;
}
return false;
}
mailbox_msg_handle_t tfm_ns_mailbox_fetch_reply_msg_isr(void)
{
uint8_t idx;
mailbox_msg_handle_t handle;
mailbox_queue_status_t replied_status;
if (!mailbox_queue_ptr) {
return MAILBOX_MSG_NULL_HANDLE;
}
tfm_ns_mailbox_hal_enter_critical_isr();
replied_status = mailbox_queue_ptr->replied_slots;
tfm_ns_mailbox_hal_exit_critical_isr();
if (!replied_status) {
return MAILBOX_MSG_NULL_HANDLE;
}
for (idx = 0; idx < NUM_MAILBOX_QUEUE_SLOT; idx++) {
/* Find the first replied message in queue */
if (replied_status & (0x1UL << idx)) {
tfm_ns_mailbox_hal_enter_critical_isr();
clear_queue_slot_replied(idx);
set_queue_slot_woken(idx);
tfm_ns_mailbox_hal_exit_critical_isr();
if (get_mailbox_msg_handle(idx, &handle) == MAILBOX_SUCCESS) {
return handle;
}
}
}
return MAILBOX_MSG_NULL_HANDLE;
}
const void *tfm_ns_mailbox_get_msg_owner(mailbox_msg_handle_t handle)
{
uint8_t idx;
if (get_mailbox_msg_idx(handle, &idx) != MAILBOX_SUCCESS) {
return NULL;
}
if (idx < NUM_MAILBOX_QUEUE_SLOT) {
return mailbox_queue_ptr->queue[idx].owner;
}
return NULL;
}
int32_t tfm_ns_mailbox_init(struct ns_mailbox_queue_t *queue)
{
int32_t ret;
if (!queue) {
return MAILBOX_INVAL_PARAMS;
}
/*
* Further verification of mailbox queue address may be required according
* to non-secure memory assignment.
*/
memset(queue, 0, sizeof(*queue));
/* Initialize empty bitmask */
queue->empty_slots =
(mailbox_queue_status_t)((1UL << (NUM_MAILBOX_QUEUE_SLOT - 1)) - 1);
queue->empty_slots +=
(mailbox_queue_status_t)(1UL << (NUM_MAILBOX_QUEUE_SLOT - 1));
mailbox_queue_ptr = queue;
/* Platform specific initialization. */
ret = tfm_ns_mailbox_hal_init(queue);
#ifdef TFM_MULTI_CORE_TEST
tfm_ns_mailbox_tx_stats_init();
#endif
return ret;
}
#ifdef TFM_MULTI_CORE_MULTI_CLIENT_CALL
int32_t tfm_ns_mailbox_wait_reply(mailbox_msg_handle_t handle)
{
uint8_t idx;
int32_t ret;
if (!mailbox_queue_ptr) {
return MAILBOX_INVAL_PARAMS;
}
if (handle == MAILBOX_MSG_NULL_HANDLE) {
return MAILBOX_INVAL_PARAMS;
}
ret = get_mailbox_msg_idx(handle, &idx);
if (ret != MAILBOX_SUCCESS) {
return ret;
}
while (1) {
tfm_ns_mailbox_hal_wait_reply(handle);
/*
* Woken up from sleep
* Check the completed flag to make sure that the current thread is
* woken up by reply event, rather than other events.
*/
tfm_ns_mailbox_hal_enter_critical();
if (is_queue_slot_woken(idx)) {
tfm_ns_mailbox_hal_exit_critical();
break;
}
tfm_ns_mailbox_hal_exit_critical();
}
return MAILBOX_SUCCESS;
}
#endif

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2019-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cmsis_nvic_virtual.h"
#include "tfm_platform_api.h"
void NVIC_SystemReset(void)
{
tfm_platform_system_reset();
}

View File

@ -0,0 +1,37 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_error.h"
#include "tfm_ns_interface.h"
void mbed_tfm_init(void)
{
/*
* In case of V8-M, we need to initialize NS interface
* after the RTOS has started to enable
* communication from Secure and Non-Secure cores.
*/
int32_t ret;
ret = tfm_ns_interface_init();
if (ret != TFM_SUCCESS) {
/* Avoid undefined behavior after NS interface initialization failed */
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM,
MBED_ERROR_CODE_INITIALIZATION_FAILED),
"Failed to initialize NS interface");
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "tfm_api.h"
#include "tfm_ns_interface.h"
#include "cmsis_os2.h"
/**
* \brief the ns_lock ID
*/
static osMutexId_t ns_lock_handle = NULL;
__attribute__((weak))
int32_t tfm_ns_interface_dispatch(veneer_fn fn,
uint32_t arg0, uint32_t arg1,
uint32_t arg2, uint32_t arg3)
{
int32_t result;
osStatus_t status;
/* TFM request protected by NS lock */
status = osMutexAcquire(ns_lock_handle, osWaitForever);
if (status != osOK) {
return (int32_t)TFM_ERROR_GENERIC;
}
result = fn(arg0, arg1, arg2, arg3);
status = osMutexRelease(ns_lock_handle);
if (status != osOK) {
return (int32_t)TFM_ERROR_GENERIC;
}
return result;
}
__attribute__((weak))
enum tfm_status_e tfm_ns_interface_init(void)
{
const osMutexAttr_t attr = {
.name = NULL,
.attr_bits = osMutexPrioInherit, /* Priority inheritance is recommended
* to enable if it is supported.
* For recursive mutex and the ability
* of auto release when owner being
* terminated is not required.
*/
.cb_mem = NULL,
.cb_size = 0U
};
ns_lock_handle = osMutexNew(&attr);
if (!ns_lock_handle) {
return TFM_ERROR_GENERIC;
}
return TFM_SUCCESS;
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "psa/client.h"
#include "tfm_ns_interface.h"
#include "tfm_api.h"
/**** API functions ****/
uint32_t psa_framework_version(void)
{
return tfm_ns_interface_dispatch(
(veneer_fn)tfm_psa_framework_version_veneer,
0,
0,
0,
0);
}
uint32_t psa_version(uint32_t sid)
{
return tfm_ns_interface_dispatch(
(veneer_fn)tfm_psa_version_veneer,
sid,
0,
0,
0);
}
psa_handle_t psa_connect(uint32_t sid, uint32_t version)
{
return tfm_ns_interface_dispatch(
(veneer_fn)tfm_psa_connect_veneer,
sid,
version,
0,
0);
}
psa_status_t psa_call(psa_handle_t handle, int32_t type,
const psa_invec *in_vec,
size_t in_len,
psa_outvec *out_vec,
size_t out_len)
{
/* FixMe: sanity check can be added to offload some NS thread checks from
* TFM secure API
*/
/* Due to v8M restrictions, TF-M NS API needs to add another layer of
* serialization in order for NS to pass arguments to S
*/
const struct tfm_control_parameter_t ctrl_param = {
.type = type,
.in_len = in_len,
.out_len = out_len,
};
return tfm_ns_interface_dispatch(
(veneer_fn)tfm_psa_call_veneer,
(uint32_t)handle,
(uint32_t)&ctrl_param,
(uint32_t)in_vec,
(uint32_t)out_vec);
}
void psa_close(psa_handle_t handle)
{
(void)tfm_ns_interface_dispatch(
(veneer_fn)tfm_psa_close_veneer,
(uint32_t)handle,
0,
0,
0);
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2019 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cmsis.h"
#ifndef NVIC_VIRTUAL_H
#define NVIC_VIRTUAL_H
#ifdef __cplusplus
extern "C" {
#endif
/* NVIC functions */
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
#define NVIC_EnableIRQ __NVIC_EnableIRQ
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
#define NVIC_DisableIRQ __NVIC_DisableIRQ
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
#define NVIC_GetActive __NVIC_GetActive
#define NVIC_SetPriority __NVIC_SetPriority
#define NVIC_GetPriority __NVIC_GetPriority
/**
* \brief Overriding the default CMSIS system reset implementation by calling
* secure TFM service.
*
*/
void NVIC_SystemReset(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _IPC_CONFIG_H_
#define _IPC_CONFIG_H_
#include "platform_multicore.h"
#define IPC_RX_CHAN IPC_PSA_CLIENT_REPLY_CHAN
#define IPC_RX_INTR_STRUCT IPC_PSA_CLIENT_REPLY_INTR_STRUCT
#define IPC_RX_INT_MASK IPC_PSA_CLIENT_REPLY_INTR_MASK
#define IPC_TX_CHAN IPC_PSA_CLIENT_CALL_CHAN
#define IPC_TX_NOTIFY_MASK IPC_PSA_CLIENT_CALL_NOTIFY_MASK
#define PSA_CLIENT_REPLY_NVIC_IRQn IPC_PSA_CLIENT_REPLY_IPC_INTR
#define PSA_CLIENT_REPLY_IRQ_PRIORITY 3
#endif

View File

@ -0,0 +1,175 @@
/*
* Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __PSA_CLIENT_H__
#define __PSA_CLIENT_H__
#include <stddef.h>
#include <stdint.h>
#include "psa/error.h"
#ifdef __cplusplus
extern "C" {
#endif
/*********************** PSA Client Macros and Types *************************/
/**
* The version of the PSA Framework API that is being used to build the calling
* firmware.
*/
#define PSA_FRAMEWORK_VERSION (0x0100u)
/**
* Return value from psa_version() if the requested RoT Service is not present
* in the system.
*/
#define PSA_VERSION_NONE (0u)
/**
* The zero-value null handle can be assigned to variables used in clients and
* RoT Services, indicating that there is no current connection or message.
*/
#define PSA_NULL_HANDLE ((psa_handle_t)0)
/**
* Tests whether a handle value returned by psa_connect() is valid.
*/
#define PSA_HANDLE_IS_VALID(handle) ((psa_handle_t)(handle) > 0)
/**
* Converts the handle value returned from a failed call psa_connect() into
* an error code.
*/
#define PSA_HANDLE_TO_ERROR(handle) ((psa_status_t)(handle))
/**
* Maximum number of input and output vectors for a request to psa_call().
*/
#define PSA_MAX_IOVEC (4u)
/**
* An IPC message type that indicates a generic client request.
*/
#define PSA_IPC_CALL (0)
typedef int32_t psa_handle_t;
/**
* A read-only input memory region provided to an RoT Service.
*/
typedef struct psa_invec {
const void *base; /*!< the start address of the memory buffer */
size_t len; /*!< the size in bytes */
} psa_invec;
/**
* A writable output memory region provided to an RoT Service.
*/
typedef struct psa_outvec {
void *base; /*!< the start address of the memory buffer */
size_t len; /*!< the size in bytes */
} psa_outvec;
/*************************** PSA Client API **********************************/
/**
* \brief Retrieve the version of the PSA Framework API that is implemented.
*
* \return version The version of the PSA Framework implementation
* that is providing the runtime services to the
* caller. The major and minor version are encoded
* as follows:
* \arg version[15:8] -- major version number.
* \arg version[7:0] -- minor version number.
*/
uint32_t psa_framework_version(void);
/**
* \brief Retrieve the version of an RoT Service or indicate that it is not
* present on this system.
*
* \param[in] sid ID of the RoT Service to query.
*
* \retval PSA_VERSION_NONE The RoT Service is not implemented, or the
* caller is not permitted to access the service.
* \retval > 0 The version of the implemented RoT Service.
*/
uint32_t psa_version(uint32_t sid);
/**
* \brief Connect to an RoT Service by its SID.
*
* \param[in] sid ID of the RoT Service to connect to.
* \param[in] version Requested version of the RoT Service.
*
* \retval > 0 A handle for the connection.
* \retval PSA_ERROR_CONNECTION_REFUSED The SPM or RoT Service has refused the
* connection.
* \retval PSA_ERROR_CONNECTION_BUSY The SPM or RoT Service cannot make the
* connection at the moment.
* \retval "PROGRAMMER ERROR" The call is a PROGRAMMER ERROR if one or more
* of the following are true:
* \arg The RoT Service ID is not present.
* \arg The RoT Service version is not supported.
* \arg The caller is not allowed to access the RoT
* service.
*/
psa_handle_t psa_connect(uint32_t sid, uint32_t version);
/**
* \brief Call an RoT Service on an established connection.
*
* \param[in] handle A handle to an established connection.
* \param[in] type The reuqest type.
* Must be zero( \ref PSA_IPC_CALL) or positive.
* \param[in] in_vec Array of input \ref psa_invec structures.
* \param[in] in_len Number of input \ref psa_invec structures.
* \param[in/out] out_vec Array of output \ref psa_outvec structures.
* \param[in] out_len Number of output \ref psa_outvec structures.
*
* \retval >=0 RoT Service-specific status value.
* \retval <0 RoT Service-specific error code.
* \retval PSA_ERROR_PROGRAMMER_ERROR The connection has been terminated by the
* RoT Service. The call is a PROGRAMMER ERROR if
* one or more of the following are true:
* \arg An invalid handle was passed.
* \arg The connection is already handling a request.
* \arg type < 0.
* \arg An invalid memory reference was provided.
* \arg in_len + out_len > PSA_MAX_IOVEC.
* \arg The message is unrecognized by the RoT
* Service or incorrectly formatted.
*/
psa_status_t psa_call(psa_handle_t handle, int32_t type,
const psa_invec *in_vec,
size_t in_len,
psa_outvec *out_vec,
size_t out_len);
/**
* \brief Close a connection to an RoT Service.
*
* \param[in] handle A handle to an established connection, or the
* null handle.
*
* \retval void Success.
* \retval "PROGRAMMER ERROR" The call is a PROGRAMMER ERROR if one or more
* of the following are true:
* \arg An invalid handle was provided that is not
* the null handle.
* \arg The connection is currently handling a
* request.
*/
void psa_close(psa_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* __PSA_CLIENT_H__ */

View File

@ -0,0 +1,111 @@
/**
* \file psa/crypto_compat.h
*
* \brief PSA cryptography module: Backward compatibility aliases
*
* This header declares alternative names for macro and functions.
* New application code should not use these names.
* These names may be removed in a future version of Mbed Crypto.
*
* \note This file may not be included directly. Applications must
* include psa/crypto.h.
*/
/*
* Copyright (C) 2019-2020, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef PSA_CRYPTO_COMPAT_H
#define PSA_CRYPTO_COMPAT_H
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/*
* Mechanism for declaring deprecated values
*/
#if defined(MBEDTLS_DEPRECATED_WARNING) && !defined(MBEDTLS_PSA_DEPRECATED)
#define MBEDTLS_PSA_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_PSA_DEPRECATED
#endif
typedef MBEDTLS_PSA_DEPRECATED size_t mbedtls_deprecated_size_t;
typedef MBEDTLS_PSA_DEPRECATED psa_status_t mbedtls_deprecated_psa_status_t;
typedef MBEDTLS_PSA_DEPRECATED psa_key_usage_t mbedtls_deprecated_psa_key_usage_t;
#define MBEDTLS_DEPRECATED_CONSTANT( type, value ) \
( (mbedtls_deprecated_##type) ( value ) )
/*
* Deprecated PSA Crypto error code definitions (PSA Crypto API <= 1.0 beta2)
*/
#define PSA_ERROR_UNKNOWN_ERROR \
MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_GENERIC_ERROR )
#define PSA_ERROR_OCCUPIED_SLOT \
MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_ALREADY_EXISTS )
#define PSA_ERROR_EMPTY_SLOT \
MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_DOES_NOT_EXIST )
#define PSA_ERROR_INSUFFICIENT_CAPACITY \
MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_INSUFFICIENT_DATA )
#define PSA_ERROR_TAMPERING_DETECTED \
MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_CORRUPTION_DETECTED )
/*
* Deprecated PSA Crypto numerical encodings (PSA Crypto API <= 1.0 beta3)
*/
#define PSA_KEY_USAGE_SIGN \
MBEDTLS_DEPRECATED_CONSTANT( psa_key_usage_t, PSA_KEY_USAGE_SIGN_HASH )
#define PSA_KEY_USAGE_VERIFY \
MBEDTLS_DEPRECATED_CONSTANT( psa_key_usage_t, PSA_KEY_USAGE_VERIFY_HASH )
/*
* Deprecated PSA Crypto size calculation macros (PSA Crypto API <= 1.0 beta3)
*/
#define PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE \
MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_SIGNATURE_MAX_SIZE )
#define PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type, key_bits, alg ) \
MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_SIGN_OUTPUT_SIZE( key_type, key_bits, alg ) )
/*
* Deprecated PSA Crypto function names (PSA Crypto API <= 1.0 beta3)
*/
MBEDTLS_PSA_DEPRECATED psa_status_t psa_asymmetric_sign( psa_key_handle_t key,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length );
MBEDTLS_PSA_DEPRECATED psa_status_t psa_asymmetric_verify( psa_key_handle_t key,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
size_t signature_length );
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#ifdef __cplusplus
}
#endif
#endif /* PSA_CRYPTO_COMPAT_H */

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/**
* \file psa/crypto_platform.h
*
* \brief PSA cryptography module: Mbed TLS platform definitions
*
* \note This file may not be included directly. Applications must
* include psa/crypto.h.
*
* This file contains platform-dependent type definitions.
*
* In implementations with isolation between the application and the
* cryptography module, implementers should take care to ensure that
* the definitions that are exposed to applications match what the
* module implements.
*/
#ifndef PSA_CRYPTO_PLATFORM_H
#define PSA_CRYPTO_PLATFORM_H
/* PSA requires several types which C99 provides in stdint.h. */
#include <stdint.h>
/* Integral type representing a key handle. */
typedef uint16_t psa_key_handle_t;
/* This implementation distinguishes *application key identifiers*, which
* are the key identifiers specified by the application, from
* *key file identifiers*, which are the key identifiers that the library
* sees internally. The two types can be different if there is a remote
* call layer between the application and the library which supports
* multiple client applications that do not have access to each others'
* keys. The point of having different types is that the key file
* identifier may encode not only the key identifier specified by the
* application, but also the the identity of the application.
*
* Note that this is an internal concept of the library and the remote
* call layer. The application itself never sees anything other than
* #psa_app_key_id_t with its standard definition.
*/
/* The application key identifier is always what the application sees as
* #psa_key_id_t. */
typedef uint32_t psa_app_key_id_t;
#endif /* PSA_CRYPTO_PLATFORM_H */

View File

@ -0,0 +1,650 @@
/*
* Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/**
* \file psa/crypto_sizes.h
*
* \brief PSA cryptography module: Mbed TLS buffer size macros
*
* \note This file may not be included directly. Applications must
* include psa/crypto.h.
*
* This file contains the definitions of macros that are useful to
* compute buffer sizes. The signatures and semantics of these macros
* are standardized, but the definitions are not, because they depend on
* the available algorithms and, in some cases, on permitted tolerances
* on buffer sizes.
*
* In implementations with isolation between the application and the
* cryptography module, implementers should take care to ensure that
* the definitions that are exposed to applications match what the
* module implements.
*
* Macros that compute sizes whose values do not depend on the
* implementation are in crypto.h.
*/
#ifndef PSA_CRYPTO_SIZES_H
#define PSA_CRYPTO_SIZES_H
#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8)
#define PSA_ROUND_UP_TO_MULTIPLE(block_size, length) \
(((length) + (block_size) - 1) / (block_size) * (block_size))
/** The size of the output of psa_hash_finish(), in bytes.
*
* This is also the hash size that psa_hash_verify() expects.
*
* \param alg A hash algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_HASH(\p alg) is true), or an HMAC algorithm
* (#PSA_ALG_HMAC(\c hash_alg) where \c hash_alg is a
* hash algorithm).
*
* \return The hash size for the specified hash algorithm.
* If the hash algorithm is not recognized, return 0.
* An implementation may return either 0 or the correct size
* for a hash algorithm that it recognizes, but does not support.
*/
#define PSA_HASH_SIZE(alg) \
( \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 16 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 : \
0)
/** \def PSA_HASH_MAX_SIZE
*
* Maximum size of a hash.
*
* This macro must expand to a compile-time constant integer. This value
* should be the maximum size of a hash supported by the implementation,
* in bytes, and must be no smaller than this maximum.
*/
/* Note: for HMAC-SHA-3, the block size is 144 bytes for HMAC-SHA3-226,
* 136 bytes for HMAC-SHA3-256, 104 bytes for SHA3-384, 72 bytes for
* HMAC-SHA3-512. */
#define PSA_HASH_MAX_SIZE 64
#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128
/** \def PSA_MAC_MAX_SIZE
*
* Maximum size of a MAC.
*
* This macro must expand to a compile-time constant integer. This value
* should be the maximum size of a MAC supported by the implementation,
* in bytes, and must be no smaller than this maximum.
*/
/* All non-HMAC MACs have a maximum size that's smaller than the
* minimum possible value of PSA_HASH_MAX_SIZE in this implementation. */
/* Note that the encoding of truncated MAC algorithms limits this value
* to 64 bytes.
*/
#define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE
/** The tag size for an AEAD algorithm, in bytes.
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
*
* \return The tag size for the specified algorithm.
* If the AEAD algorithm does not have an identified
* tag that can be distinguished from the rest of
* the ciphertext, return 0.
* If the AEAD algorithm is not recognized, return 0.
* An implementation may return either 0 or a
* correct size for an AEAD algorithm that it
* recognizes, but does not support.
*/
#define PSA_AEAD_TAG_LENGTH(alg) \
(PSA_ALG_IS_AEAD(alg) ? \
(((alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> PSA_AEAD_TAG_LENGTH_OFFSET) : \
0)
/* The maximum size of an RSA key on this implementation, in bits.
* This is a vendor-specific macro.
*
* Mbed TLS does not set a hard limit on the size of RSA keys: any key
* whose parameters fit in a bignum is accepted. However large keys can
* induce a large memory usage and long computation times. Unlike other
* auxiliary macros in this file and in crypto.h, which reflect how the
* library is configured, this macro defines how the library is
* configured. This implementation refuses to import or generate an
* RSA key whose size is larger than the value defined here.
*
* Note that an implementation may set different size limits for different
* operations, and does not need to accept all key sizes up to the limit. */
#define PSA_VENDOR_RSA_MAX_KEY_BITS 4096
/* The maximum size of an ECC key on this implementation, in bits.
* This is a vendor-specific macro. */
#define PSA_VENDOR_ECC_MAX_CURVE_BITS 521
/** Bit size associated with an elliptic curve.
*
* \param curve An elliptic curve (value of type #psa_ecc_curve_t).
*
* \return The size associated with \p curve, in bits.
* This may be 0 if the implementation does not support
* the specified curve.
*/
#define PSA_ECC_CURVE_BITS(curve) \
((curve) == PSA_ECC_CURVE_SECT163K1 ? 163 : \
(curve) == PSA_ECC_CURVE_SECT163R1 ? 163 : \
(curve) == PSA_ECC_CURVE_SECT163R2 ? 163 : \
(curve) == PSA_ECC_CURVE_SECT193R1 ? 193 : \
(curve) == PSA_ECC_CURVE_SECT193R2 ? 193 : \
(curve) == PSA_ECC_CURVE_SECT233K1 ? 233 : \
(curve) == PSA_ECC_CURVE_SECT233R1 ? 233 : \
(curve) == PSA_ECC_CURVE_SECT239K1 ? 239 : \
(curve) == PSA_ECC_CURVE_SECT283K1 ? 283 : \
(curve) == PSA_ECC_CURVE_SECT283R1 ? 283 : \
(curve) == PSA_ECC_CURVE_SECT409K1 ? 409 : \
(curve) == PSA_ECC_CURVE_SECT409R1 ? 409 : \
(curve) == PSA_ECC_CURVE_SECT571K1 ? 571 : \
(curve) == PSA_ECC_CURVE_SECT571R1 ? 571 : \
(curve) == PSA_ECC_CURVE_SECP160K1 ? 160 : \
(curve) == PSA_ECC_CURVE_SECP160R1 ? 160 : \
(curve) == PSA_ECC_CURVE_SECP160R2 ? 160 : \
(curve) == PSA_ECC_CURVE_SECP192K1 ? 192 : \
(curve) == PSA_ECC_CURVE_SECP192R1 ? 192 : \
(curve) == PSA_ECC_CURVE_SECP224K1 ? 224 : \
(curve) == PSA_ECC_CURVE_SECP224R1 ? 224 : \
(curve) == PSA_ECC_CURVE_SECP256K1 ? 256 : \
(curve) == PSA_ECC_CURVE_SECP256R1 ? 256 : \
(curve) == PSA_ECC_CURVE_SECP384R1 ? 384 : \
(curve) == PSA_ECC_CURVE_SECP521R1 ? 521 : \
(curve) == PSA_ECC_CURVE_BRAINPOOL_P256R1 ? 256 : \
(curve) == PSA_ECC_CURVE_BRAINPOOL_P384R1 ? 384 : \
(curve) == PSA_ECC_CURVE_BRAINPOOL_P512R1 ? 512 : \
(curve) == PSA_ECC_CURVE_CURVE25519 ? 255 : \
(curve) == PSA_ECC_CURVE_CURVE448 ? 448 : \
0)
/** \def PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN
*
* This macro returns the maximum length of the PSK supported
* by the TLS-1.2 PSK-to-MS key derivation.
*
* Quoting RFC 4279, Sect 5.3:
* TLS implementations supporting these ciphersuites MUST support
* arbitrary PSK identities up to 128 octets in length, and arbitrary
* PSKs up to 64 octets in length. Supporting longer identities and
* keys is RECOMMENDED.
*
* Therefore, no implementation should define a value smaller than 64
* for #PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN.
*/
#define PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN 128
/** The maximum size of a block cipher supported by the implementation. */
#define PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE 16
/** The size of the output of psa_mac_sign_finish(), in bytes.
*
* This is also the MAC size that psa_mac_verify_finish() expects.
*
* \param key_type The type of the MAC key.
* \param key_bits The size of the MAC key in bits.
* \param alg A MAC algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_MAC(\p alg) is true).
*
* \return The MAC size for the specified algorithm with
* the specified key parameters.
* \return 0 if the MAC algorithm is not recognized.
* \return Either 0 or the correct size for a MAC algorithm that
* the implementation recognizes, but does not support.
* \return Unspecified if the key parameters are not consistent
* with the algorithm.
*/
#define PSA_MAC_FINAL_SIZE(key_type, key_bits, alg) \
((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \
PSA_ALG_IS_HMAC(alg) ? PSA_HASH_SIZE(PSA_ALG_HMAC_GET_HASH(alg)) : \
PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
((void)(key_type), (void)(key_bits), 0))
/** The maximum size of the output of psa_aead_encrypt(), in bytes.
*
* If the size of the ciphertext buffer is at least this large, it is
* guaranteed that psa_aead_encrypt() will not fail due to an
* insufficient buffer size. Depending on the algorithm, the actual size of
* the ciphertext may be smaller.
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
* \param plaintext_length Size of the plaintext in bytes.
*
* \return The AEAD ciphertext size for the specified
* algorithm.
* If the AEAD algorithm is not recognized, return 0.
* An implementation may return either 0 or a
* correct size for an AEAD algorithm that it
* recognizes, but does not support.
*/
#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) \
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
(plaintext_length) + PSA_AEAD_TAG_LENGTH(alg) : \
0)
/** The maximum size of the output of psa_aead_decrypt(), in bytes.
*
* If the size of the plaintext buffer is at least this large, it is
* guaranteed that psa_aead_decrypt() will not fail due to an
* insufficient buffer size. Depending on the algorithm, the actual size of
* the plaintext may be smaller.
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
* \param ciphertext_length Size of the plaintext in bytes.
*
* \return The AEAD ciphertext size for the specified
* algorithm.
* If the AEAD algorithm is not recognized, return 0.
* An implementation may return either 0 or a
* correct size for an AEAD algorithm that it
* recognizes, but does not support.
*/
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
(ciphertext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
0)
/** A sufficient output buffer size for psa_aead_update().
*
* If the size of the output buffer is at least this large, it is
* guaranteed that psa_aead_update() will not fail due to an
* insufficient buffer size. The actual size of the output may be smaller
* in any given call.
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
* \param input_length Size of the input in bytes.
*
* \return A sufficient output buffer size for the specified
* algorithm.
* If the AEAD algorithm is not recognized, return 0.
* An implementation may return either 0 or a
* correct size for an AEAD algorithm that it
* recognizes, but does not support.
*/
/* For all the AEAD modes defined in this specification, it is possible
* to emit output without delay. However, hardware may not always be
* capable of this. So for modes based on a block cipher, allow the
* implementation to delay the output until it has a full block. */
#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
PSA_ROUND_UP_TO_MULTIPLE(PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE, (input_length)) : \
(input_length))
/** A sufficient ciphertext buffer size for psa_aead_finish().
*
* If the size of the ciphertext buffer is at least this large, it is
* guaranteed that psa_aead_finish() will not fail due to an
* insufficient ciphertext buffer size. The actual size of the output may
* be smaller in any given call.
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
*
* \return A sufficient ciphertext buffer size for the
* specified algorithm.
* If the AEAD algorithm is not recognized, return 0.
* An implementation may return either 0 or a
* correct size for an AEAD algorithm that it
* recognizes, but does not support.
*/
#define PSA_AEAD_FINISH_OUTPUT_SIZE(alg) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
0)
/** A sufficient plaintext buffer size for psa_aead_verify().
*
* If the size of the plaintext buffer is at least this large, it is
* guaranteed that psa_aead_verify() will not fail due to an
* insufficient plaintext buffer size. The actual size of the output may
* be smaller in any given call.
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
*
* \return A sufficient plaintext buffer size for the
* specified algorithm.
* If the AEAD algorithm is not recognized, return 0.
* An implementation may return either 0 or a
* correct size for an AEAD algorithm that it
* recognizes, but does not support.
*/
#define PSA_AEAD_VERIFY_OUTPUT_SIZE(alg) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
0)
#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \
(PSA_ALG_IS_RSA_OAEP(alg) ? \
2 * PSA_HASH_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \
11 /*PKCS#1v1.5*/)
/**
* \brief ECDSA signature size for a given curve bit size
*
* \param curve_bits Curve size in bits.
* \return Signature size in bytes.
*
* \note This macro returns a compile-time constant if its argument is one.
*/
#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \
(PSA_BITS_TO_BYTES(curve_bits) * 2)
/** Sufficient signature buffer size for psa_sign_hash().
*
* This macro returns a sufficient buffer size for a signature using a key
* of the specified type and size, with the specified algorithm.
* Note that the actual size of the signature may be smaller
* (some algorithms produce a variable-size signature).
*
* \warning This function may call its arguments multiple times or
* zero times, so you should not pass arguments that contain
* side effects.
*
* \param key_type An asymmetric key type (this may indifferently be a
* key pair type or a public key type).
* \param key_bits The size of the key in bits.
* \param alg The signature algorithm.
*
* \return If the parameters are valid and supported, return
* a buffer size in bytes that guarantees that
* psa_sign_hash() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro shall return either a
* sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
*/
#define PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \
(PSA_KEY_TYPE_IS_RSA(key_type) ? ((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \
PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \
((void)alg, 0))
#define PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE \
PSA_ECDSA_SIGNATURE_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
/** \def PSA_SIGNATURE_MAX_SIZE
*
* Maximum size of an asymmetric signature.
*
* This macro must expand to a compile-time constant integer. This value
* should be the maximum size of a signature supported by the implementation,
* in bytes, and must be no smaller than this maximum.
*/
#define PSA_SIGNATURE_MAX_SIZE \
(PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) > PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE ? \
PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) : \
PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE)
/** Sufficient output buffer size for psa_asymmetric_encrypt().
*
* This macro returns a sufficient buffer size for a ciphertext produced using
* a key of the specified type and size, with the specified algorithm.
* Note that the actual size of the ciphertext may be smaller, depending
* on the algorithm.
*
* \warning This function may call its arguments multiple times or
* zero times, so you should not pass arguments that contain
* side effects.
*
* \param key_type An asymmetric key type (this may indifferently be a
* key pair type or a public key type).
* \param key_bits The size of the key in bits.
* \param alg The signature algorithm.
*
* \return If the parameters are valid and supported, return
* a buffer size in bytes that guarantees that
* psa_asymmetric_encrypt() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro shall return either a
* sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
*/
#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \
(PSA_KEY_TYPE_IS_RSA(key_type) ? \
((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \
0)
/** Sufficient output buffer size for psa_asymmetric_decrypt().
*
* This macro returns a sufficient buffer size for a ciphertext produced using
* a key of the specified type and size, with the specified algorithm.
* Note that the actual size of the ciphertext may be smaller, depending
* on the algorithm.
*
* \warning This function may call its arguments multiple times or
* zero times, so you should not pass arguments that contain
* side effects.
*
* \param key_type An asymmetric key type (this may indifferently be a
* key pair type or a public key type).
* \param key_bits The size of the key in bits.
* \param alg The signature algorithm.
*
* \return If the parameters are valid and supported, return
* a buffer size in bytes that guarantees that
* psa_asymmetric_decrypt() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro shall return either a
* sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
*/
#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \
(PSA_KEY_TYPE_IS_RSA(key_type) ? \
PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) : \
0)
/* Maximum size of the ASN.1 encoding of an INTEGER with the specified
* number of bits.
*
* This definition assumes that bits <= 2^19 - 9 so that the length field
* is at most 3 bytes. The length of the encoding is the length of the
* bit string padded to a whole number of bytes plus:
* - 1 type byte;
* - 1 to 3 length bytes;
* - 0 to 1 bytes of leading 0 due to the sign bit.
*/
#define PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(bits) \
((bits) / 8 + 5)
/* Maximum size of the export encoding of an RSA public key.
* Assumes that the public exponent is less than 2^32.
*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER } -- e
*
* - 4 bytes of SEQUENCE overhead;
* - n : INTEGER;
* - 7 bytes for the public exponent.
*/
#define PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) \
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) + 11)
/* Maximum size of the export encoding of an RSA key pair.
* Assumes thatthe public exponent is less than 2^32 and that the size
* difference between the two primes is at most 1 bit.
*
* RSAPrivateKey ::= SEQUENCE {
* version Version, -- 0
* modulus INTEGER, -- N-bit
* publicExponent INTEGER, -- 32-bit
* privateExponent INTEGER, -- N-bit
* prime1 INTEGER, -- N/2-bit
* prime2 INTEGER, -- N/2-bit
* exponent1 INTEGER, -- N/2-bit
* exponent2 INTEGER, -- N/2-bit
* coefficient INTEGER, -- N/2-bit
* }
*
* - 4 bytes of SEQUENCE overhead;
* - 3 bytes of version;
* - 7 half-size INTEGERs plus 2 full-size INTEGERs,
* overapproximated as 9 half-size INTEGERS;
* - 7 bytes for the public exponent.
*/
#define PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) \
(9 * PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE((key_bits) / 2 + 1) + 14)
/* Maximum size of the export encoding of a DSA public key.
*
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING } -- contains DSAPublicKey
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters Dss-Parms } -- SEQUENCE of 3 INTEGERs
* DSAPublicKey ::= INTEGER -- public key, Y
*
* - 3 * 4 bytes of SEQUENCE overhead;
* - 1 + 1 + 7 bytes of algorithm (DSA OID);
* - 4 bytes of BIT STRING overhead;
* - 3 full-size INTEGERs (p, g, y);
* - 1 + 1 + 32 bytes for 1 sub-size INTEGER (q <= 256 bits).
*/
#define PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) \
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3 + 59)
/* Maximum size of the export encoding of a DSA key pair.
*
* DSAPrivateKey ::= SEQUENCE {
* version Version, -- 0
* prime INTEGER, -- p
* subprime INTEGER, -- q
* generator INTEGER, -- g
* public INTEGER, -- y
* private INTEGER, -- x
* }
*
* - 4 bytes of SEQUENCE overhead;
* - 3 bytes of version;
* - 3 full-size INTEGERs (p, g, y);
* - 2 * (1 + 1 + 32) bytes for 2 sub-size INTEGERs (q, x <= 256 bits).
*/
#define PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) \
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3 + 75)
/* Maximum size of the export encoding of an ECC public key.
*
* The representation of an ECC public key is:
* - The byte 0x04;
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
* - where m is the bit size associated with the curve.
*
* - 1 byte + 2 * point size.
*/
#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) \
(2 * PSA_BITS_TO_BYTES(key_bits) + 1)
/* Maximum size of the export encoding of an ECC key pair.
*
* An ECC key pair is represented by the secret value.
*/
#define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \
(PSA_BITS_TO_BYTES(key_bits))
/** Sufficient output buffer size for psa_export_key() or psa_export_public_key().
*
* This macro returns a compile-time constant if its arguments are
* compile-time constants.
*
* \warning This function may call its arguments multiple times or
* zero times, so you should not pass arguments that contain
* side effects.
*
* The following code illustrates how to allocate enough memory to export
* a key by querying the key type and size at runtime.
* \code{c}
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
* psa_status_t status;
* status = psa_get_key_attributes(key, &attributes);
* if (status != PSA_SUCCESS) handle_error(...);
* psa_key_type_t key_type = psa_get_key_type(&attributes);
* size_t key_bits = psa_get_key_bits(&attributes);
* size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits);
* psa_reset_key_attributes(&attributes);
* uint8_t *buffer = malloc(buffer_size);
* if (buffer == NULL) handle_error(...);
* size_t buffer_length;
* status = psa_export_key(key, buffer, buffer_size, &buffer_length);
* if (status != PSA_SUCCESS) handle_error(...);
* \endcode
*
* For psa_export_public_key(), calculate the buffer size from the
* public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR
* to convert a key pair type to the corresponding public key type.
* \code{c}
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
* psa_status_t status;
* status = psa_get_key_attributes(key, &attributes);
* if (status != PSA_SUCCESS) handle_error(...);
* psa_key_type_t key_type = psa_get_key_type(&attributes);
* psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
* size_t key_bits = psa_get_key_bits(&attributes);
* size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(public_key_type, key_bits);
* psa_reset_key_attributes(&attributes);
* uint8_t *buffer = malloc(buffer_size);
* if (buffer == NULL) handle_error(...);
* size_t buffer_length;
* status = psa_export_public_key(key, buffer, buffer_size, &buffer_length);
* if (status != PSA_SUCCESS) handle_error(...);
* \endcode
*
* \param key_type A supported key type.
* \param key_bits The size of the key in bits.
*
* \return If the parameters are valid and supported, return
* a buffer size in bytes that guarantees that
* psa_sign_hash() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro shall return either a
* sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
*/
#define PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits) \
(PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
(key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \
(key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
(key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \
(key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \
PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
0)
#endif /* PSA_CRYPTO_SIZES_H */

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/**
* \file psa/error.h
* \brief Standard error codes for the SPM and RoT Services
*/
#ifndef __PSA_ERROR_H__
#define __PSA_ERROR_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* If #PSA_SUCCESS is already defined, it means that #psa_status_t
* is also defined in an external header, so prevent its multiple
* definition.
*/
#ifndef PSA_SUCCESS
typedef int32_t psa_status_t;
#endif
#define PSA_SUCCESS ((psa_status_t)0)
#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t)-129)
#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t)-130)
#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t)-131)
#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132)
#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133)
#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134)
#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135)
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138)
#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139)
#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140)
#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141)
#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142)
#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t)-144)
#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145)
#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146)
#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147)
#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149)
#ifdef __cplusplus
}
#endif
#endif /* __PSA_ERROR_H__ */

View File

@ -0,0 +1,228 @@
/*
* Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/***************************************************************************/
/* DRAFT UNDER REVIEW */
/* These APIs are still evolving and are meant as a prototype for review.*/
/* The APIs will change depending on feedback and will be firmed up */
/* to a stable set of APIs once all the feedback has been considered. */
/***************************************************************************/
#ifndef __PSA_INITIAL_ATTESTATION_H__
#define __PSA_INITIAL_ATTESTATION_H__
#include <limits.h>
#include <stdint.h>
#include <stddef.h>
#include "psa/crypto.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief PSA INITIAL ATTESTATION API version
*
* Initial attestation API version is: 1.0.0
*/
#define PSA_INITIAL_ATTEST_API_VERSION_MAJOR (1)
#define PSA_INITIAL_ATTEST_API_VERSION_MINOR (0)
/**
* The allowed size of input challenge in bytes: 32, 48, 64
* Challenge can be a nonce from server
* or the hash of some combined data : nonce + attested data by caller.
*/
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32 (32u)
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48 (48u)
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 (64u)
/**
* The maximum size of an attestation token that can be generated by the
* attestation service. Used to configure buffers for services that verify the
* produced tokens.
*/
#define PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE (0x400)
/**
* The list of fixed claims in the initial attestation token is still evolving,
* you can expect slight changes in the future.
*
* The initial attestation token is planned to be aligned with future version of
* Entity Attestation Token format:
* https://tools.ietf.org/html/draft-mandyam-eat-01
*
* Current list of claims:
* - Challenge: Input object from caller. Can be a single nonce from server
* or hash of nonce and attested data. It is intended to provide
* freshness to reports and the caller has responsibility to
* arrange this. Allowed length: 32, 48, 64 bytes. The claim is
* modeled to be eventually represented by the EAT standard
* claim nonce. Until such a time as that standard exists,
* the claim will be represented by a custom claim. Value
* is encoded as byte string.
*
* - Instance ID: It represents the unique identifier of the instance. In the
* PSA definition it is a hash of the public attestation key
* of the instance. The claim is modeled to be eventually
* represented by the EAT standard claim UEID of type GUID.
* Until such a time as that standard exists, the claim will be
* represented by a custom claim Value is encoded as byte
* string.
*
* - Verification service indicator: Optional, recommended claim. It is used by
* a Relying Party to locate a validation service for the token.
* The value is a text string that can be used to locate the
* service or a URL specifying the address of the service. The
* claim is modeled to be eventually represented by the EAT
* standard claim origination. Until such a time as that
* standard exists, the claim will be represented by a custom
* claim. Value is encoded as text string.
*
* - Profile definition: Optional, recommended claim. It contains the name of
* a document that describes the 'profile' of the token, being
* a full description of the claims, their usage, verification
* and token signing. The document name may include versioning.
* Custom claim with a value encoded as text string.
*
* - Implementation ID: It represents the original implementation signer of the
* attestation key and identifies the contract between the
* report and verification. A verification service will use this
* claim to locate the details of the verification process.
* Custom claim with a value encoded as byte string.
*
* - Security lifecycle: It represents the current lifecycle state of the
* instance. Custom claim with a value encoded as integer that
* is divided to convey a major state and a minor state. The
* PSA state and implementation state are encoded as follows:
* - version[15:8] - PSA lifecycle state - major
* - version[7:0] - IMPLEMENTATION DEFINED state - minor
* Possible PSA lifecycle states:
* - Unknown (0x1000u),
* - PSA_RoT_Provisioning (0x2000u),
* - Secured (0x3000u),
* - Non_PSA_RoT_Debug(0x4000u),
* - Recoverable_PSA_RoT_Debug (0x5000u),
* - Decommissioned (0x6000u)
*
* - Client ID: The partition ID of that secure partition or non-secure
* thread who called the initial attestation API. Custom claim
* with a value encoded as a *signed* integer. Negative number
* represents non-secure caller, positive numbers represents
* secure callers, zero is invalid.
*
* - HW version: Optional claim. Globally unique number in EAN-13 format
* identifying the GDSII that went to fabrication, HW and ROM.
* It can be used to reference the security level of the PSA-ROT
* via a certification website. Custom claim with a value is
* encoded as text string.
* - Boot seed: It represents a random value created at system boot time that
* will allow differentiation of reports from different system
* sessions. The size is 32 bytes. Custom claim with a value is
* encoded as byte string.
*
* - Software components: Recommended claim. It represents the software state
* of the system. The value of the claim is an array of CBOR map
* entries, with one entry per software component within the
* device. Each map contains multiple claims that describe
* evidence about the details of the software component.
*
* - Measurement type: Optional claim. It represents the role of the
* software component. Value is encoded as short(!) text
* string.
*
* - Measurement value: It represents a hash of the invariant software
* component in memory at start-up time. The value must be a
* cryptographic hash of 256 bits or stronger.Value is
* encoded as byte string.
*
* - Version: Optional claim. It represents the issued software version.
* Value is encoded as text string.
*
* - Signer ID: It represents the hash of a signing authority public key.
* Value is encoded as byte string.
*
* - Measurement description: Optional claim. It represents the way in which
* the measurement value of the software component is
* computed. Value is encoded as text string containing an
* abbreviated description (name) of the measurement method.
*
* - No software measurements: In the event that the implementation does not
* contain any software measurements then the software
* components claim above can be omitted but instead
* it is mandatory to include this claim to indicate this is a
* deliberate state. Custom claim a value is encoded as unsigned
* integer set to 1.
*/
/**
* \brief Get initial attestation token
*
* \param[in] auth_challenge Pointer to buffer where challenge input is
* stored. Nonce and / or hash of attested data.
* Must be always
* \ref PSA_INITIAL_ATTEST_TOKEN_SIZE bytes
* long.
* \param[in] challenge_size Size of challenge object in bytes.
* \param[out] token_buf Pointer to the buffer where attestation token
* will be stored.
* \param[in] token_buf_size Size of allocated buffer for token, in bytes.
* \param[out] token_size Size of the token that has been returned, in
* bytes.
*
* \return Returns error code as specified in \ref psa_status_t
*/
psa_status_t
psa_initial_attest_get_token(const uint8_t *auth_challenge,
size_t challenge_size,
uint8_t *token_buf,
size_t token_buf_size,
size_t *token_size);
/**
* \brief Get the exact size of initial attestation token in bytes.
*
* It just returns with the size of the IAT token. It can be used if the caller
* dynamically allocates memory for the token buffer.
*
* \param[in] challenge_size Size of challenge object in bytes. This must be
* a supported challenge size (as above).
* \param[out] token_size Size of the token in bytes, which is created by
* initial attestation service.
*
* \return Returns error code as specified in \ref psa_status_t
*/
psa_status_t
psa_initial_attest_get_token_size(size_t challenge_size,
size_t *token_size);
/**
* \brief Get the initial attestation public key.
*
* \param[out] public_key Pointer to the buffer where the public key
* will be stored.
* \param[in] key_buf_size Size of allocated buffer for key, in bytes.
* \param[out] public_key_len Size of public key in bytes.
* \param[out] public_key_curve Type of the elliptic curve which the key
* belongs to.
*
* \note Currently only the ECDSA P-256 over SHA-256 algorithm is supported.
*
* \return Returns error code as specified in \ref psa_status_t
*/
psa_status_t
tfm_initial_attest_get_public_key(uint8_t *public_key,
size_t public_key_buf_size,
size_t *public_key_len,
psa_ecc_curve_t *elliptic_curve_type);
#ifdef __cplusplus
}
#endif
#endif /* __PSA_INITIAL_ATTESTATION_H__ */

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/** This file describes the PSA Internal Trusted Storage API
*/
#ifndef PSA_INTERNAL_TRUSTED_STORAGE_H
#define PSA_INTERNAL_TRUSTED_STORAGE_H
#include <stddef.h>
#include <stdint.h>
#include "psa/error.h"
#include "psa/storage_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PSA_ITS_API_VERSION_MAJOR 1 /**< The major version number of the
* PSA ITS API
*/
#define PSA_ITS_API_VERSION_MINOR 0 /**< The minor version number of the
* PSA ITS API
*/
// This version of the header file is associated with 1.0 final release.
/**
* \brief Create a new, or modify an existing, uid/value pair
*
* Stores data in the internal storage.
*
* \param[in] uid The identifier for the data
* \param[in] data_length The size in bytes of the data in `p_data`
* \param[in] p_data A buffer containing the data
* \param[in] create_flags The flags that the data will be stored with
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_NOT_PERMITTED The operation failed because the
* provided `uid` value was already
* created with
* PSA_STORAGE_FLAG_WRITE_ONCE
* \retval PSA_ERROR_NOT_SUPPORTED The operation failed because one or
* more of the flags provided in
* `create_flags` is not supported or is
* not valid
* \retval PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there
* was insufficient space on the
* storage medium
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the
* physical storage has failed (Fatal
* error)
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one
* of the provided pointers(`p_data`)
* is invalid, for example is `NULL` or
* references memory the caller cannot
* access
*/
psa_status_t psa_its_set(psa_storage_uid_t uid,
size_t data_length,
const void *p_data,
psa_storage_create_flags_t create_flags);
/**
* \brief Retrieve data associated with a provided UID
*
* Retrieves up to `data_size` bytes of the data associated with `uid`, starting
* at `data_offset` bytes from the beginning of the data. Upon successful
* completion, the data will be placed in the `p_data` buffer, which must be at
* least `data_size` bytes in size. The length of the data returned will be in
* `p_data_length`. If `data_size` is 0, the contents of `p_data_length` will
* be set to zero.
*
* \param[in] uid The uid value
* \param[in] data_offset The starting offset of the data requested
* \param[in] data_size The amount of data requested
* \param[out] p_data On success, the buffer where the data will
* be placed
* \param[out] p_data_length On success, this will contain size of the data
* placed in `p_data`
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the
* provided `uid` value was not found in
* the storage
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the
* physical storage has failed (Fatal
* error)
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the
* provided arguments (`p_data`,
* `p_data_length`) is invalid, for example
* is `NULL` or references memory the
* caller cannot access. In addition, this
* can also happen if `data_offset` is
* larger than the size of the data
* associated with `uid`
*/
psa_status_t psa_its_get(psa_storage_uid_t uid,
size_t data_offset,
size_t data_size,
void *p_data,
size_t *p_data_length);
/**
* \brief Retrieve the metadata about the provided uid
*
* Retrieves the metadata stored for a given `uid` as a `psa_storage_info_t`
* structure.
*
* \param[in] uid The `uid` value
* \param[out] p_info A pointer to the `psa_storage_info_t` struct that will
* be populated with the metadata
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided
* uid value was not found in the storage
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical
* storage has failed (Fatal error)
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the
* provided pointers(`p_info`)
* is invalid, for example is `NULL` or
* references memory the caller cannot
* access
*/
psa_status_t psa_its_get_info(psa_storage_uid_t uid,
struct psa_storage_info_t *p_info);
/**
* \brief Remove the provided uid and its associated data from the storage
*
* Deletes the data from internal storage.
*
* \param[in] uid The `uid` value
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one or more
* of the given arguments were invalid (null
* pointer, wrong flags and so on)
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided
* uid value was not found in the storage
* \retval PSA_ERROR_NOT_PERMITTED The operation failed because the provided
* uid value was created with
* PSA_STORAGE_FLAG_WRITE_ONCE
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical
* storage has failed (Fatal error)
*/
psa_status_t psa_its_remove(psa_storage_uid_t uid);
#ifdef __cplusplus
}
#endif
#endif // PSA_INTERNAL_TRUSTED_STORAGE_H

View File

@ -0,0 +1,282 @@
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/* This file describes the PSA Protected Storage API */
#ifndef PSA_PROTECTED_STORAGE_H
#define PSA_PROTECTED_STORAGE_H
#include <stddef.h>
#include <stdint.h>
#include "psa/error.h"
#include "psa/storage_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief PSA_PS_API_VERSION version
*
* Major and minor PSA_PS_API_VERSION numbers
*/
#define PSA_PS_API_VERSION_MAJOR 1
#define PSA_PS_API_VERSION_MINOR 0
// This version of the header file is associated with 1.0 final release
/**
* \brief Create a new, or modify an existing, uid/value pair
*
* Stores data in the protected storage.
*
* \param[in] uid The identifier for the data
* \param[in] data_length The size in bytes of the data in `p_data`
* \param[in] p_data A buffer containing the data
* \param[in] create_flags The flags that the data will be stored with
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_NOT_PERMITTED The operation failed because the
* provided `uid` value was already
* created with
* PSA_STORAGE_FLAG_WRITE_ONCE
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one
* of the provided pointers(`p_data`)
* is invalid, for example is `NULL` or
* references memory the caller cannot
* access
* \retval PSA_ERROR_NOT_SUPPORTED The operation failed because one or
* more of the flags provided in
* `create_flags` is not supported or is
* not valid
* \retval PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there
* was insufficient space on the
* storage medium
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the
* physical storage has failed (Fatal
* error)
* \retval PSA_ERROR_GENERIC_ERROR The operation failed because of an
* unspecified internal failure
*/
psa_status_t psa_ps_set(psa_storage_uid_t uid,
size_t data_length,
const void *p_data,
psa_storage_create_flags_t create_flags);
/**
* \brief Retrieve data associated with a provided uid
*
* Retrieves up to `data_size` bytes of the data associated with `uid`, starting
* at `data_offset` bytes from the beginning of the data. Upon successful
* completion, the data will be placed in the `p_data` buffer, which must be at
* least `data_size` bytes in size. The length of the data returned will be in
* `p_data_length`. If `data_size` is 0, the contents of `p_data_length` will
* be set to zero.
*
* \param[in] uid The uid value
* \param[in] data_offset The starting offset of the data requested
* \param[in] data_size The amount of data requested
* \param[out] p_data On success, the buffer where the data will
* be placed
* \param[out] p_data_length On success, this will contain size of the data
* placed in `p_data`
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the
* provided arguments (`p_data`,
* `p_data_length`) is invalid, for example
* is `NULL` or references memory the
* caller cannot access. In addition, this
* can also happen if `data_offset` is
* larger than the size of the data
* associated with `uid`
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the
* provided `uid` value was not found in
* the storage
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the
* physical storage has failed (Fatal
* error)
* \retval PSA_ERROR_GENERIC_ERROR The operation failed because of an
* unspecified internal failure
* \retval PSA_ERROR_DATA_CORRUPT The operation failed because the data
* associated with the UID was corrupt
* \retval PSA_ERROR_INVALID_SIGNATURE The operation failed because the data
* associated with the UID failed
* authentication
*/
psa_status_t psa_ps_get(psa_storage_uid_t uid,
size_t data_offset,
size_t data_size,
void *p_data,
size_t *p_data_length);
/**
* \brief Retrieve the metadata about the provided uid
*
* Retrieves the metadata stored for a given `uid`
*
* \param[in] uid The `uid` value
* \param[out] p_info A pointer to the `psa_storage_info_t` struct that will
* be populated with the metadata
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the
* provided pointers(`p_info`)
* is invalid, for example is `NULL` or
* references memory the caller cannot
* access
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided
* uid value was not found in the storage
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical
* storage has failed (Fatal error)
* \retval PSA_ERROR_GENERIC_ERROR The operation failed because of an
* unspecified internal failure
* \retval PSA_ERROR_DATA_CORRUPT The operation failed because the data
* associated with the UID was corrupt
*/
psa_status_t psa_ps_get_info(psa_storage_uid_t uid,
struct psa_storage_info_t *p_info);
/**
* \brief Remove the provided uid and its associated data from the storage
*
* Removes previously stored data and any associated metadata,
* including rollback protection data.
*
* \param[in] uid The `uid` value
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one or more
* of the given arguments were invalid (null
* pointer, wrong flags and so on)
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided
* uid value was not found in the storage
* \retval PSA_ERROR_NOT_PERMITTED The operation failed because the provided
* uid value was created with
* PSA_STORAGE_FLAG_WRITE_ONCE
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical
* storage has failed (Fatal error)
* \retval PSA_ERROR_GENERIC_ERROR The operation failed because of an
* unspecified internal failure
*/
psa_status_t psa_ps_remove(psa_storage_uid_t uid);
/**
* \brief Reserves storage for the specified uid
*
* Upon success, the capacity of the storage will be capacity, and the size
* will be 0. It is only necessary to call this function for assets that will
* be written with the psa_ps_set_extended function. If only the psa_ps_set
* function is needed, calls to this function are redundant.
*
* \param[in] uid The `uid` value
* \param[in] capacity The capacity to be allocated in bytes
* \param[in] create_flags Flags indicating properties of storage
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the
* physical storage has failed
* (Fatal error)
* \retval PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because the
* capacity is bigger than the current
* available space
* \retval PSA_ERROR_NOT_SUPPORTED The operation failed because the
* function is not implemented or one
* or more create_flags are not
* supported.
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because uid was
* 0 or create_flags specified flags
* that are not defined in the API.
* \retval PSA_ERROR_GENERIC_ERROR The operation failed due to an
* unspecified error
* \retval PSA_ERROR_ALREADY_EXISTS Storage for the specified uid
* already exists
*/
psa_status_t psa_ps_create(psa_storage_uid_t uid,
size_t capacity,
psa_storage_create_flags_t create_flags);
/**
* \brief Sets partial data into an asset
*
* Before calling this function, the storage must have been reserved with a call
* to psa_ps_create. It can also be used to overwrite data in an asset that was
* created with a call to psa_ps_set. Calling this function with data_length = 0
* is permitted, which will make no change to the stored data.This function can
* overwrite existing data and/or extend it up to the capacity for the uid
* specified in psa_ps_create, but cannot create gaps.
*
* That is, it has preconditions:
* - data_offset <= size
* - data_offset + data_length <= capacity
* and postconditions:
* - size = max(size, data_offset + data_length)
* - capacity unchanged.
*
* \param[in] uid The `uid` value
* \param[in] data_offset Offset within the asset to start the write
* \param[in] data_length The size in bytes of the data in p_data to write
* \param[in] p_data Pointer to a buffer which contains the data to write
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The asset exists, the input parameters
* are correct and the data is correctly
* written in the physical storage.
* \retval PSA_ERROR_STORAGE_FAILURE The data was not written correctly in
* the physical storage
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one or more
* of the preconditions listed above
* regarding data_offset, size, or
* data_length was violated.
* \retval PSA_ERROR_DOES_NOT_EXIST The specified uid was not found
* \retval PSA_ERROR_NOT_SUPPORTED The implementation of the API does not
* support this function
* \retval PSA_ERROR_GENERIC_ERROR The operation failed due to an
* unspecified error
* \retval PSA_ERROR_DATA_CORRUPT The operation failed because the
* existing data has been corrupted.
* \retval PSA_ERROR_INVALID_SIGNATURE The operation failed because the
* existing data failed authentication
* (MAC check failed).
* \retval PSA_ERROR_NOT_PERMITTED The operation failed because it was
* attempted on an asset which was written
* with the flag
* PSA_STORAGE_FLAG_WRITE_ONCE
*/
psa_status_t psa_ps_set_extended(psa_storage_uid_t uid,
size_t data_offset,
size_t data_length,
const void *p_data);
/**
* \brief Lists optional features.
*
* \return A bitmask with flags set for all of
* the optional features supported by the
* implementation.Currently defined flags
* are limited to
* PSA_STORAGE_SUPPORT_SET_EXTENDED
*/
uint32_t psa_ps_get_support(void);
#ifdef __cplusplus
}
#endif
#endif /* PSA_PROTECTED_STORAGE_H */

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/* This file includes common definitions for PSA storage
*/
#ifndef PSA_STORAGE_COMMON_H
#define PSA_STORAGE_COMMON_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint32_t psa_storage_create_flags_t;
typedef uint64_t psa_storage_uid_t;
/* Flags */
#define PSA_STORAGE_FLAG_NONE 0u
#define PSA_STORAGE_FLAG_WRITE_ONCE (1u << 0)
#define PSA_STORAGE_FLAG_NO_CONFIDENTIALITY (1u << 1)
#define PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION (1u << 2)
/* A container for metadata associated with a specific uid */
struct psa_storage_info_t {
size_t capacity;
size_t size;
psa_storage_create_flags_t flags;
};
#define PSA_STORAGE_SUPPORT_SET_EXTENDED (1u << 0)
#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149)
#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152)
#ifdef __cplusplus
}
#endif
#endif // PSA_STORAGE_COMMON_H

View File

@ -0,0 +1,142 @@
/*
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __TFM_API_H__
#define __TFM_API_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "psa/client.h"
#define TFM_INVALID_CLIENT_ID 0
/**
* \brief Checks if the provided client ID is a secure client ID.
*
* \param[in] client_id Client ID to check.
*
* \retval 1 Client ID is secure.
* \retval 0 Client ID is non-secure.
*/
#define TFM_CLIENT_ID_IS_S(client_id) ((client_id)>0)
/**
* \brief Checks if the provided client ID is a non-secure client ID.
*
* \param[in] client_id Client ID to check.
*
* \retval 1 Client ID is non-secure.
* \retval 0 Client ID is secure.
*/
#define TFM_CLIENT_ID_IS_NS(client_id) ((client_id)<0)
/* The mask used for timeout values */
#define PSA_TIMEOUT_MASK PSA_BLOCK
/* FixMe: sort out DEBUG compile option and limit return value options
* on external interfaces */
enum tfm_status_e
{
TFM_SUCCESS = 0,
TFM_PARTITION_BUSY,
TFM_ERROR_SECURE_DOMAIN_LOCKED,
TFM_ERROR_INVALID_PARAMETER,
TFM_ERROR_PARTITION_NON_REENTRANT,
TFM_ERROR_NS_THREAD_MODE_CALL,
TFM_ERROR_NOT_INITIALIZED,
TFM_ERROR_NO_ACTIVE_PARTITION,
TFM_ERROR_INVALID_EXC_MODE,
TFM_SECURE_LOCK_FAILED,
TFM_SECURE_UNLOCK_FAILED,
TFM_ERROR_GENERIC = 0x1F,
};
/*
* Structure to package type, in_len and out_len, it is mainly used for
* psa_call.
*/
struct tfm_control_parameter_t {
int32_t type;
size_t in_len;
size_t out_len;
};
/********************* Secure function declarations ***************************/
/**
* \brief Assign client ID to the current TZ context.
*
* \param[in] ns_client_id The client ID to be assigned to the current
* context.
* \retval TFM_SUCCESS The client ID assigned successfully.
* \retval error code The client ID assignment failed, an error code
* returned according to \ref tfm_status_e.
* \note This function have to be called from handler mode.
*/
enum tfm_status_e tfm_register_client_id (int32_t ns_client_id);
/**
* \brief Retrieve the version of the PSA Framework API that is implemented.
*
* \return The version of the PSA Framework.
*/
uint32_t tfm_psa_framework_version_veneer(void);
/**
* \brief Return version of secure function provided by secure binary.
*
* \param[in] sid ID of secure service.
*
* \return Version number of secure function.
*/
uint32_t tfm_psa_version_veneer(uint32_t sid);
/**
* \brief Connect to secure function.
*
* \param[in] sid ID of secure service.
* \param[in] version Version of SF requested by client.
*
* \return Returns handle to connection.
*/
psa_handle_t tfm_psa_connect_veneer(uint32_t sid, uint32_t version);
/**
* \brief Call a secure function referenced by a connection handle.
*
* \param[in] handle Handle to connection.
* \param[in] ctrl_param Parameter structure, includes reuqest type,
* in_num and out_num.
* \param[in] in_vec Array of input \ref psa_invec structures.
* \param[in/out] out_vec Array of output \ref psa_outvec structures.
*
* \return Returns \ref psa_status_t status code.
*/
psa_status_t tfm_psa_call_veneer(psa_handle_t handle,
const struct tfm_control_parameter_t *ctrl_param,
const psa_invec *in_vec,
psa_outvec *out_vec);
/**
* \brief Close connection to secure function referenced by a connection handle.
*
* \param[in] handle Handle to connection
*
* \return void
*/
void tfm_psa_close_veneer(psa_handle_t handle);
/***************** End Secure function declarations ***************************/
#ifdef __cplusplus
}
#endif
#endif /* __TFM_API_H__ */

View File

@ -0,0 +1,180 @@
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/*
* This is header file of common mailbox objects shared by NSPE and SPE.
* Please refer to tfm_ns_mailbox.h for the definitions only used in NSPE
* mailbox library.
* Please refer to tfm_spe_mailbox.h for the SPE specific definitions and APIs.
*/
#ifndef __TFM_MAILBOX_H__
#define __TFM_MAILBOX_H__
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifdef TFM_MULTI_CORE_MULTI_CLIENT_CALL
#include "device_cfg.h"
#endif
#include "psa/client.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* If multiple outstanding NS PSA Client calls is enabled, multi-core platform
* should define the number of mailbox queue slots NUM_MAILBOX_QUEUE_SLOT in
* platform device_cfg.h.
* Otherwise, NUM_MAILBOX_QUEUE_SLOT is defined as 1.
*/
#ifdef TFM_MULTI_CORE_MULTI_CLIENT_CALL
#ifndef NUM_MAILBOX_QUEUE_SLOT
#error "Error: Platform doesn't define NUM_MAILBOX_QUEUE_SLOT for mailbox queue"
#endif
#if (NUM_MAILBOX_QUEUE_SLOT < 2)
#error "Error: Invalid NUM_MAILBOX_QUEUE_SLOT. The value should be more than 1"
#endif
/*
* The number of slots should be no more than the number of bits in
* mailbox_queue_status_t.
* Here the value is hardcoded. A better way is to define a sizeof() to
* calculate the bits in mailbox_queue_status_t and dump it with pragma message.
*/
#if (NUM_MAILBOX_QUEUE_SLOT > 32)
#error "Error: Invalid NUM_MAILBOX_QUEUE_SLOT. The value should be no more than 32"
#endif
#else /* TFM_MULTI_CORE_MULTI_CLIENT_CALL */
/* Force the number of mailbox queue slots as 1. */
#undef NUM_MAILBOX_QUEUE_SLOT
#define NUM_MAILBOX_QUEUE_SLOT (1)
#endif /* TFM_MULTI_CORE_MULTI_CLIENT_CALL */
/* PSA client call type value */
#define MAILBOX_PSA_FRAMEWORK_VERSION (0x1)
#define MAILBOX_PSA_VERSION (0x2)
#define MAILBOX_PSA_CONNECT (0x3)
#define MAILBOX_PSA_CALL (0x4)
#define MAILBOX_PSA_CLOSE (0x5)
/* Return code of mailbox APIs */
#define MAILBOX_SUCCESS (0)
#define MAILBOX_QUEUE_FULL (INT32_MIN + 1)
#define MAILBOX_INVAL_PARAMS (INT32_MIN + 2)
#define MAILBOX_NO_PERMS (INT32_MIN + 3)
#define MAILBOX_NO_PEND_EVENT (INT32_MIN + 4)
#define MAILBOX_CHAN_BUSY (INT32_MIN + 5)
#define MAILBOX_CALLBACK_REG_ERROR (INT32_MIN + 6)
#define MAILBOX_INIT_ERROR (INT32_MIN + 7)
/*
* This structure holds the parameters used in a PSA client call.
*/
struct psa_client_params_t {
union {
struct {
uint32_t sid;
} psa_version_params;
struct {
uint32_t sid;
uint32_t version;
} psa_connect_params;
struct {
psa_handle_t handle;
int32_t type;
const psa_invec *in_vec;
size_t in_len;
psa_outvec *out_vec;
size_t out_len;
} psa_call_params;
struct {
psa_handle_t handle;
} psa_close_params;
};
};
/* Mailbox message passed from NSPE to SPE to deliver a PSA client call */
struct mailbox_msg_t {
uint32_t call_type; /* PSA client call type */
struct psa_client_params_t params; /* Contain parameters used in PSA
* client call
*/
int32_t client_id; /* Optional client ID of the
* non-secure caller.
* It is required to identify the
* non-secure task when NSPE OS
* enforces non-secure task isolation
*/
};
/* A handle to a mailbox message in use */
typedef int32_t mailbox_msg_handle_t;
#define MAILBOX_MSG_NULL_HANDLE ((mailbox_msg_handle_t)0)
/*
* Mailbox reply structure in non-secure memory
* to hold the PSA client call return result from SPE
*/
struct mailbox_reply_t {
int32_t return_val;
};
/* A single slot structure in NSPE mailbox queue */
struct ns_mailbox_slot_t {
struct mailbox_msg_t msg;
struct mailbox_reply_t reply;
const void *owner; /* Handle of the owner task of this
* slot
*/
bool is_woken; /* Indicate that owner task has been
* or should be woken up, after the
* replied is received.
*/
};
typedef uint32_t mailbox_queue_status_t;
/* NSPE mailbox queue */
struct ns_mailbox_queue_t {
mailbox_queue_status_t empty_slots; /* Bitmask of empty slots */
mailbox_queue_status_t pend_slots; /* Bitmask of slots pending
* for SPE handling
*/
mailbox_queue_status_t replied_slots; /* Bitmask of active slots
* containing PSA client call
* return result
*/
struct ns_mailbox_slot_t queue[NUM_MAILBOX_QUEUE_SLOT];
#ifdef TFM_MULTI_CORE_TEST
uint32_t nr_tx; /* The total number of
* submission of NS PSA Client
* calls from NS task via
* mailbox.
*/
uint32_t nr_used_slots; /* The total number of used
* mailbox queue slots each time
* NS thread requests a mailbox
* queue slot.
*/
#endif
};
#ifdef __cplusplus
}
#endif
#endif /* __TFM_MAILBOX_H__ */

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __TFM_MULTI_CORE_API__
#define __TFM_MULTI_CORE_API__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* \brief Called on the non-secure CPU.
* Flags that the non-secure side has completed its initialization.
* Waits, if necessary, for the secure CPU to flag that it has completed
* its initialization.
*
* \return Return 0 if succeeds.
* \return Otherwise, return specific error code.
*/
int32_t tfm_ns_wait_for_s_cpu_ready(void);
/**
* \brief Synchronisation with secure CPU, platform-specific implementation.
* Flags that the non-secure side has completed its initialization.
* Waits, if necessary, for the secure CPU to flag that it has completed
* its initialization.
*
* \retval Return 0 if succeeds.
* \retval Otherwise, return specific error code.
*/
int32_t tfm_platform_ns_wait_for_s_cpu_ready(void);
/**
* \brief Acquire the multi-core lock for synchronizing PSA client call(s)
* The actual implementation depends on the use scenario.
*
* \return \ref TFM_SUCCESS on success
* \return \ref TFM_ERROR_GENERIC on error
*/
uint32_t tfm_ns_multi_core_lock_acquire(void);
/**
* \brief Release the multi-core lock for synchronizing PSA client call(s)
* The actual implementation depends on the use scenario.
*
* \return \ref TFM_SUCCESS on success
* \return \ref TFM_ERROR_GENERIC on error
*/
uint32_t tfm_ns_multi_core_lock_release(void);
#ifdef __cplusplus
}
#endif
#endif /* __TFM_MULTI_CORE_API__ */

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __TFM_NS_INTERFACE_H__
#define __TFM_NS_INTERFACE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "tfm_api.h"
typedef int32_t (*veneer_fn) (uint32_t arg0, uint32_t arg1,
uint32_t arg2, uint32_t arg3);
/**
* \brief NS interface, veneer function dispatcher
*
* \details This function implements the dispatching mechanism for the
* desired veneer function, to be called with the parameters
* described from arg0 to arg3.
*
* \param[in] fn Function pointer to the veneer function desired
* \param[in] arg0 Argument 0
* \param[in] arg1 Argument 1
* \param[in] arg2 Argument 2
* \param[in] arg3 Argument 3
*
* \return Returns the same return value of the requested veneer function
*/
int32_t tfm_ns_interface_dispatch(veneer_fn fn,
uint32_t arg0, uint32_t arg1,
uint32_t arg2, uint32_t arg3);
/**
* \brief NS interface, Initialise the NS interface
*
* \details This function needs to be called from the NS world to
* properly initialise the NS interface towards TF-M. This
* function will initialise all the objects required for
* runtime dispatching of TF-M requests to services
*
* \return A value according to \ref enum tfm_status_e
*/
enum tfm_status_e tfm_ns_interface_init(void);
#ifdef __cplusplus
}
#endif
#endif /* __TFM_NS_INTERFACE_H__ */

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <stdio.h>
#include "cmsis_compiler.h"
#ifndef __TFM_NS_SVC_H__
#define __TFM_NS_SVC_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Include all the SVC handler headers
*/
#include "tfm_nspm_svc_handler.h"
/**
* \brief Macro to encode an svc instruction
*
*/
#define SVC(code) __ASM volatile("svc %0" : : "I" (code))
/**
* \def LIST_SVC_NSPM
*
* \brief This is an X macro which lists
* the SVC interface exposed by TF-M
* for the NS OS.
*
*/
#define LIST_SVC_NSPM \
X(SVC_TFM_NSPM_REGISTER_CLIENT_ID, tfm_nspm_svc_register_client_id) \
/**
* \brief Numbers associated to each SVC available
*
* \details Start from 1 as 0 is reserved by RTX
*/
enum tfm_svc_num {
SVC_INVALID = 0,
#define X(SVC_ENUM, SVC_HANDLER) SVC_ENUM,
/* SVC API for Services */
#ifdef TFM_NS_CLIENT_IDENTIFICATION
LIST_SVC_NSPM
#endif
#undef X
/* add all the new entries above this line */
SVC_TFM_MAX,
};
/* number of user SVC functions */
#define USER_SVC_COUNT ((uint32_t)SVC_TFM_MAX - 1)
#ifdef __cplusplus
}
#endif
#endif /* __TFM_NS_SVC_H__ */

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __TFM_PLATFORM_API__
#define __TFM_PLATFORM_API__
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include "tfm_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief TFM secure partition platform API version
*/
#define TFM_PLATFORM_API_VERSION_MAJOR (0)
#define TFM_PLATFORM_API_VERSION_MINOR (3)
#define TFM_PLATFORM_API_ID_NV_READ (1010)
#define TFM_PLATFORM_API_ID_NV_INCREMENT (1011)
/*!
* \enum tfm_platform_err_t
*
* \brief Platform service error types
*
*/
enum tfm_platform_err_t {
TFM_PLATFORM_ERR_SUCCESS = 0,
TFM_PLATFORM_ERR_SYSTEM_ERROR,
TFM_PLATFORM_ERR_INVALID_PARAM,
TFM_PLATFORM_ERR_NOT_SUPPORTED,
/* Following entry is only to ensure the error code of int size */
TFM_PLATFORM_ERR_FORCE_INT_SIZE = INT_MAX
};
typedef int32_t tfm_platform_ioctl_req_t;
/*!
* \brief Resets the system.
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t tfm_platform_system_reset(void);
/*!
* \brief Performs a platform-specific service
*
* \param[in] request Request identifier (valid values vary
* based on the platform)
* \param[in] input Input buffer to the requested service (or NULL)
* \param[in,out] output Output buffer to the requested service (or NULL)
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t tfm_platform_ioctl(tfm_platform_ioctl_req_t request,
psa_invec *input,
psa_outvec *output);
/*!
* \brief Increments the given non-volatile (NV) counter by one
*
* \param[in] counter_id NV counter ID.
*
* \return TFM_PLATFORM_ERR_SUCCESS if the value is read correctly. Otherwise,
* it returns TFM_PLATFORM_ERR_SYSTEM_ERROR.
*/
enum tfm_platform_err_t
tfm_platform_nv_counter_increment(uint32_t counter_id);
/*!
* \brief Reads the given non-volatile (NV) counter
*
* \param[in] counter_id NV counter ID.
* \param[in] size Size of the buffer to store NV counter value
* in bytes.
* \param[out] val Pointer to store the current NV counter value.
*
* \return TFM_PLATFORM_ERR_SUCCESS if the value is read correctly. Otherwise,
* it returns TFM_PLATFORM_ERR_SYSTEM_ERROR.
*/
enum tfm_platform_err_t
tfm_platform_nv_counter_read(uint32_t counter_id,
uint32_t size, uint8_t *val);
#ifdef __cplusplus
}
#endif
#endif /* __TFM_PLATFORM_API__ */

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "psa/initial_attestation.h"
#include "tfm_ns_interface.h"
#include "psa/client.h"
#include "psa/crypto_types.h"
#include "psa_manifest/sid.h"
#define IOVEC_LEN(x) (sizeof(x)/sizeof(x[0]))
psa_status_t
psa_initial_attest_get_token(const uint8_t *auth_challenge,
size_t challenge_size,
uint8_t *token_buf,
size_t token_buf_size,
size_t *token_size)
{
psa_handle_t handle = PSA_NULL_HANDLE;
psa_status_t status;
psa_invec in_vec[] = {
{auth_challenge, challenge_size}
};
psa_outvec out_vec[] = {
{token_buf, token_buf_size}
};
handle = psa_connect(TFM_ATTEST_GET_TOKEN_SID,
TFM_ATTEST_GET_TOKEN_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_HANDLE_TO_ERROR(handle);
}
status = psa_call(handle, PSA_IPC_CALL,
in_vec, IOVEC_LEN(in_vec),
out_vec, IOVEC_LEN(out_vec));
psa_close(handle);
if (status == PSA_SUCCESS) {
*token_size = out_vec[0].len;
}
return status;
}
psa_status_t
psa_initial_attest_get_token_size(size_t challenge_size,
size_t *token_size)
{
psa_handle_t handle = PSA_NULL_HANDLE;
psa_status_t status;
psa_invec in_vec[] = {
{&challenge_size, sizeof(challenge_size)}
};
psa_outvec out_vec[] = {
{token_size, sizeof(size_t)}
};
handle = psa_connect(TFM_ATTEST_GET_TOKEN_SIZE_SID,
TFM_ATTEST_GET_TOKEN_SIZE_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_HANDLE_TO_ERROR(handle);
}
status = psa_call(handle, PSA_IPC_CALL,
in_vec, IOVEC_LEN(in_vec),
out_vec, IOVEC_LEN(out_vec));
psa_close(handle);
return status;
}
psa_status_t
tfm_initial_attest_get_public_key(uint8_t *public_key,
size_t public_key_buf_size,
size_t *public_key_len,
psa_ecc_curve_t *elliptic_curve_type)
{
psa_handle_t handle = PSA_NULL_HANDLE;
psa_status_t status;
psa_outvec out_vec[] = {
{.base = public_key, .len = public_key_buf_size},
{.base = elliptic_curve_type, .len = sizeof(*elliptic_curve_type)},
{.base = public_key_len, .len = sizeof(*public_key_len)}
};
handle = psa_connect(TFM_ATTEST_GET_PUBLIC_KEY_SID,
TFM_ATTEST_GET_PUBLIC_KEY_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_HANDLE_TO_ERROR(handle);
}
status = psa_call(handle, PSA_IPC_CALL,
NULL, 0,
out_vec, IOVEC_LEN(out_vec));
psa_close(handle);
return status;
}

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "psa/internal_trusted_storage.h"
#include "tfm_api.h"
#include "psa/client.h"
#include "psa_manifest/sid.h"
#define IOVEC_LEN(x) (sizeof(x)/sizeof(x[0]))
psa_status_t psa_its_set(psa_storage_uid_t uid,
size_t data_length,
const void *p_data,
psa_storage_create_flags_t create_flags)
{
psa_status_t status;
psa_handle_t handle;
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) },
{ .base = p_data, .len = data_length },
{ .base = &create_flags, .len = sizeof(create_flags) }
};
handle = psa_connect(TFM_ITS_SET_SID, TFM_ITS_SET_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_ERROR_GENERIC_ERROR;
}
status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), NULL, 0);
psa_close(handle);
if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return status;
}
psa_status_t psa_its_get(psa_storage_uid_t uid,
size_t data_offset,
size_t data_size,
void *p_data,
size_t *p_data_length)
{
psa_status_t status;
psa_handle_t handle;
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) },
{ .base = &data_offset, .len = sizeof(data_offset) }
};
psa_outvec out_vec[] = {
{ .base = p_data, .len = data_size }
};
if (p_data_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
handle = psa_connect(TFM_ITS_GET_SID, TFM_ITS_GET_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_ERROR_GENERIC_ERROR;
}
status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), out_vec,
IOVEC_LEN(out_vec));
psa_close(handle);
if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) {
return PSA_ERROR_INVALID_ARGUMENT;
}
*p_data_length = out_vec[0].len;
return status;
}
psa_status_t psa_its_get_info(psa_storage_uid_t uid,
struct psa_storage_info_t *p_info)
{
psa_status_t status;
psa_handle_t handle;
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) }
};
psa_outvec out_vec[] = {
{ .base = p_info, .len = sizeof(*p_info) }
};
handle = psa_connect(TFM_ITS_GET_INFO_SID, TFM_ITS_GET_INFO_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_ERROR_GENERIC_ERROR;
}
status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), out_vec,
IOVEC_LEN(out_vec));
psa_close(handle);
if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return status;
}
psa_status_t psa_its_remove(psa_storage_uid_t uid)
{
psa_status_t status;
psa_handle_t handle;
psa_invec in_vec[] = {
{ .base = &uid, .len = sizeof(uid) }
};
handle = psa_connect(TFM_ITS_REMOVE_SID, TFM_ITS_REMOVE_VERSION);
if (!PSA_HANDLE_IS_VALID(handle)) {
return PSA_ERROR_GENERIC_ERROR;
}
status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), NULL, 0);
psa_close(handle);
return status;
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <stdbool.h>
#include "tfm_platform_api.h"
#include "psa_manifest/sid.h"
enum tfm_platform_err_t tfm_platform_system_reset(void)
{
psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
psa_handle_t handle = PSA_NULL_HANDLE;
handle = psa_connect(TFM_SP_PLATFORM_SYSTEM_RESET_SID,
TFM_SP_PLATFORM_SYSTEM_RESET_VERSION);
if (handle <= 0) {
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
}
status = psa_call(handle, PSA_IPC_CALL,
NULL, 0, NULL, 0);
psa_close(handle);
if (status < PSA_SUCCESS) {
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
} else {
return (enum tfm_platform_err_t) status;
}
}
enum tfm_platform_err_t
tfm_platform_ioctl(tfm_platform_ioctl_req_t request,
psa_invec *input, psa_outvec *output)
{
tfm_platform_ioctl_req_t req = request;
struct psa_invec in_vec[2] = { {0} };
size_t inlen, outlen;
psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
psa_handle_t handle = PSA_NULL_HANDLE;
in_vec[0].base = &req;
in_vec[0].len = sizeof(req);
if (input != NULL) {
in_vec[1].base = input->base;
in_vec[1].len = input->len;
inlen = 2;
} else {
inlen = 1;
}
if (output != NULL) {
outlen = 1;
} else {
outlen = 0;
}
handle = psa_connect(TFM_SP_PLATFORM_IOCTL_SID,
TFM_SP_PLATFORM_IOCTL_VERSION);
if (handle <= 0) {
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
}
status = psa_call(handle, PSA_IPC_CALL,
in_vec, inlen,
output, outlen);
psa_close(handle);
if (status < PSA_SUCCESS) {
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
} else {
return (enum tfm_platform_err_t) status;
}
}

View File

@ -54,6 +54,8 @@
#define MBEDTLS_PSA_CRYPTO_STORAGE_C
#define MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C
#undef MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#endif
/*

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
#if DEVICE_TRNG
#if defined(DEVICE_TRNG) || defined(FEATURE_PSA)
#include "hal/trng_api.h"
#include "platform/SingletonPtr.h"
@ -24,6 +24,7 @@ SingletonPtr<PlatformMutex> mbedtls_mutex;
extern "C"
int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t *olen ) {
#if defined(DEVICE_TRNG)
trng_t trng_obj;
mbedtls_mutex->lock();
trng_init(&trng_obj);
@ -31,6 +32,12 @@ int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t
trng_free(&trng_obj);
mbedtls_mutex->unlock();
return ret;
#else /* defined(FEATURE_PSA) */
mbedtls_mutex->lock();
int ret = trng_get_bytes(NULL, output, len, olen);
mbedtls_mutex->unlock();
return ret;
#endif
}
#endif

View File

@ -18,6 +18,7 @@
#ifndef MBEDTLS_DEVICE_H
#define MBEDTLS_DEVICE_H
#ifndef MXCRYPTO_DISABLED
/* Currently this target supports SHA1 */
// #define MBEDTLS_SHA1_C
@ -44,4 +45,5 @@
#define MBEDTLS_ECDSA_SIGN_ALT
#define MBEDTLS_ECDSA_VERIFY_ALT
#endif /* #ifndef MXCRYPTO_DISABLED */
#endif /* MBEDTLS_DEVICE_H */

View File

@ -23,7 +23,7 @@
#include <stddef.h>
#include "device.h"
#if DEVICE_TRNG
#if defined(DEVICE_TRNG) || defined(FEATURE_PSA)
/** TRNG HAL structure. trng_s is declared in the target's HAL
*/

View File

@ -41,6 +41,10 @@
},
"MCU_PSOC6": {
"internal_size": "0x10000"
},
"CYTFM_064B0S2_4343W": {
"internal_size": "0x8000",
"internal_base_address": "0x10168000"
}
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2019, Cypress Semiconductor Corporation, All Rights Reserved
* SPDX-License-Identifier: LicenseRef-PBL
*
* This file and the related binary are licensed under the
* Permissive Binary License, Version 1.0 (the "License");
* you may not use these files except in compliance with the License.
*
* You may obtain a copy of the License here:
* LICENSE-permissive-binary-license-1.0.txt and at
* https://www.mbed.com/licenses/PBL-1.0
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDED_NVRAM_IMAGE_H_
#define INCLUDED_NVRAM_IMAGE_H_
#include <string.h>
#include <stdint.h>
#include "generated_mac_address.txt"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Character array of NVRAM image
* Generated from cyw9cy8cmod-064b0s2-4343w_P100_724315.txt
*/
static const char wifi_nvram_image[] =
"NVRAMRev=$Rev: 724315 $" "\x00"
"manfid=0x2d0" "\x00"
"prodid=0x087d" "\x00"
"vendid=0x14e4" "\x00"
"devid=0x43e2" "\x00"
"boardtype=0x087d" "\x00"
"boardrev=0x1100" "\x00"
"boardnum=22" "\x00"
NVRAM_GENERATED_MAC_ADDRESS "\x00"
"sromrev=11" "\x00"
"boardflags=0x00404201" "\x00"
"boardflags3=0x08000000" "\x00"
"xtalfreq=37400" "\x00"
"nocrc=1" "\x00"
"ag0=255" "\x00"
"aa2g=1" "\x00"
"ccode=ALL" "\x00"
"" "\x00"
"swdiv_en=1" "\x00"
"swdiv_gpio=2" "\x00"
"" "\x00"
"pa0itssit=0x20" "\x00"
"extpagain2g=0" "\x00"
"" "\x00"
"pa2ga0=-168,6393,-757" "\x00"
"AvVmid_c0=0x0,0xc8" "\x00"
"AvVmidIQcal=0x2,0xa8" "\x00"
"cckpwroffset0=5" "\x00"
"" "\x00"
"maxp2ga0=84" "\x00"
"txpwrbckof=6" "\x00"
"cckbw202gpo=0" "\x00"
"legofdmbw202gpo=0x66111111" "\x00"
"mcsbw202gpo=0x77711111" "\x00"
"propbw202gpo=0xdd" "\x00"
"" "\x00"
"ofdmdigfilttype=18" "\x00"
"ofdmdigfilttypebe=18" "\x00"
"papdmode=1" "\x00"
"papdvalidtest=1" "\x00"
"pacalidx2g=32" "\x00"
"papdepsoffset=-36" "\x00"
"papdendidx=61" "\x00"
"" "\x00"
"" "\x00"
"wl0id=0x431b" "\x00"
"" "\x00"
"deadman_to=0xffffffff" "\x00"
"muxenab=0x11" "\x00"
"" "\x00"
"spurconfig=0x3 " "\x00"
"" "\x00"
"rssicorrnorm=1" "\x00"
"\x00\x00";
#ifdef __cplusplus
} /*extern "C" */
#endif
#else /* ifndef INCLUDED_NVRAM_IMAGE_H_ */
#error Wi-Fi NVRAM image included twice
#endif /* ifndef INCLUDED_NVRAM_IMAGE_H_ */

View File

@ -0,0 +1,36 @@
/*******************************************************************************
* File Name: cycfg.c
*
* Description:
* Wrapper function to initialize all generated code.
* This file was automatically generated and should not be modified.
* cfg-backend-cli: 1.2.0.1483
* Device Support Library (libs/psoc6pdl): 1.6.0.4266
*
********************************************************************************
* Copyright 2017-2019 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#include "cycfg.h"
void init_cycfg_all(void)
{
init_cycfg_system();
init_cycfg_clocks();
init_cycfg_routing();
init_cycfg_peripherals();
init_cycfg_pins();
}

View File

@ -0,0 +1,49 @@
/*******************************************************************************
* File Name: cycfg.h
*
* Description:
* Simple wrapper header containing all generated files.
* This file was automatically generated and should not be modified.
* cfg-backend-cli: 1.2.0.1483
* Device Support Library (libs/psoc6pdl): 1.6.0.4266
*
********************************************************************************
* Copyright 2017-2019 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#if !defined(CYCFG_H)
#define CYCFG_H
#if defined(__cplusplus)
extern "C" {
#endif
#include "cycfg_notices.h"
#include "cycfg_system.h"
#include "cycfg_clocks.h"
#include "cycfg_routing.h"
#include "cycfg_peripherals.h"
#include "cycfg_pins.h"
void init_cycfg_all(void);
#if defined(__cplusplus)
}
#endif
#endif /* CYCFG_H */

View File

@ -0,0 +1,26 @@
/*******************************************************************************
* File Name: cycfg.timestamp
*
* Description:
* Sentinel file for determining if generated source is up to date.
* This file was automatically generated and should not be modified.
* cfg-backend-cli: 1.2.0.1483
* Device Support Library (libs/psoc6pdl): 1.6.0.4266
*
********************************************************************************
* Copyright 2017-2019 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/

View File

@ -0,0 +1,47 @@
/*******************************************************************************
* File Name: cycfg_clocks.c
*
* Description:
* Clock configuration
* This file was automatically generated and should not be modified.
* cfg-backend-cli: 1.2.0.1483
* Device Support Library (libs/psoc6pdl): 1.6.0.4266
*
********************************************************************************
* Copyright 2017-2019 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#include "cycfg_clocks.h"
#if defined (CY_USING_HAL)
const cyhal_resource_inst_t CYBSP_CSD_CLK_DIV_obj =
{
.type = CYHAL_RSC_CLOCK,
.block_num = CYBSP_CSD_CLK_DIV_HW,
.channel_num = CYBSP_CSD_CLK_DIV_NUM,
};
#endif //defined (CY_USING_HAL)
void init_cycfg_clocks(void)
{
Cy_SysClk_PeriphDisableDivider(CY_SYSCLK_DIV_8_BIT, 0U);
Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, 0U, 0U);
Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, 0U);
#if defined (CY_USING_HAL)
cyhal_hwmgr_reserve(&CYBSP_CSD_CLK_DIV_obj);
#endif //defined (CY_USING_HAL)
}

View File

@ -0,0 +1,55 @@
/*******************************************************************************
* File Name: cycfg_clocks.h
*
* Description:
* Clock configuration
* This file was automatically generated and should not be modified.
* cfg-backend-cli: 1.2.0.1483
* Device Support Library (libs/psoc6pdl): 1.6.0.4266
*
********************************************************************************
* Copyright 2017-2019 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#if !defined(CYCFG_CLOCKS_H)
#define CYCFG_CLOCKS_H
#include "cycfg_notices.h"
#include "cy_sysclk.h"
#if defined (CY_USING_HAL)
#include "cyhal_hwmgr.h"
#endif //defined (CY_USING_HAL)
#if defined(__cplusplus)
extern "C" {
#endif
#define CYBSP_CSD_CLK_DIV_ENABLED 1U
#define CYBSP_CSD_CLK_DIV_HW CY_SYSCLK_DIV_8_BIT
#define CYBSP_CSD_CLK_DIV_NUM 0U
#if defined (CY_USING_HAL)
extern const cyhal_resource_inst_t CYBSP_CSD_CLK_DIV_obj;
#endif //defined (CY_USING_HAL)
void init_cycfg_clocks(void);
#if defined(__cplusplus)
}
#endif
#endif /* CYCFG_CLOCKS_H */

View File

@ -0,0 +1,32 @@
/*******************************************************************************
* File Name: cycfg_notices.h
*
* Description:
* Contains warnings and errors that occurred while generating code for the
* design.
* This file was automatically generated and should not be modified.
* cfg-backend-cli: 1.2.0.1483
* Device Support Library (libs/psoc6pdl): 1.6.0.4266
*
********************************************************************************
* Copyright 2017-2019 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#if !defined(CYCFG_NOTICES_H)
#define CYCFG_NOTICES_H
#endif /* CYCFG_NOTICES_H */

View File

@ -0,0 +1,38 @@
/*******************************************************************************
* File Name: cycfg_peripherals.c
*
* Description:
* Peripheral Hardware Block configuration
* This file was automatically generated and should not be modified.
* cfg-backend-cli: 1.2.0.1483
* Device Support Library (libs/psoc6pdl): 1.6.0.4266
*
********************************************************************************
* Copyright 2017-2019 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#include "cycfg_peripherals.h"
cy_stc_csd_context_t cy_csd_0_context =
{
.lockKey = CY_CSD_NONE_KEY,
};
void init_cycfg_peripherals(void)
{
Cy_SysClk_PeriphAssignDivider(PCLK_CSD_CLOCK, CY_SYSCLK_DIV_8_BIT, 0U);
}

Some files were not shown because too many files have changed in this diff Show More