(4)Tokenization。国际芯片卡标准化组织EMVCo定义了智能卡支付,也定义了一个Token(即令牌),在实际卡应用中作为代用品。商家可以使用同样的方式处理卡和令牌,这意味着没有必要改变已经部署和安装的PoS(Point of Sale)终端。这种巧妙的处理通过一个令牌服务提供商TSP(Token Service Provider)进行,TSP拥有实际的卡信息。签发令牌Tokens时,可以灵活的作出一些限制,如只能供一些特定的商家使用、只能在线使用、只能线下使用,还可以对令牌的值、时间和地点作出限制,如根据设备的安全等级来确定其有效时间。必要时,令牌可以销毁和重新签发。Tokens解决方法可以保证与已有的基础设施兼容,节省开支。和HCE一起工作,令牌可以解决可用性的问题,当移动网络不稳定时,令牌本地存储在移动手机上,可以离线的进行支付。EMVCo支付令牌规范技术框架v1.0提供了在设备上进行令牌安全存储的例子,例如可以存放在一个可信执行环境TEE中。另外,令牌可以通过任何通道进行使用,如NFC HCE、网络交易以及蓝牙Beacons,因此该技术不只限于PoS终端。
芯片制造商可以集成t-base TEE,为PIN码、指纹和证书等提供隔离和保护,防止来自主操作系统环境的威胁。t-base使用ARM TrustZone安全隔离特征(目前SoC处理器中已经存在),并使用微内核和安全域隔离来保证可信apps的隔离。Trustonic为领先的芯片制造商提供集成的服务和支持,供应智能连接设备市场。
设备制造商在生产线上设置Trustonic t-kph密钥配置主机系统(t-kph Key Provisioning Host system)。Trustonic为每个设备的每个t-base TEE创建一个信任根(root of trust),并同步记录到Trustonic的t-sek目录中。
安全应用开发者使用Trustonic提供的t-sdk软件开发工具包(可以通过Trustonic t-dev开发者计划获得)创建可信apps,可以运行在t-base中。
服务提供商通过Trustonic的t-sek服务许可工具包(Service Enablement Kit)连接到t-base内的安全域,t-sek可以授权部署应用到安全域。
t-base的用户认证:TEE的能力之一是可以安全连接外设,可以保护用户的输入,如FIDO的UAF认证子(触屏或者指纹传感器)。通过触屏可以输入用户PIN码,通过可信用户接口进行。生物认证可以作为另外一个认证因子,TEE可以安全存储一个注册的指纹信息,并在可信环境中进行指纹的匹配。随着技术的发展,TEE还可以保护更多的认证因子。
t-base的安全存储:软件保护容易被攻破,需要使用一个基于硬件的信任根来保护设备上的敏感资产。硬件信任根只能通过TEE访问,用来加密存储在其它大规模存储设备上的敏感数据。硬件信任根不会在TEE之外被访问,如主机OS就无法获取访问硬件信任根的接口。其可以存储临时的授权令牌或者存储用于解密beacon消息的密钥。这些主要靠t-base TEE保护设备上的密钥。
t-base的安全通信:使用一个安全存储的密钥,一个可信app可以构建和云服务的一个可靠安全的连接,也可以构建与本地设备(如安全元素SE)之间的一个安全通道。TEE保护建立这些安全连接的私钥、秘密密钥和随机数生成器,可以和任何终端设备构建安全连接。
t-base的安全显示:通过控制对显示驱动外设的访问,TEE能够在设备上安全的显示数据。TEE隔离显示缓存和信息,使得其不会被主机OS篡改,真正达到“what you see is what you sign”。
由于指纹的采集、传输走的是独立的加密物理通道,指纹的处理、比对发生在TEE中,而TEE和手机操作系统是完全隔离的。因此,指纹采集和识别的过程不会被手机中的病毒、恶意程序干扰,即便手机被Root获取了最高权限也依旧无法获取TEE区内的任何数据资料。
在指纹的录入过程中,指纹图像会直接在TEE中被处理成数字信息,经过提取、加密等一系列复杂的措施,最终将一段加密后的内存保存下来,才算完成指纹录入的全过程。在指纹的验证过程中,用户的指纹信息同样会进入TEE中进行处理,并将之前录入的指纹数据读取到TEE中进行解密,然后才会进行指纹信息匹配。
在该过程中,指纹信息的所有处理过程均发生在TEE区,由于指纹从图像信息转成数字信息的过程不可逆,确保了即便获取了编译后的数字信息也无法反推得到指纹图像信息,而对数字信息的加解密过程又只能在TEE中进行,从而保证指纹录入和识别的安全性。
TEE环境下也要有一个操作系统,海思有自己的Trustzone的操作系统,此外还有Trustonic、高通的QSEE、国内的豆荚,还有开源的OPTEE等。这些都是TEE环境下的操作系统。在操作系统之上自然要有应用程序,在Trustzone里面我们一般叫TrustApp,当然TEE里面每个TrustApp都在一个沙盒里,互相之间是隔离的。比如说支付,就可以做成一个App(需要注意的是,和Normal World里面的App是两个概念),这个App简单来说就负责用私钥把网上发来的Challenge签个名,而这个签名的动作是需要在Secure World里面做的,避免恶意程序窃取到私钥来伪造签名。
ARM TrustZone 技术是所有 Cortex-A 类处理器的基本功能,是通过 ARM 架构安全扩展引入的。 这些扩展可在供应商、平台和应用程序中提供一致的程序员模型,同时提供真实的硬件支持的安全环境。
http://blog.sina.com.cn/s/blog_4ce016230102v7xs.html
1.Truztzone和已有trust computing比如TPM技术的区别。
trustzone并没有打算取代TPM,它们关注的点不一样,TPM最关注的Key的安全,它的endorsement key从不会让外界知道,所以这个秘钥加密过的东西十分安全,你只有把密文扔给之前加密的那块TPM芯片才能解密。但是TPM没办法保护运行时的攻击,比如某个黑客直接在运行时进行破解,直接去内存访问你解密过的东西,那TPM秘钥就形同虚设了。Trustzone正好能保护这一点,即使黑客root了你的设备,他也没法访问trustzone里面保护的东西,只有生产者自己写的“trust”的代码模块才能访问。而且一整套secure boot的技术保证了别人没法篡改你的代码image。然而trustzone也没有定义关于key保存的技术标准,所以它并不与TPM技术冲突,假如说SoC制造商即支持了trustzone,又实现了一套只有secure world才能访问的key存储技术,那么按理说这时候trustzone就能取代TPM了。那样trustzone看起来就像是一个超级功能的TPM,所有的安全操作都可以在里面完成(甚至键盘驱动,显示驱动等一条龙走到底都在安全世界里完成),攻击者就没任何办法拿到敏感信息。
2.Trustzone技术的关键:隔离
每个物理的处理器核提供两个虚拟核,一个是非安全核(Non-secure, NS),另一个是安全核(Secure, S),arm体系保证了很多硬件资源都是双份的,每个虚拟核独享自己的那份资源,大大简化了软件设计。在这二者之间切换的机制叫做monitor模式。NS核只能访问NS的系统资源,而安全核能访问所有资源。普通世界的软件可以使用SMC指令或者通过硬件异常机制的一个子集来进入到monitor模式,从而获取安全世界的服务。普通世界只能获取安全世界的服务,要想拿到点其他东西,就连门都没有了。
CP15的SCR寄存器中有一个NS位代表了当前cpu所处的世界,NS=0表示安全世界,只有安全世界能修改SCR寄存器,另外,monitor模式下总是安全世界。
3. trustzone和MMU
安全世界和普通世界都有自己的虚拟MMU,实际上只是两个世界都有一份TTBR0、TTBR1、TTBCR,也就是会有两个MMU表。但TLB是共享的,在TLB里面会对安全世界的TLB项打上tag,所以实际上一个TLB也是逻辑上被划分了两个,不同世界各管各的。另外TLB对不同世界的项打上Tag也不是必须的,不同SoC可以不一定实现这个功能,毕竟转换世界的时候刷出整个TLB就可以了。MMU表里的描述符里也会有一个NS位,对于普通世界,处理器做地址转换的时候无视这个位,对于安全世界,处理器做地址转换的时候按照描述符里的NS位来确定地址转换的物理地址空间,NS=0的时候是按照安全世界的物理空间来做地址转换的,反之就是按安全世界的物理空间来做地址转换的。
这里会有疑问,什么是安全世界的物理地址空间和普通世界的物理地址空间?看起来安全世界可以访问所有资源,怎么还是普通世界访问MMU表时无视里面的NS位?
这两个问题是相关的,首先要明白对资源的保护可不是通过MMU表里的NS位,而且TZASC和TZPC来做保护。划分为安全世界的物理地址空间和普通世界的物理地址空间,并不是说两个地址空间的内存map不一样,而是说同一个物理地址实际上被打上了安全和普通的两个“烙印”,这个“烙印”是对cache和TLB而言的(特别是cache),也就是说安全世界和普通世界访问同一个物理内存地址的内容,最后在cache里是有两份的。假设两个世界共享某一块内存用来做交互,如果普通世界更新了一些内容,这些内容暂时还在cache里,这时候安全世界如果以安全世界的身份来访问这块内容的话,访问的是cache里安全世界自己的东西,这就有可能导致cache不一致。所以安全世界也以普通世界的身份来访问的话,那样就能保证cache的一致。另外,对普通世界而言,描述符的NS位确实没有意义,因为它只能访问普通世界的资源。
4. trustzone和Cache
Cache也是共享,但是必须保证Cache行对不同世界的内容打上不同Tag,这样不同世界刷cache只要刷自己的。
后面再写吧:
5. trustzone和中断
6. trustzone和debug
7. trustzone的物理内存和外设保护
8. trustzone和多核
9. trustzone和ACP
5. trustzone和中断
中断也是隔离的,安全世界和普通世界有独立的VBAR寄存器,中断向量表。唯独monitor模式下有自己的中断向量表,寄存器是MVBAR,smc指令就是跳到这个向量表。GIC可以配置某个中断号属于安全世界还是普通世界的,有关GIC的安全的配置只有安全世界下才有权限配置。通常,IRQ会被配置成普通世界的中断源,而FIQ配成安全世界的,这是因为ARM上的操作系统比如Linux只用IRQ。当中断来的时候,如果该中断属于当前世界,那么中断就在当前世界处理了,如果不属于,那么会触发切换到monitor模式,monitor模式的代码需要考虑是不是切换到另外的世界来处理中断或是丢弃该中断。CPSR里面的F和A位是用来mask FIQ和external abort中断的,普通世界能不能修改两个bit也是安全世界说了算,SCR里面有禁止这两个bit被安全世界修改的位
6. trustzone的物理内存和外设保护
Trustzone需要物理内存和外设在两个世界之间的隔离,这是安全世界真正在意的东西 --- 因为你所要保护的信息和内容就在内存里或是经过某些外设。
物理内存和外设的隔离保护通过TZASC和TZPC的设置来达到目的。TZASC可以把物理内存分成多个区域,每个区域的访问权限可以灵活配置为安全区域或是非安全区域,甚至可以配置成只有普通世界可以访问。TZPC则是配置不同的外设属于哪个世界。当然了TZASC和TZPC的配置只能在安全世界下进行。
7. trustzone和多核
比如四核的soc,每个核都可以配成两个虚拟核,那么总共会有8个世界。虽然cache一致性、中断处理等机制硬件层都尽量避免不同世界互相干扰。但是在系统软件设计上,cache的一致性,多核之间的普通世界和安全世界之间的状态管理和同步都需要精心设计。 如果使用的场景不复杂,最好就配置安全世界只在一个核上运行,所有其他核上的请求都经过这个核最终产生请求,这样简可以简化软件设计,增加系统的可靠性和稳定性。
8. trustzone和ACP
ACP(Accelerator Coherence Port)作为AXI slave interface,也带有安全属性,比如某个PCIe是连到ACP端口的,如果PCIe是配置为属于普通世界的,那么ACP产生的事务也是non-secure的,这时候打个比方说ACP的作用region是DDR的区域0-128M,那么0-128M必须配置为属于普通世界 ,或者说可以把linux的DMA zone配置在128M以内,并把这个DMA区域配置为属于普通世界,否则ACP功能就没法用了。
总结,soc启动的时候就开始工作在secure世界,secure启动代码需要做所有的安全方面的初始化和资源配置,并load安全内核和普通世界代码(比如Linux),由于硬件单元的支持,理论上现有的普通世界操作系统代码不需要修改或者很少修改就能正常工作,唯一欠缺的是一个通过安全世界的驱动程序。TrustZone技术中,TEE系统代码开发才是大头,现有的开源项目如openvirtualization以及Op-Tee可以提供不少参考。
另外,TEE技术还需要比较重要的一环就是secure boot,这是整个系统的root of secure,从上电boot就保证要启动的image没被篡改,从而从根本上保证系统的安全性。那又是另外一个话题了
在我的例子里,u-boot本身就是在安全世界下运行的,所以我只要实现一个命令来做安全初始化,再写一个小的normal程序,先load normal程序到DDR,在执行这个命令设置安全环境,然后直接跳转至normal运行,normal跳回安全环境后打印再smc跳回,如此反复。几点经验:
1. 准备jtag调试器,否则寸步难行。
2. 这个例子虽然代码不多,但是信息量巨大,已经涵盖了ARM Secure extension的基本知识点,想成功在其他环境跑起来并非易事。
|-> /headers
| |-> v7.h C header file for misc ARMv7-A helper functions
|-> /obj This is where generated objected files will be placed
|-> /src
| |-> v7.s Implementation of misc ARMv7-A helper functions
| |-> main_normal.c main() for the Normal world
| |-> main_secure.c main() for the Secure world
| |-> monitor.c Code for the Secure Monitor
| |-> retarget_normal.c Wrapper for main(), for Normal world
| |-> retarget_secure.c Wrapper for main(), for Secure world
| |-> startup_normal.s Initialization code for Normal world
| |-> startup_secure.s Initialization code for Secure world
|-> build.bat Build script for DOS
|-> build.sh Build script for BASH
|-> ReadMe.txt This file
|-> scatter_secure.txt scatter file for the Secure world image
|-> scatter_normal.txt scatter file for the Normal world image
|-> normal.axf Debug symbols for Normal world
|-> secure.axf Debug symbols for Secure world, code for both worlds
Description
============
Execution flow
---------------
secureStart startup_secure.s: Initialization of Secure world
|
__main ARM library initialization
|
$Sub$$main retarget_secure.s: Enable caches
|
monitorInit monitor.s: Initialize Monitor and call NS world
|
<< S -> NS >>
|
normalStart startup_normal.s: Initialization of Normal world
|
__main ARM library initialization
|
$Sub$$main retarget_normal.s: Enable caches
|
main main_normal.c: Print message and execute SMC
|
<< NS -> S >>
|
SMC_Handler monitor.s: Perform context switch from NS to S
|
$Sub$$main retarget_secure.s: call Secure world's main()
|
main main_secure.c: Print message and execute SMC
|
SMC_Handler monitor.s: Perform context switch from NS to S
|
<< S -> NS >>
|
main main_normal.c: Print message and execute SMC
|
<< NS -> S >>
|
SMC_Handler monitor.s: Perform context switch from NS to S
|
main main_secure.c: Print message and execute SMC
3. 这个例子埋了两个坑
a. movs pc,lr
这个指令是arm的中断返回指令,在改pc之前先把当前模式的spsr替换cpsr,是模式转换的重要指令。
但是一旦cpsr的值有点问题,那么等待你的就是奇怪的data abort。原来的例子代码这里可能会有一个坑,取决于你之前secure world的设置。
b. sp指针的上下文切换
两个世界可是共享sp_svc和sp_usr寄存器的,所以要保护好,那么问题来了,进到monitor模式以后sp已经是sp_mon,怎么拿到原来的sp? 原来的代码没实现,又是另外一个坑。
optee开源项目的学习_fanguannan0706的博客-CSDN博客_optee
发现optee有4个项目:
optee_os:包含了TEE操作系统本身的源代码,提供了TEE的内部接口。
optee_client:包含了TEE客户端库的源代码,提供了TEE的客户端接口。
optee_linuxdriver:包含了TEE驱动的源代码,提供了TEE的通用驱动程序
https://github.com/OP-TEE/optee_os.git
https://github.com/OP-TEE/manifest.git
https://github.com/OP-TEE/build.git
https://github.com/OP-TEE/optee_client.git
https://github.com/OP-TEE/optee_linuxdriver.git