物联网安全-基于Cortex-M处理器的TrustZone技术简介(2)
Secure/Non-secure转换
之前介绍了如何利用SAU和IDAU配置一块内存区域的安全属性,用户可以在安全区和非安全区定义相应的函数,TrustZone技术允许两种状态下的函数相互调用,在进行相互调用时需要用到几个特殊指令:SG、BXNS、BLXNS, 如下表所示。
执行状态切换时的具体操作如下图所示:
SG指令:用于从非安全状态切换到安全状态,是从非安全区跳转到NSC区域之后执行的第一条指令。
BXNS指令: 用于从安全状态返回到非安全状态。
BLXNS指令: 用于在安全状态下调用非安全函数。
这里介绍两种特殊的函数:Entry function和Non-secure function。
其中,Entry function是指那些可以被非安全函数调用的安全函数;Non-secure function是指那些可以被安全函数调用的非安全函数。
用户在实现两种状态下函数的相互调用时,不需要额外关注该执行哪条特殊指令(SG/BXNS/BLXNS),而只需要将那些被调用的函数定义为Entry function或 Non-secure function即可。下面简单介绍如何定义以及使用Entry function和Non-secure function。
1. Entry function
Entry function需要用“ attribute((cmse_nonsecure_entry)) ”属性修饰,举例如下:
/* Entry function */
int func1(int x) __attribute__((cmse_nonsecure_entry)) {
return x+3;
}
此时func1()已经被定义为了entry function,在非安全内存中调用entry function的方法与调用普通的非安全函数的方法是相同的,如下所示:
/* Call entry function func1 */
val1 = func1 (1);
这样即可实现非安全函数调用安全函数的功能。
2. Non-secure function call
Non-secure function函数定义如下所示:
typedef void __attribute_((cmse_nonsecure_call)) nsfunc(void);
在安全内存中的调用non-secure function的方法如下:
nsfunc *FunctionPointer;
FunctionPointer=cmse_nsfptr_create((nsfunc *)(0x21000248u));
If (cmse_is_nsfptr(FunctionPointer))
FunctionPointer();
这样即可实现在安全函数中调用0x21000248u处的非安全函数。
工作流程
TrustZone的工作流程:
安全属性划分:
1. FLASH,RAM,ROM
2. 外设,GPIO
遵循下面规则:
SAU + IDAU | Trusted Execution Environment Register | End Result |
---|---|---|
Non-secure | Non-secure | Non-secure |
Non-secure | Secure | Secure |
Secure | Non-secure | ERROR |
Secure | Secure | Secure |
3. 中断
根据 《Armv8-M Architecture Reference Manual》 可知中断默认安全,通过NVIC->ITNS修改安全属性。
水平有限,难免有错误之处。感谢NXP官方公众号对TrustZone技术的讲解。