Secure Request Framework
Secure Request Pool Library

General Description

Secure Request Pool Library provides an implementation of secure request pool mtb_srf_pool_t, which is composed of multiple secure request objects mtb_srf_request_ns_t.

Secure request objects need to be accessible by both the secure and non-secure world. In practice, this means that they should be allocated out of the "shared memory" region rather than e.g. off the stack. This, in turn, means that any RAM which is allocated for secure request pool description struct mtb_srf_pool_t is statically allocated for the lifetime of the program. Therefore, it would be inefficient for every secure request client to allocate its own secure request object. There needs to be a means for sharing. This need is satisfied by a secure request pool, which allows multiple secure request clients to share a small number of pre-allocated secure request pool description struct. A secure request pool is specific to a particular non-secure processing environment. I.e. in a system where both the CM33_NS and the CM55 are making secure requests, there would be two secure request pools, one for the CM33_NS and one for the CM55. Usage of this mechanism is optional. If needed to satisfy some special case, a secure request client can allocate their own custom secure request object and use that instead.

Features:

Prerequisites

There are three parameters which define a secure request pool:

Pool initialization can be performed explicitly via the mtb_srf_pool_init function.

A secure request pool consolidates three user-provided memory allocations:

The input and output argument arrays are shared equally between all requests in the pool. For example, if a secure reqest pool contains three entries and args_in_length is 12, then each secure request would support up to 4 input arguments. The benefit is that the pool initialization process is simpler because there are fewer allocations required

A default pool is defined in the BSP and initialized as part of the non-secure application initialization. This default pool is expected to be sufficient for the majority of uses cases, so users should generally not need to do any manual allocation or management of pools.

Note
the default secure request pool setup is only performed when we are not running in the secure world. This is because the secure request pools are the means by which the non-secure world submits requests to the secure world. There would be no reason for the secure world to submit a request to itself.

Secure request object allocation is performed via the mtb_srf_pool_allocate function. Secure request object free is performed via the mtb_srf_pool_free function.

Code Snippets

Init sequence for secure request pool

#define MY_INPUT_ARRAY_SIZE (6UL) // Means 6 bytes
#define MY_OUTPUT_ARRAY_SIZE (2UL) // Means 2 bytes
#define MY_NUM_REQ_IN_POOL (6UL)
CY_SECTION_SHAREDMEM mtb_srf_pool_t pool;
CY_SECTION_SHAREDMEM static uint32_t pool_memory[(MTB_SRF_POOL_ENTRY_SIZE(MTB_SRF_MAX_ARG_IN_SIZE,
MTB_SRF_MAX_ARG_OUT_SIZE)
* MTB_SRF_POOL_SIZE) / sizeof(uint32_t)];
//--------------------------------------------------------------------------------------------------
// snippet_mtb_srf_pool_init_api
//--------------------------------------------------------------------------------------------------
cy_rslt_t snippet_mtb_srf_pool_init_api(void)
{
cy_rslt_t result = CY_RSLT_SUCCESS;
// Other initialization steps
result = mtb_srf_pool_init(&pool,
&pool_memory[0],
MY_NUM_REQ_IN_POOL,
MY_INPUT_ARRAY_SIZE,
MY_OUTPUT_ARRAY_SIZE);
(void)result;
return result;
}
cy_rslt_t mtb_srf_pool_init(mtb_srf_pool_t *pool, uint32_t *allocated_mem, size_t num_entries, size_t input_len_per_entry, size_t output_len_per_entry)
Initializes an secure request pool instance.
Definition: mtb_srf_pool.c:73
#define MTB_SRF_POOL_ENTRY_SIZE(input_values_length, output_values_length)
A tool to calculate how much memory to provide for a pool.
Definition: mtb_srf_pool_init.h:71

Allocation/Free operation

cy_rslt_t snippet_mtb_srf_pool_allocate_free_api(void)
{
cy_rslt_t result = CY_RSLT_SUCCESS;
// Assuming an already initialized request pool
mtb_srf_invec_ns_t* inVec = NULL;
mtb_srf_outvec_ns_t* outVec = NULL;
uint8_t inVec_cnt = 1;
uint8_t outVec_cnt = 1;
// If it is in ISR, timeout_us should be zero.
uint32_t timeout_us = 2000;
result = mtb_srf_pool_allocate(&cy_pdl_srf_default_pool, &inVec, &outVec, timeout_us);
if (result != CY_RSLT_SUCCESS)
{
return result;
}
// Populate the mtb_srf_request_ns_t structure, then submit it
// See snippet_mtb_srf_submit_request_api for example on population
result = mtb_srf_request_submit(inVec, inVec_cnt, outVec, outVec_cnt);
// Free to allow other assets to reuse the memory
result = mtb_srf_pool_free(&cy_pdl_srf_default_pool, inVec, outVec);
return result;
}
cy_rslt_t mtb_srf_pool_allocate(mtb_srf_pool_t *pool, mtb_srf_invec_ns_t **inVec, mtb_srf_outvec_ns_t **outVec, uint32_t timeout_us)
Allocate secure request object within an secure request pool.
Definition: mtb_srf_pool.c:104
cy_rslt_t mtb_srf_pool_free(mtb_srf_pool_t *pool, const mtb_srf_invec_ns_t *inVec, const mtb_srf_outvec_ns_t *outVec)
Free secure request object within an secure request pool.
Definition: mtb_srf_pool.c:177
An input vector - a section of memory to be used along with the length.
Definition: mtb_srf_iovec.h:72
An output vector - a section of memory to be used along with the length.
Definition: mtb_srf_iovec.h:79
cy_rslt_t mtb_srf_request_submit(mtb_srf_invec_ns_t *inVec_ns, uint8_t inVec_cnt_ns, mtb_srf_outvec_ns_t *outVec_ns, uint8_t outVec_cnt_ns)
Submit a request from the non-secure side to the secure.

Macros

#define MTB_SRF_ROUND_UP(N, S)   ((((N) + (S) - 1UL) / (S)) * (S))
 Round up.
 
#define MTB_SRF_POOL_ALIGNMENT   (4UL)
 Address alignment value of pool in bytes.
 

Functions

cy_rslt_t mtb_srf_pool_allocate (mtb_srf_pool_t *pool, mtb_srf_invec_ns_t **inVec, mtb_srf_outvec_ns_t **outVec, uint32_t timeout_us)
 Allocate secure request object within an secure request pool. More...
 
cy_rslt_t mtb_srf_pool_free (mtb_srf_pool_t *pool, const mtb_srf_invec_ns_t *inVec, const mtb_srf_outvec_ns_t *outVec)
 Free secure request object within an secure request pool. More...
 
cy_rslt_t mtb_srf_pool_get_entry_len (mtb_srf_pool_t *pool, size_t *input_len_per_entry, size_t *output_len_per_entry)
 Get the input and output length per entry configuration of a pool that were set at initalization. More...
 

Function Documentation

◆ mtb_srf_pool_allocate()

cy_rslt_t mtb_srf_pool_allocate ( mtb_srf_pool_t *  pool,
mtb_srf_invec_ns_t **  inVec,
mtb_srf_outvec_ns_t **  outVec,
uint32_t  timeout_us 
)

Allocate secure request object within an secure request pool.

Parameters
[in,out]poolThe pool object that was populated by mtb_srf_pool_init
[in,out]inVecPointer to an array of input vectors for the pool to allocate
[in,out]outVecPointer to an array of output vectors for the pool to allocate
[in]timeout_usTimeout to wait in microsecond. Set to 0 to perform no wait.
Note
The timeout_us must always be 0 if allocation is invoked from an interrupt context.
Returns
the status of allocate request

Allocate secure request object within an secure request pool.

◆ mtb_srf_pool_free()

cy_rslt_t mtb_srf_pool_free ( mtb_srf_pool_t *  pool,
const mtb_srf_invec_ns_t inVec,
const mtb_srf_outvec_ns_t outVec 
)

Free secure request object within an secure request pool.

Parameters
[in,out]poolThe pool object that was populated by mtb_srf_pool_init
[in]inVecPointer to an input vectors for the pool to free
[in]outVecPointer to an output vectors for the pool to free. This must belong to the same request as inVec
Returns
the status of free request

Free secure request object within an secure request pool.

◆ mtb_srf_pool_get_entry_len()

cy_rslt_t mtb_srf_pool_get_entry_len ( mtb_srf_pool_t *  pool,
size_t *  input_len_per_entry,
size_t *  output_len_per_entry 
)

Get the input and output length per entry configuration of a pool that were set at initalization.

Parameters
[in,out]poolThe pool object that was populated by mtb_srf_pool_init
[in,out]input_len_per_entryValue to store the input length per entry
[in,out]output_len_per_entryValue to store the output length per entry
Returns
the status of the initialization