TEE Trusted Execution Environment 可信执行环境,通常用来进行数字版权管理(DRM : Digital Rights Management )、移动支付和敏感数据保护。TEE 的实现是基于 ARM TrustZone。
REE(Rich Execution Environment)是所有移动设备通用的环境,运行通用的 OS,例如 Android,IOS 系统, LINUX等。
OTP One-Time Programmable 一次性可编程
ATF Arm Trusted Firmware arm可信固件
OPTEE Open Portable Trusted Execution Environment开放可移植可信执行环境
BLD Bootloader 引导装载程序
BST Bootstrap 引导
GP Global Platform 全球平台
CA Client Application 客户机应用程序
TA Trusted Application受信任的应用程序(用户态执行),含有签名在安全世界
PTA Pseudo ['sju:dəʊ] TA 伪受信任的应用程序(在内核态执行),含有签名嵌入信任OS
AES Advanced Encryption Standard 高级加密标准
RSA An asymmetric cypher, RSA stands for its inventor’s names (Ron Rivest, Adi Shamir, and Leonard Adleman) RSA是一个不对称密码,RSA代表其发明者的名字
SHA Secure Hash Algorithm 安全哈希算法
SSL Secure Socket Layer 安全套接字层
TLS Transport Layer Secure 传输层安全
RPC Remote Procedure Call 远程过程调用
DRM Digital Rights Management,数字版权管理
svc: supervisor call 应用程序调用kernel(el0-》el1)功能
hvc: hypervisor call,os 调用hypervisor(EL2)
smc: secure monitor call ,os or hypervisor 调用 secure monitor (El3)
spl: Secondary Program Loader 第二阶段程序加载器 SPL是uboot第一阶段执行的代码. 主要负责搬移uboot第二阶段的代码到内存中运行. SPL 是由固化在芯片内部的ROM引导的
MLO(功能类似于spl) : The ROM will initialise the SD/MMC device, detect a card and look for a boot image. The ROM bootloader is capable of reading from the card with a filesystem. It will search for a file named MLO which should be located on the boot partition, on a partition of type FAT16/32. So, this explains the name MLO
FSBL:First Stage Boot Loader: 第一阶段bootloader, 初始化DDR clock bus等
PBL: Primary Boot Loader:位于rom,芯片商的第一行代码,调到SBL1
SBL1: Second BootLoader stage 1:第一阶段bootloader, 初始化DDR clock bus等
tee_supplicant: 在正常世界中,用于安全世界访问REE的文件系统
ROT :Root of trust,写入OTP 的key
公钥,私钥,签名,证书基本概念的解释,请参照下文(漫画图文详解,浅显易懂)
https://www.cnblogs.com/xq1314/p/7918644.html
Unlikely previous ambarella platform, Cv2x include Secure Rom
使引导过程能够在整个引导序列期间执行数字签名检查,安全ROM认证BST;BST重复使用安全ROM中的代码块(RSA / SHA)和ATF (BL2)认证。因此,不再需要RO引导分区
basic knowledge of arm trustzone: https://blog.csdn.net/MageeLen/article/details/98294065
大致分为安全和不安全区域,安全区域可以访问非安全区域信息,反之不可以
https://www.cnblogs.com/dakewei/p/10267774.html
OP-TEE必须尽可能早启动(因为如果BootLoader 运行优先于OP-TEE会带来缺陷是,触碰敏感数据)
1. 典型linux启动过程:rom 加载第一阶段BootLoader -》第二阶段BootLoader -》linux内核 (安全世界上下文)
2. ARMV7(附含TEE): SPL 加载OP-TEE和U-BOOT,跳转到OP-TEE,OP-TEE初始化完毕,OP-TEE会切换到非安全上下文,并且跳转到U-BOOT中,OP-TEE代码继续放在内存中,以便为内核提供安全服务。
3. ARMV8(附含TEE):TEE 启动流程涉及一个SPL加载ATF的步骤,SPL 跳转到ATF firmware,这个firmware随后和OP-TEE共同协作,然后OP-TEE 转而跳转到处于非安全上下文的U-BOOT。
4. 在一个ARMV8平台上,ATF提供一个监视器代码去管理安全世界和非安全世界之间切换,而在ARMV7这一功能被嵌入到OP-TEE中。
为了访问硬件特性,许多安全芯片给用户空间程序提供OpenSSL引擎接口。一个相同的模型能够通过开发一个TEE client app作为OpenSSL引擎与TA之间的接口,因此能够最小化用户空间程序的任何修改。Trusted Application将需要实现密钥管理和加密操作等接口。OP-TEE OS包含libtomcrypt,这个库提供各种各样的对称/非对称/椭圆曲线加密函数,因此TA 大部分工作是负责输入校验和调用合适的OP-TEE 核心API。
是一种公钥加密系统,用于数据加密。(有一个加密和解密),加密是公钥,解密是私钥
是一种asymmetry(不对称的) 的加密系统. 在RSA中,这种不对称的困难点是基于两个大素数(primer number)乘积(product)的因数分解。RSA 相对较慢,所以不用做直接对数据加密,而是用于对对称密钥加密的共享密钥进行加密,该方法能以高得多的速率执行大量加密-解密操作
CV2x 的secure rom就是包含RSA2048支持,代码量很小
公钥和私钥参考:https://blog.csdn.net/qq_33369979/article/details/88708513
Secure boot会在boot的每个阶段都做加密检测,避免在running时候不授权或者恶意修改软件。所以启动应该在ROM而不是在RAM。 常用RSA 加密算法,可以生成一个公钥和一个私钥,每个阶段的bin文件,user都用私钥生成一个签名附在bin文件后面。然后将公钥写入一次性写入(OTP,one time programming)的memory(efuse, 通常只有128bit)。
启动时,安全的ROM将去从OTP memory中读取RSA 公钥,再去检查RST bin文件的完整性,然后RST bin文件将用该公钥或者由本公钥生成的公钥去验证ATF的完整性,然后ATF验证BLD,BLD验证linux bin文件的完整性。
当然除了ROM从OTP读取RSA公钥外,后面生成的公钥都可以放在NAND中,其完整性由chain of trust 的方法保证。写入OTP memory的公钥称为Root of trust(ROT)。由secure ROM 中先运行的代码具有数字签名授权的能力。” secure ROM” + “ROT in OTP” + “ATF”组合可以对启动过程搭建一个完整的授权chain。从secure ROM的第一条指令到Rich OS/Trust OS启动结束,所有的模块都经过了授权。(Rich OS 主要有linux,Trust OS有OP-TEE等OS)。
下图描述了安全启动流程,黑线为启动顺序,蓝线为授权公钥和授权目标。
通常我们需要cover从secure boot -> BST(BL1)->ATF(BL2), ATF可以cover ATF->BLD->Linux, 和ATF->OP-TEE。
在生成bin文件时,SHA256 算法将为bin文件生成数字签名,然后用RSA私钥去为签名加密。
在启动阶段时候,每个启动过程都将用SHA256算法根据公钥为后一级的过程生成数字签名,然后和SHA256解密签名(私钥加密的) 做对比。BST和ATF 可以从OTP memory拿root 公钥去授权,后续阶段的授权需要去拿由公钥生成的公钥去完成。
总之就是通常先RSA算法生成一个公钥和私钥,私钥先生成签名附在bin文件后面,公钥写入OTP memory。启动阶段,根据trust chain,前一阶段的公钥生成下一阶段的公钥,每个阶段的公钥生成签名去和之前由私钥生成的签名作对比。
在EL3阶段,包含安全监测功能(BL31~BL32)。EL0~EL2阶段由于不在trust zone,不能访问安全相关的寄存器和设备,但是EL3就在trust zone,可以访问所有寄存器和设备。
ATF中做初始化异常向量表,控制寄存区,平台中断,使能标准ARM IP,包括GIC(generic interrupt controller),cache,NIC(network interrupt controller), TZC(trust zone controller), 实现由secure monitor 到normal 连接。
ATF 通过认证延伸(hash ,公钥,无volatile 计数器)来搭建一套trust chain。
下图阐述了ATF中有证书的信任链。
Secure world 和 normal world的memory是相互独立的。但是secure world可以访问non-secure world的memory。
Major |
Sub1 |
Sub2 |
Start Address |
End Address |
Total Size |
Secure World Memory |
ATF (BL2) |
- |
0x00000000 |
0x0007FFFF |
512KB |
ATF (BL31) |
- |
0x00080000 |
0x000FFFFF |
512KB |
|
OPTEE (BL32) |
TEE memory |
0x00100000 |
0x001FFFFF |
1MB |
|
TA memory |
0x00200000 |
0x00BFFFFF |
10MB |
||
Normal World memory |
Share memory |
- |
0x00C00000 |
0x01000000 |
4MB |
Linux BLD (BL33) |
- |
0x01000000 |
0x010FFFFF |
1MB |
|
Block Buffer |
- |
0x01100000 |
0x011FFFFF |
1MB |
|
Left memory |
- |
0x01200000 |
- |
Total Size - 18MB |
描述了安全启动后trust zone的实现,包含安全世界OS,TA/CA, UUID/KEY
OPTEE是用的全球平台TEE标准,Rich OS(linux)可以用全球平台标准的TEE client API 去访问trust OS。TEE client API同样可以在TEE内触发APP的安全执行。OP-TEE包含完整的开足正常世界的栈,如Client API(OP-TEE_client), Linux kernel TEE driver(op-tee_linuxdriver),trust OS+, secure moniter, test_suite(xtest).
TA Trusted Application受信任的应用程序(用户态执行),含有签名在安全世界
PTA Pseudo ['sju:dəʊ] TA 伪受信任的应用程序(在内核态执行),含有签名嵌入信任OS
每个TA都有一个UUID 作为其身份,当需要访问Normal TA时候,在其被签名验证通过后,TEE发送访问安全世界请求,将由tee-supplicant 加载到安全世界,tee-supplicant(常驻进程)访问流程图如下。
从tee_supplicant处理来自TEE侧的请求来看主要是有三个点。
第一是驱动在触发smc操作之后会进入到loop循环中,根据secure world中的返回值来判定该返回时来自TEE的RPC请求还是最终处理结果,如果是RPC请求,也就是需要驱动或者tee_supplicant执行其他操作,驱动将RPC请求会保存到驱动的请求消息队列中,然后block住等待请求处理结果。
第二是在tee_supplicant作为一个常驻进程存在于REE中,它会不停的尝试从驱动的请求消息队列中获取到来自TEE侧的请求。如果请求消息队列中并没有请求则会block住,直到拿到了请求才返回。拿到请求之后会对请求进行解析,然后根据func执行具体的操作。
第三是在tee_supplicant处理完来自TEE的请求后,会调用send操作将处理结果存放到该消息队列的参数区域,并使用complete函数通知驱动该请求已经被处理完毕。驱动block住的地方可以继续往下执行,调用smc操作将结果返回给TEE侧
参考:https://blog.csdn.net/shuaifengyun/article/details/72934531
部分常用的库的链接
TEE_Client_API: optee_client\libteec
TEE_Internal_API: optee_os\lib\libutee\include
OP-TEE driver: kernel\linux\drivers\tee\optee
RPC Service: optee_client\tee-supplicant(常用于当私钥不能被工程师知道时,将私钥用RPC 远程获取)
AES :Advanced Encryption Standard高级加密标准
#define DATA_ENCRYPTION_AES_UUID_ID {0xabb6f4b5, 0x7e33, 0x4ad2, \
{ \
0x98, 0x02, 0xe6, 0x4f, 0x2a, 0x7c, 0xc2, 0x0c \
} \
}
abb6f4b5-7e33-4ad2-9802-e64f2a7cc20c作为加密和解密的密码
test_data_encryption_aes's options
'--inputfile [%s]': input file for encryption/decryption
'--outputfile [%s]': output encrypted/decrypted file
'--aesmode: supported aes mode : CBC, ECB, CTR or CTS
'--aesoper': enc or dec
'--len': 128, 192 or 256
加密解密过程cmd,编辑a.c文件后执行下面的cmd,再cat c 文件,会发现a.c和c文件是一样的(当然本app属于私有的,不能share,依赖driver,不能公开,大致提供一种实现的方式)
test_data_encryption_aes --inputfile a.c --outputfile b --aesmode CBC --aesope
r enc --len 128
输入密码:abb6f4b5-7e33-4ad2-9802-e64f2a7cc20c
test_data_encryption_aes --inputfile b --outputfile c --aesmode CBC --aesoper
dec --len 128
输入密码:abb6f4b5-7e33-4ad2-9802-e64f2a7cc20c
为了避免硬件clone,每个芯片出厂时会有个unique ID 存在它的固件中,签名用RSA root 私钥加密,在安全启动阶段,设备unique ID 的签名必须确认无误。设备unique ID可用于获取设备独有的加密key,该加密key只能被安全世界访问,不能被修改。(应用场景:当授权licence时候,客户从算法商买了有限个licence,每个licence对应一个unique ID,为了防止客户生成的每个板子unique ID 设置为相同,算法商会保存一份私钥,check 固件的unique ID,但是万一固件的unique ID被改变了,还有一套保险机制芯片厂商在软件(so,等处不能破解)维护一份unique ID,算法商将固件的unique ID和芯片上的so维护的unique ID做对比,如果不同,在芯片厂商的软件上会处理)。
OPTEE 使用设备独有的加密key使能正常世界的安全存储,如下图所示:
128bits~32k bits
通常有一个bit的zone lock的bit,可以将其他所有bit的值lock住不能修改,该bit为一次性修改的。
OTP 可以由CA和PTA来编写,通常会将pubkey 写入OTP中
Secure ROM 确保启动第一阶段的code是只读的,RSA 公钥也是一次性写入OTP,每个启动阶段都会check 签名的,以保证每个阶段启动的完整性,当在任何阶段的一个签名失败时,启动暂停,返回error 信息。
使能安全启动,然后生成key,CA 和PTA会允许写入OTP中。包含写入pubkey,读pubkey,lock pubkey,等操作(软件行为)
为了确保一个可信的执行环境,一个专用的操作系统OPTEE被用来实现secure world软件。这种体系结构最大限度地隔离了安全和正常的世界。敏感数据在安全环境中存储和处理,然后与正常环境进行通信。
OPTEE为所有安全世界应用程序提供基础设施,以及安全和正常世界应用程序之间的接口。安全应用程序作为服务提供者执行,并使用来自Arm信任区的安全监视器过程响应正常应用程序。
敏感数据在OPTEE安全世界中受到保护,这意味着普通世界应用程序不能访问它。因此,如果一个普通应用程序需要访问敏感数据,建议将该应用程序分成两部分:(1)不需要访问敏感数据的普通应用程序中的CA应用程序, (2)能够处理敏感数据并提供反馈的TA应用程序。
为了在正常情况下保护敏感数据,使用DRAM置乱特性,确保原始数据不能从置乱的数据中得到。置乱方法采用AES等对称数据加密方法。为了保护移动中的数据,建议使用诸如Open SSL等传输层安全方法。
常用为敏感/私有数据加密,4.3小节例子会show怎么样在安全世界中加密数据。
数据加密的key因为不能暴露于正常世界,建议写入OTP,
有两种硬件克隆方法:包括NAND的复制克隆和带有制造软件的克隆。
为了防止包括NAND在内的硬件复制克隆,制造商可以在每台设备的固件上安装一个唯一的加密密钥。
虽然带有制造软件的克隆存在复杂的安全问题,但在大规模生产过程中激活每台设备(使用私钥为每个芯片分配唯一的ID),防止没有私钥在克隆设备上生成正确数字签名的攻击者。为了确保克隆设备的安全性,建议用户在引导阶段和应用程序中执行数字签名验证。
为了绕过安全引导,攻击者试图重新编写以前易受攻击的固件。然而,Ambarella在OTP内部包含一个单调计数器,以防止重编程。每个固件编程操作的单调计数器持续增加。因此,在引导过程中检查单调计数器(monotonic counter)有助于防止反回滚攻击。
加速加密引擎
CV2x的CPU是四核ARM®-A53。它支持Armv8加密扩展。
加密扩展增加了新的A64, A32,和T32指令的高级SIMD,可对以下加密方法加速:
1 高级加密标准(AES)加密和解密。
2 安全哈希算法(SHA)函数SHA-1、SHA-224和SHA-256。
3 有限域算术用于算法,如Galois/计数器模式和椭圆曲线加密。
安全性的一个重要方面是密钥管理。在生成支持安全引导特性的二进制文件时,用户必须生成并存储私钥。这些私钥对于维护安全引导特性的安全性非常重要。
ATF和OPTEE没有成熟的密钥管理机制,因此客户编译ATF或OPTEE时,如果项目中有多位工程师,能够访问私钥比较严重的。注意,如果系统的默认密钥管理是在ATF / OPTEE中,则可能会出现安全问题。
结合上文,主要有三种key:
1 安全启动需要ROT key,
2 linux 内核验证的key
3 为TA binary验证的TA key
•应该将ROT公钥(rot_public.bin)编程到OTP中,因为它是所有其他证书的根密钥。
ATF key来自于ATF的CoT中的ROT key。默认情况下,这些key在每个编译阶段生成。在这种情况下,不需要保存这些密钥(ROT密钥除外)。
•对于OPTEE, TA公钥被嵌入到OPTEE- os二进制文件中。
•对于Linux认证内核,内核公钥被嵌入到Amboot二进制文件中。
•由于boot和opte - os在执行前都经过身份验证,因此它们的公钥会自动进行身份验证,这比从OTP读取公钥更容易。
为了防止key的泄露,可以用RPC(remote procedure call) 的方式限制私钥由管理者管理,其它开发者,能够在不访问私钥时候也能编译ATF/OPTEE. 这套工具在开发者侧含一个dameon进程和保护伞,
下图显示了开发工具包的三个组件:开发服务器、守护进程和工具代理。开发人员共享一个服务器,而每个开发人员应该有自己的守护程序和工具代理。
因为保留私钥的开发服务器是由管理员控制的,所以只有管理员可以直接访问私钥。开发服务器通过TLS连接提供私钥相关的服务,称为RPC(远程过程调用)。
每个开发人员端都包括一个守护程序和工具代理。守护进程程序保持与开发服务器的TLS连接,并在开发服务器和工具代理之间中继请求/响应。
开发服务器和守护进程程序之间存在相互身份验证,以保证私有密钥相关RPC只适用于经过批准的开发人员;服务器生成使用口令加密的身份密钥对和自签名证书,开发人员生成同样使用口令加密的身份密钥对)。服务器维护一个开发帐户数据库,并手动批准开发帐户。开发人员使用他的口令运行他的守护程序和登录服务器。
工具代理提供与ATF / OPTEE中的原始工具相同的服务,但有一个例外:私钥不是本地的—它们存在于远程服务器端。
正常可以提供生成key,编译方法和用安全启动和trustzone生成的bin文件。
在编译bin文件之前,sdk可以生成本地key以替换默认的key,保证openSSL 加载进编译器,此时在本地编译服务器可以生成新的key。
通常,这些Keys只需要生成一次。生成后,保持私钥的机密性。生成一对新的ROT密钥(包括公钥 bin文件):
用户在生成ROT密钥时应谨慎使用。在继续之前,确保生成是必要的。生成后,备份ROT密钥对。如果其中一个密钥丢失,验证过程将不会通过,系统将无法工作。
如果用户已经有一个私有ROT密钥,需要有命令生成相应的二进制格式的公钥。这一步非常重要,因为公钥bin将以bin格式被编进OTP。
可以根据ROT 私钥推到出ROT公钥,然后其他公钥可以在编译过程中生成。因此,如果用户希望使用现有的私钥,就需要替换默认的公钥。
需要编译出develop server,daemon,tool proxy(工具代理)
1. 第一次,您需要生成服务器密钥和服务器证书,先让服务器运行。
2 . developer在用安全启动feature编译sdk之前,第一次,你应该获取服务器的公钥并生成守护进程的私钥和公钥,运行developer守护进程(需要server的公钥)(如果同一台构建机器上有多个帐户,则每个帐户有一个守护进程和一个本地端口)
3. 通过openSSL 让deamon和server建立连接
4. 守护进程运行前,注册你的帐户,输入"your_account_name" + ENTER,然后等待管理员的批准(在服务器控制台输入'y' + ENTER)。在管理员批准之后,您可以使用存储在服务器端的私有密钥进行编译。
通常会设计跳线帽,进入安全启动模式,然后重启根据log看是否进入secure boot
最后想要跟各位推荐一本书:图解密码技术(日本作家(结城浩),译(周自恒))
目标读者: 对密码相关知识感兴趣的人; 希望理解公钥密码,数字签名等密码技术原理的人; 对信息安全感兴趣的人;