一、简介
1.TrustZone
系统范围的安全方法,针对高性能计算平台上的大量应用,包括安全支付、数字版权管理(DRM)、企业服务和基于Web 的服务。
TrustZone 技术与 CortexTM-A 处理器紧密集成,并通过 AMBA-AXI 总线和特定的 TrustZone 系统 IP块在系统中进行扩展。此系统方法意味着可以保护安全内存、加密块、键盘和屏幕等外设,从而可确保它们免遭软件攻击。
可信应用程序采用基 TrustZone 技术的 SoC(运行可信执行环境),与主 OS 分开,可防止软件/恶意软件攻击。TrustZone 可切换到安全模式,提供硬件支持的隔离。可信应用程序通常是可集装箱化的,如允许不同支付公司的可信应用程序共存于一台设备上。
1)硬件架构
架构的主要安全目标是支持构建可编程环境, 以防止资产的机密性和完整性受到特定攻击。
-
隔离所有 SoC 硬件和软件资源,使它们分别位于两个区域(用于安全子系统的安全区域以及用于存储其他所有内容的普通区域)中。支持 TrustZone 的 AMBA3 AXITM总线构造中的硬件逻辑可确保普通区域组件无法访问安全区域资源,从而在这两个区域之间构建强大边界。
-
在一些 ARM 处理器内核中实现的扩展。通过这些额外增加的扩展,单个物理处理器内核能够以时间片的方式安全有效地同时从普通区域和安全区域执行代码。这样便无需使用专用安全处理器内核,从而节省了芯片面积和能源,并且允许高性能安全软件与普通区域操作环境一起运行。
-
更改当前运行的虚拟处理器后,这两个虚拟处理器通过新处理器模式(称为监视模式)来进行上下文切换。
2)软件架构
- 从系统架构角度看,如下是启用了 ARM TrustZone 技术后的 64 位平台系统架构图。整个系统被分
成了两个世界:左边是非安全世界,右边是安全世界。安全世界可以访问两个世界的所有资源,非安全
世界只能访问非安全世界的资源。 - 两个世界之间的往来需要通过 ARM Trusted Firmware 作为桥梁。当 CPU 处于非安全世界时,如果想进入安全世界则需要先进入 ARM Trusted Firmware(通过 ARM 的 SMC 硬件指令),在 ARMTrusted Firmware 里的 Secure Monitor 代码会把 CPU 从非安全身份切换成安全的身份,然后再以安全身份进入安全世界。反之亦然。
- Rockchip 的 Trust是 ARM Trusted Firmware + OP-TEE OS 的功能集合,实现了安全世界里用户需求的功能以及 Secure Monitor(两个世界转换的核心代码)的功能。
2.TEE 环境
基于 ARM TrustZone 技术的设备与开放 API 相结合,提供了可信执行环境(TEE)。
Rockchip平台采用的TEE方案为OP-TEE,TEE API符合GlobalPlatform标准。
目前运行在rockchip平台上的OP-TEE有两个版本,OP-TEE V1与OP-TEE V2。
- RK312x、RK322x、RK3288、RK3328、RK322xh、RK3368、RK3399、RK3399Pro采用OP-TEE V1版本。
- RK3326、RK3308、RK1808、RV1109/RV1126、RK3566/RK3568和后续新平台均采用OP-TEE V2 版本。
3.Rockchip 平台的 Trust
1)启动流程
ARM Trusted Firmware 的体系架构里将整个系统分成四种安全等级,分别为:EL0、EL1、EL2、EL3。将整个安全启动的流程阶段定义为:BL1、BL2、BL31、BL32、BL33,其中 ARM TrustedFirmware 自身的源代码里提供了 BL1、BL2、BL31 的功能。
Rockchip 平台仅使用了其中的 BL31 的功能,BL1 和 BL2 有独特的一套实现方案。这种阶段定义映射到 Rockchip 的平台各级固件上,对应关系为:Maskrom(BL1)、Loader(BL2)、Trust(BL31:ARM Trusted Firmware + BL32:OP-TEE OS)、U-Boot(BL33)。
- Loader、Trust 运行在安全世界;
- U-Boot、kernel、Rootfs 运行在非安全世界里(安全的driver、APP 除外)
2)Trust固件
目前只提供 binary 文件,不提供源代码。Trust 的 binary 文件提交在 U-Boot 工程里,可以在u-boot/tools/rk_tools/bin/或rkbin/bin/找到。
当编译某个平台的 uboot.img 的时候,相应平台的 trust.img 也会同时打包生成在 U-Boot 的根目录
下。其中 binary 打包成 trust.img 的时候是通过 ini 文件进行索引。
二、编译TEE固件和驱动
1.trust.img添加TEE Secure OS
TEE Secure OS的源码默认不开源,binary位于rkbin/bin/目录,例如rkbin/bin/rl1x/rk1808_bl32_v1.14.bin。
修改SDK中的rkbin/RKTRUST/RK1808TRUST.ini,将BL32_OPTION的SEC=1,会将binary文件打包成固件trust.img。
[BL32_OPTION]
SEC=1
2.TEE linux kernel驱动
在设备树添加optee
/ {
firmware {
optee {
compatible = "linaro,optee-tz";
method = "smc";
status = "okay";
};
};
};
开启内核配置
CONFIG_TEE=y
CONFIG_OPTEE=y
3.parameter.txt添加security分区
Rockchip的OP-TEE目前同时支持security与rpmb两种安全存储文件系统,使用哪种文件系统由TA中设置storageID参数决定。
若parameter.txt中没有定义security分区,则TA无法使用security安全存储文件系统。
- 设置security分区只需在parameter.txt中添加0x00002000@0x000xxxxx(security)即可。
- 0x00002000表示大小4M, 0x000xxxxx表示起始地址
$ vim device/rockchip/rk1808/parameter-ubuntu-optee.txt
...
CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(trust),0x00002000@0x00008000(misc),0x00010000@0x0000a000(boot),0x00002000@0x0001a000(security),0x00010000@0x0001c000(recovery),0x00010000@0x0002c000(backup),0x00020000@0x0003c000(oem),-@0x0005a000(rootfs:grow)
...
三、烧录并启动设备
固件重新编译并烧录到rk1808设备后上电,正常启动日志如下:
- ARM Trusted Firmware 打印格式:INFO: *********
- OP-TEE OS 打印格式:INF [0x0] TEE-CORE: *********
DDR Version V1.04 20191121
LPDDR3
933MHz
BW=32 Col=10 Bk=8 CS0 Row=15 CS1 Row=15 CS=2 Die BW=32 Size=2048MB
out
Boot1 Release Time: Dec 9 2019 18:18:13, version: 1.05
chip_id:524b188,0
ChipType = 0x14, 10271
sfc nor id: ff ff ff
sfc_nand id: ff ff ff
NeedKHz=200KHz,clock=12000KHz
NeedKHz=200KHz,clock=12000KHz
NeedKHz=200KHz,clock=12000KHz
NeedKHz=18000KHz,clock=192000KHz
NeedKHz=48000KHz,clock=192000KHz
mmc2:cmd19,100
SdmmcInit=2 0
BootCapSize=2000
UserCapSize=14910MB
FwPartOffset=2000 , 2000
SdmmcInit=0 NOT PRESENT
StorageInit ok = 20594
SecureMode = 0
Secure read PBA: 0x4
Secure read PBA: 0x404
Secure read PBA: 0x804
Secure read PBA: 0xc04
Secure read PBA: 0x1004
SecureInit ret = 0, SecureMode = 0
atags_set_bootdev: ret:(0)
GPT part: 0, name: uboot, start:0x4000, size:0x2000
GPT part: 1, name: trust, start:0x6000, size:0x2000
GPT part: 2, name: misc, start:0x8000, size:0x2000
GPT part: 3, name: boot, start:0xa000, size:0x10000
GPT part: 4, name: security, start:0x1a000, size:0x2000
GPT part: 5, name: recovery, start:0x1c000, size:0x10000
GPT part: 6, name: backup, start:0x2c000, size:0x10000
GPT part: 7, name: oem, start:0x3c000, size:0x20000
GPT part: 8, name: rootfs, start:0x5a000, size:0x1cc4fdf
find part:uboot OK. first_lba:0x4000.
find part:trust OK. first_lba:0x6000.
LoadTrust Addr:0x6000
No find bl30.bin
Load uboot, ReadLba = 4000
Load OK, addr=0x600000, size=0xcb708
RunBL31 0x40000 @ 82541 us
�INFO: Preloader serial: 2
NOTICE: BL31: v1.3(debug):877eaebaf
NOTICE: BL31: Built : 10:49:23, Jun 11 2020
NOTICE: BL31: Rockchip release version: v1.0
INFO: GICv3 with legacy support detected. ARM GICV3 driver initialized in EL3
INFO: not boot from ram
INFO: Using opteed sec cpu_context!
INFO: boot cpu mask: 0
INFO: plat_rockchip_pmu_init(1807): pd status 8002
INFO: BL31: Initializing runtime services
INFO: BL31: Initializing BL32
I/TC:
I/TC: Start rockchip platform init
I/TC: Rockchip release version: 1.1
I/TC: OP-TEE version: 3.6.0-218-g85f8d2dd #32 Fri Mar 13 02:42:03 UTC 2020 aarch64 # OP-TEE V2 启动
I/TC: Initialized
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x600000
INFO: SPSR = 0x3c9
......
[ 1.493927] optee: probing for conduit method from DT.
[ 1.494983] optee: initialized driver # 初始化optee驱动
......
optee v2驱动的设备节点
$ ls /dev/tee*
/dev/tee0
/dev/teepriv0
四、CA/TA 开发与测试
CA(Client Application,运行在normal world),TA(Trust Application,运行在secure world)。在rk1808上,CA需要编译成64位,TA需要编译为32位。
1.rk_tee_user工程
属于OP-TEE健全性测试套件,包含Linux中使用ARM(R)TrustZone(R)技术的TEE健全性测试套件的源代码。
TEE CA/TA测试程序在 linux 工程目录 external/security/rk_tee_user (使用develop-next分支)下。
-
CROSS_COMPILE_HOST
:用于编译非安全客户端应用程序(ca)(host/xtest
)的交叉编译器 -
CROSS_COMPILE_TA
:用于编译受信任的应用程序(ta
)的交叉编译器 -
TA_DEV_KIT_DIR
:Trusted Application Dev Kit的路径。编译optee_os后,可以在optee_os存储库中找到它。
$ tree rk_tee_user -L 2
rk_tee_user
├── Android.mk
├── build.sh
├── client_export
│ └── public
├── export-user_ta
│ ├── host_include
│ ├── include
│ ├── keys
│ ├── lib
│ ├── mk
│ ├── scripts
│ └── src
├── host
│ ├── lib
│ ├── LICENSE
│ └── rkdemo
├── Makefile
├── ndk_build.sh
├── Notice.md
├── package
│ └── testsuite
├── README_FOR_RK.md
├── README.md
├── ta
│ ├── Android.mk
│ ├── Makefile
│ ├── prebuilt
│ ├── ta_common.mk
│ ├── testapp
│ └── testapp_storage
└── tools
├── change_puk_tool-release
└── ta_resign_tool-release
2.编译rk_tee_user
$ cd external/security/rk_tee_user/
# 安装依赖库
$ sudo pip install pycrypto
# 编译 CA 64bits,TA 32bits
$ ./build.sh 6432
# 编译成功后文件输出在out文件夹
$ tree out/
out/
├── rkdemo # CA程序
│ ├── testapp
│ ├── testapp_ca.o
│ ├── testapp_storage
│ └── testapp_storage_ca.o
└── ta # TA程序
├── testapp
│ ├── 8cccf200-2450-11e4-abe2-0002a5d5c52c.dmp
│ ├── 8cccf200-2450-11e4-abe2-0002a5d5c52c.elf
│ ├── 8cccf200-2450-11e4-abe2-0002a5d5c52c.map
│ ├── 8cccf200-2450-11e4-abe2-0002a5d5c52c.stripped.elf
│ ├── 8cccf200-2450-11e4-abe2-0002a5d5c52c.ta # testapp 对应的TA可执行文件
│ ├── ta.lds
│ ├── testapp_ta.o
│ └── user_ta_header.o
└── testapp_storage
├── 8dddf200-2450-11e4-abe2-0002a5d5c53d.dmp
├── 8dddf200-2450-11e4-abe2-0002a5d5c53d.elf
├── 8dddf200-2450-11e4-abe2-0002a5d5c53d.map
├── 8dddf200-2450-11e4-abe2-0002a5d5c53d.stripped.elf
├── 8dddf200-2450-11e4-abe2-0002a5d5c53d.ta # testapp_storage 对应的TA可执行文件
├── ta.lds
├── testapp_storage_ta.o
└── user_ta_header.o
3.测试CA/TA程序
1)安装依赖环境
TEE CA/TA 依赖文件在external/security/bin,程序工程目录如下:
├── NOTICE
├── optee_v1
│ └── lib
│ ├── arm
│ │ ├── libteec.a
│ │ ├── libteec.so
│ │ ├── libteec.so.1
│ │ ├── libteec.so.1.0
│ │ └── tee-supplicant
│ └── arm64
│ ├── libteec.a
│ ├── libteec.so
│ ├── libteec.so.1
│ ├── libteec.so.1.0
│ └── tee-supplicant
└── optee_v2
├── include
│ └── rk_tee_service.h
├── lib
│ ├── arm
│ │ ├── librk_tee_service.so
│ │ ├── libteec.a
│ │ ├── libteec.so
│ │ ├── libteec.so.1
│ │ ├── libteec.so.1.0
│ │ └── tee-supplicant
│ └── arm64
│ ├── librk_tee_service.so
│ ├── libteec.a
│ ├── libteec.so # optee_client 动态库
│ ├── libteec.so.1
│ ├── libteec.so.1.0
│ └── tee-supplicant
└── ta
└── 4367fd45-4469-42a6-925d-3857b952704a.ta # 忽略
安装optee依赖
# 预先将security目录拷贝到rk1808设备上
cd security/bin/optee_v2/lib/arm64/
cp libteec.so libteec.so.1 libteec.so.1.0 librk_tee_service.so /usr/lib/
cp tee-supplicant /usr/bin/
mkdir -p /lib/optee_armtz/ # tee-supplicant 默认运行TA的路径
cd -
安装CA/TA程序
cd security/rk_tee_user/out
cp rkdemo/testapp /usr/bin/
cp rkdemo/testapp_storage /usr/bin/
cp ta/testapp/8cccf200-2450-11e4-abe2-0002a5d5c52c.ta /lib/optee_armtz/
cp ta/testapp_storage/8dddf200-2450-11e4-abe2-0002a5d5c53d.ta /lib/optee_armtz/
cd -
2)运行CA/TA程序
$ tee-supplicant &
ERR [976] TEES:get_rkss_version:40: rk_secure_storage open fail
INF [976] TEES:tee_supp_rk_fs_init:123: get_rkss_version version=-1
INF [976] TEES:main:722: tee_supp_rk_fs_init: unsupported.
$ testapp
test value : Pass!
test tembuf : Pass!
test shmbuf : Pass!
# 串口输出
I/TA: Hello Test App!
I/TA: membuf test : Pass!
I/TA: Goodbye Test App!
$ testapp_storage
Success! Please check details from the serial!
# 串口输出
I/TA: Hello Test Storage!
I/TA: TEE_CreatePersistentObject success !
I/TA: TEE_WriteObjectData success !
I/TA: TEE_SeekObjectData success !
I/TA: TEE_ReadObjectData success !
I/TA: TA Storage : verify success
I/TA: before TEE_CloseAndDeletePersistentObject
I/TA: after TEE_CloseAndDeletePersistentObject
I/TA: Goodbye Test Storage!
参考资料
- docs/Linux/Security/Rockchip_Developer_Guide_TEE_SDK_CN.pdf
- docs/Kernel/TRUST/Rockchip_Developer_Guide_Trust_CN.pdf
网友评论