This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

secure function call from none-secure side thread mode

In current trusted-firmware-m version, secure functions such as secure storage service functions can only be called from handler mode.

But I have a question about the call sequence, when none secure side call sst_get_handle sevice function, it will first call svc instruction to enter handler mode, and in the svc handler, there will be the call sequence as follows:

svc hanlder()  -> sst_veneer_get_handle->TFM_CORE_SFN_REQUEST(tfm_core_partition_request)

__attribute__ ((always_inline)) __STATIC_INLINE
int32_t tfm_core_partition_request(uint32_t id, void *fn,
        int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4)
{
    int32_t args[4] = {arg1, arg2, arg3, arg4};
    struct tfm_sfn_req_s desc, *desc_ptr = &desc;

    desc.sp_id = id;
     desc.sfn = fn;
    desc.args = args;
    desc.ns_caller = cmse_nonsecure_caller();
    desc.exc_num = __get_active_exc_num();   // what is the exc_num here? I guess it will not be EXC_NUM_THREAD_MODE, right?
     ...
    return tfm_core_sfn_request_function(desc_ptr);
}

->tfm_core_sfn_request_function ->tfm_core_call_sfn(desc_ptr){
#if TFM_LVL == 1
    if ((desc_ptr->exc_num == EXC_NUM_THREAD_MODE) && (!tfm_secure_api_init)) {
        /* Secure partition to secure partition call in TFM level 1 */
        int32_t res;
        int32_t *args = desc_ptr->args;
        int32_t retVal = desc_ptr->sfn(args[0], args[1], args[2], args[3]);
        /* return handler should restore original exc_return value... */
        res = tfm_pop_lock(NULL);
        if (res == TFM_SUCCESS) {
             /* If unlock successful, pass SS return value to caller */
             res = retVal;
        } else {
            /* Unlock errors indicate ctx database corruption or unknown
            * anomalies. Halt execution
            */
                ERROR_MSG("Secure API error during unlock!");
            tfm_secure_api_error_handler();
        }
        return res;
    }
#endif

    /* Exception return to partition start */
    return tfm_core_exc_return_to_sfn();
}

My question is whether desc_ptr->sfn(args[0], args[1], args[2], args[3]); can be executed or not in the last tfm_core_call_sfn call if TFM_LVL =1. I think desc_ptr->exc_num is not EXC_NUM_THREAD_MODE because the call sequence is from none-secure side svc handler, please let me know if I am wrong, thanks.

Parents
  • desc.exc_num = __get_active_exc_num();          // what is the exc_num here? I guess it will not be EXC_NUM_THREAD_MODE, right?

    That is correct. exc_num, i.e. exception number will be the ISR value at the point of call. ISR is not mapped between security states, so the non-secure SVC handler call to this veneer will result in an exc_num value of 11 (EXC_NUM_SVCALL).

    In tfm_core_call_sfn(desc_ptr), since desc_ptr->exc_num != EXC_NUM_THREAD_MODE, the entire

    if ((desc_ptr->exc_num == EXC_NUM_THREAD_MODE) && (!tfm_secure_api_init)) {

    block is skipped (note that there's no corresponding else statement). This results in the code below being executed:

        /* Exception return to partition start */
        return tfm_core_exc_return_to_sfn();

    That will perform a secure exception return to the context prepared for secure function execution, so desc_ptr->sfn(…) will be executed.

    Regards

    Miklos

Reply
  • desc.exc_num = __get_active_exc_num();          // what is the exc_num here? I guess it will not be EXC_NUM_THREAD_MODE, right?

    That is correct. exc_num, i.e. exception number will be the ISR value at the point of call. ISR is not mapped between security states, so the non-secure SVC handler call to this veneer will result in an exc_num value of 11 (EXC_NUM_SVCALL).

    In tfm_core_call_sfn(desc_ptr), since desc_ptr->exc_num != EXC_NUM_THREAD_MODE, the entire

    if ((desc_ptr->exc_num == EXC_NUM_THREAD_MODE) && (!tfm_secure_api_init)) {

    block is skipped (note that there's no corresponding else statement). This results in the code below being executed:

        /* Exception return to partition start */
        return tfm_core_exc_return_to_sfn();

    That will perform a secure exception return to the context prepared for secure function execution, so desc_ptr->sfn(…) will be executed.

    Regards

    Miklos

Children
No data