安全之安全(security²)博客目录导读
目录
一、组件构成
二、Arm FVP平台PoC构建
三、在Armv8-A Foundation FVP上运行PoC
四、微调fTPM TA
可信启动(Measured Boot)是通过密码学方式度量启动阶段代码及关键数据(例如使用TPM芯片)的过程,以便后续对系统安全状态进行验证。
当前TF-A集成的驱动支持多种后端存储方式,每种方式采用不同的测量值存储机制。本节重点讨论TCG事件日志后端,该后端将测量值存储在安全内存中。
详见可信启动设计文档。
该驱动还提供将事件日志传递至普通世界的机制。
本手册提供的概念验证(PoC)构建指南,旨在演示如何将可信启动与基于OP-TEE实现的fTPM(fTPM)服务结合使用。
【注意】本文档的构建指南仅用于展示TF-A可信启动如何与第三方(f)TPM服务交互,内容尽可能保持通用性。不同平台可能存在不同需求和配置(例如采用不同SHA算法),也可能使用不同类型的TPM服务(甚至其他类型的证明服务),因此部分指南可能不适用于特定场景。
一、组件构成
该PoC基于OP-TEE工具链构建(自提交cf56848起支持在Foundation模型上运行带可信启动功能的TF-A)。该工具链生成的镜像集包含验证事件日志正确性所需的所有组件,其中一个镜像将集成第三方fTPM服务用于处理事件日志。
选择OP-TEE工具链构建PoC主要出于便利性考虑。由于fTPM服务是OP-TEE可信应用(TA),可轻松将其编译支持添加到工具链中。
与可信启动/fTPM功能密切相关的核心组件包括:
-
OP-TEE:本PoC使用的fTPM服务作为OP-TEE TA运行,因此需包含OP-TEE OS镜像。OP-TEE 3.9.0版本通过实现PTA_SYSTEM_GET_TPM_EVENT_LOG系统调用,支持从TF-A获取事件日志副本。OP-TEE通过解析TF-A传递的DTB绑定信息定位事件日志(详见事件日志DTB绑定属性说明)。
-
fTPM服务:采用微软ms-tpm-20-ref参考实现中的Aarch32架构示例,该服务已扩展支持在启动时处理可信启动事件日志,并通过上述系统调用获取日志副本。
【注意】Arm不提供fTPM实现。本PoC使用的第三方fTPM服务经修改支持TF-A可信启动,其输出正确性验证超出本手册范围。
-
TPM内核模块:用于将用户空间请求转发至安全世界。
-
tpm2-tools工具集:用于读取fTPM服务中的PCR测量值。
二、Arm FVP平台PoC构建
如前所述,此PoC基于OP-TEE工具包,具有一些扩展以启用Measured Boot和fTPM服务。因此,我们可以依靠这些指令来构建原始的OP-TEE工具包。一般来说,以下步骤就足够了:
-
首先,按照获取和构建解决方案的指导来构建OP-TEE工具包。在步骤3中,您需要从主分支获取FVP平台的manifest:
$ repo init -u https://github.com/OP-TEE/manifest.git -m fvp.xml
-
接下来,您应该获得Armv8-A Foundation Platform (For Linux Hosts Only)。二进制文件应该解压缩到repo树的根目录,即像这样:<fvp-project>/Foundation_Platformpkg。最后,在克隆所有源代码,获得工具链并“安装”Foundation_Platformpkg之后,你应该有一个看起来像这样的文件夹结构:
$ ls -la
total 80
drwxrwxr-x 20 tf-a_user tf-a_user 4096 Jul 1 12:16 .
drwxr-xr-x 23 tf-a_user tf-a_user 4096 Jul 1 10:40 ..
drwxrwxr-x 12 tf-a_user tf-a_user 4096 Jul 1 10:45 build
drwxrwxr-x 16 tf-a_user tf-a_user 4096 Jul 1 12:16 buildroot
drwxrwxr-x 51 tf-a_user tf-a_user 4096 Jul 1 10:45 edk2
drwxrwxr-x 6 tf-a_user tf-a_user 4096 Jul 1 12:14 edk2-platforms
drwxr-xr-x 7 tf-a_user tf-a_user 4096 Jul 1 10:52 Foundation_Platformpkg
drwxrwxr-x 17 tf-a_user tf-a_user 4096 Jul 2 10:40 grub
drwxrwxr-x 25 tf-a_user tf-a_user 4096 Jul 2 10:39 linux
drwxrwxr-x 15 tf-a_user tf-a_user 4096 Jul 1 10:45 mbedtls
drwxrwxr-x 6 tf-a_user tf-a_user 4096 Jul 1 10:45 ms-tpm-20-ref
drwxrwxr-x 8 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_client
drwxrwxr-x 10 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_examples
drwxrwxr-x 12 tf-a_user tf-a_user 4096 Jul 1 12:13 optee_os
drwxrwxr-x 8 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_test
drwxrwxr-x 7 tf-a_user tf-a_user 4096 Jul 1 10:45 .repo
drwxrwxr-x 4 tf-a_user tf-a_user 4096 Jul 1 12:12 toolchains
drwxrwxr-x 21 tf-a_user tf-a_user 4096 Jul 1 12:15 trusted-firmware-a
3. 现在进入ms-tpm-20-ref并获取其依赖项:
$ cd ms-tpm-20-ref
$ git submodule init
$ git submodule update
Submodule path 'external/wolfssl': checked out '9c87f979a7f1d3a6d786b260653d566c1d31a1c4'
4.现在,您应该能够继续执行“获取并构建解决方案(Get and build the solution)”说明中的第5步。为了启用对Measured Boot的支持,您需要设置以下构建选项:
$ MEASURED_BOOT=y MEASURED_BOOT_FTPM=y make -j `nproc`
【注意】:构建过程可能需要很长时间。强烈建议传递-j选项以使进程运行得更快。
在这一步之后,您应该已经准备好运行镜像了。
三、在Armv8-A Foundation FVP上运行PoC
构建好所有内容后,现在可以运行镜像:
$ make run-only
【注意】:使用make run将构建并运行镜像,可以使用它来代替简单的make。但是,一旦构建了镜像,建议使用make run-only来避免重新运行所有构建规则,这将花费时间。
当启动FVP(固定虚拟平台)时,会出现两个终端窗口。FVP terminal_0是用户空间终端,而FVP terminal_1是安全世界(Secure World)的对应终端(例如可信应用TAs的日志将在此处输出)。
使用root用户登录系统镜像shell(无需密码),随后可执行ftpm命令。该命令是一个组合别名,其功能包括:
-
加载ftpm内核模块
-
调用tpm2_pcrread访问fTPM服务以读取PCR值
当加载ftpm内核模块时,fTPM可信应用(TA)会被载入安全世界。该TA随后会请求获取引导过程中生成的事件日志(Event Log)副本,从而首先检索并记录日志中的所有条目。
【注意】对于这个PoC,在BL33和NT_FW_CONFIG之后加载的任何内容都不会记录在事件日志中。
安全世界终端应该显示fTPM服务的调试日志,包括正在处理的事件日志中可用的所有测量:
M/TA: Preparing to extend the following TPM Event Log:
M/TA: TCG_EfiSpecIDEvent:
M/TA: PCRIndex : 0
M/TA: EventType : 3
M/TA: Digest : 00
M/TA: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
M/TA: : 00 00 00
M/TA: EventSize : 33
M/TA: Signature : Spec ID Event03
M/TA: PlatformClass : 0
M/TA: SpecVersion : 2.0.2
M/TA: UintnSize : 1
M/TA: NumberOfAlgorithms : 1
M/TA: DigestSizes :
M/TA: #0 AlgorithmId : SHA256
M/TA: DigestSize : 32
M/TA: VendorInfoSize : 0
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 3
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
M/TA: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
M/TA: EventSize : 17
M/TA: Signature : StartupLocality
M/TA: StartupLocality : 0
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 58 26 32 6e 64 45 64 da 45 de 35 db 96 fd ed 63
M/TA: : 2a 6a d4 0d aa 94 b0 b1 55 e4 72 e7 1f 0a e0 d5
M/TA: EventSize : 5
M/TA: Event : BL_2
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : cf f9 7d a3 5c 73 ac cb 7b a0 25 80 6a 6e 50 a5
M/TA: : 6b 2e d2 8c c9 36 92 7d 46 c5 b9 c3 a4 6c 51 7c
M/TA: EventSize : 6
M/TA: Event : BL_31
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 23 b0 a3 5d 54 d9 43 1a 5c b9 89 63 1c da 06 c2
M/TA: : e5 de e7 7e 99 17 52 12 7d f7 45 ca 4f 4a 39 c0
M/TA: EventSize : 10
M/TA: Event : HW_CONFIG
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a
M/TA: : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0
M/TA: EventSize : 14
M/TA: Event : SOC_FW_CONFIG
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 01 b0 80 47 a1 ce 86 cd df 89 d2 1f 2e fc 6c 22
M/TA: : f8 19 ec 6e 1e ec 73 ba 5a be d0 96 e3 5f 6d 75
M/TA: EventSize : 6
M/TA: Event : BL_32
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 5d c6 ef 35 5a 90 81 b4 37 e6 3b 52 da 92 ab 8e
M/TA: : d9 6e 93 98 2d 40 87 96 1b 5a a7 ee f1 f4 40 63
M/TA: EventSize : 18
M/TA: Event : BL32_EXTRA1_IMAGE
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 39 b7 13 b9 93 db 32 2f 1b 48 30 eb 2c f2 5c 25
M/TA: : 00 0f 38 dc 8e c8 02 cd 79 f2 48 d2 2c 25 ab e2
M/TA: EventSize : 6
M/TA: Event : BL_33
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6
M/TA: : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a
M/TA: EventSize : 13
M/TA: Event : NT_FW_CONFIG
这些日志对应于TF-A在测量的引导过程中存储的测量值,因此,它们应该与TF-A在启动过程中转储的日志相匹配。这些可以在terminal_0上看到:
NOTICE: Booting Trusted Firmware
NOTICE: BL1: v2.5(release):v2.5
NOTICE: BL1: Built : 10:41:20, Jul 2 2021
NOTICE: BL1: Booting BL2
NOTICE: BL2: v2.5(release):v2.5
NOTICE: BL2: Built : 10:41:20, Jul 2 2021
NOTICE: TCG_EfiSpecIDEvent:
NOTICE: PCRIndex : 0
NOTICE: EventType : 3
NOTICE: Digest : 00
NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
NOTICE: : 00 00 00
NOTICE: EventSize : 33
NOTICE: Signature : Spec ID Event03
NOTICE: PlatformClass : 0
NOTICE: SpecVersion : 2.0.2
NOTICE: UintnSize : 1
NOTICE: NumberOfAlgorithms : 1
NOTICE: DigestSizes :
NOTICE: #0 AlgorithmId : SHA256
NOTICE: DigestSize : 32
NOTICE: VendorInfoSize : 0
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 3
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
NOTICE: EventSize : 17
NOTICE: Signature : StartupLocality
NOTICE: StartupLocality : 0
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 58 26 32 6e 64 45 64 da 45 de 35 db 96 fd ed 63
NOTICE: : 2a 6a d4 0d aa 94 b0 b1 55 e4 72 e7 1f 0a e0 d5
NOTICE: EventSize : 5
NOTICE: Event : BL_2
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : cf f9 7d a3 5c 73 ac cb 7b a0 25 80 6a 6e 50 a5
NOTICE: : 6b 2e d2 8c c9 36 92 7d 46 c5 b9 c3 a4 6c 51 7c
NOTICE: EventSize : 6
NOTICE: Event : BL_31
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 23 b0 a3 5d 54 d9 43 1a 5c b9 89 63 1c da 06 c2
NOTICE: : e5 de e7 7e 99 17 52 12 7d f7 45 ca 4f 4a 39 c0
NOTICE: EventSize : 10
NOTICE: Event : HW_CONFIG
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a
NOTICE: : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0
NOTICE: EventSize : 14
NOTICE: Event : SOC_FW_CONFIG
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 01 b0 80 47 a1 ce 86 cd df 89 d2 1f 2e fc 6c 22
NOTICE: : f8 19 ec 6e 1e ec 73 ba 5a be d0 96 e3 5f 6d 75
NOTICE: EventSize : 6
NOTICE: Event : BL_32
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 5d c6 ef 35 5a 90 81 b4 37 e6 3b 52 da 92 ab 8e
NOTICE: : d9 6e 93 98 2d 40 87 96 1b 5a a7 ee f1 f4 40 63
NOTICE: EventSize : 18
NOTICE: Event : BL32_EXTRA1_IMAGE
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 39 b7 13 b9 93 db 32 2f 1b 48 30 eb 2c f2 5c 25
NOTICE: : 00 0f 38 dc 8e c8 02 cd 79 f2 48 d2 2c 25 ab e2
NOTICE: EventSize : 6
NOTICE: Event : BL_33
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6
NOTICE: : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a
NOTICE: EventSize : 13
NOTICE: Event : NT_FW_CONFIG
NOTICE: BL1: Booting BL31
NOTICE: BL31: v2.5(release):v2.5
NOTICE: BL31: Built : 10:41:20, Jul 2 2021
跟踪fTPM启动过程,我们可以看到事件日志中的所有测量都被扩展并记录在适当的PCR中:
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: 9 Event logs processed
在加载fTPM TA之后,由fTPM别名发出的对insmod的调用返回,以加载fTPM内核模块,然后通过tpm_pcrread命令读取TPM PCRs。请注意,我们在这里只对SHA256日志感兴趣,因为这是我们在TF-A上用于测量的算法(参见上面日志中的AlgorithmId字段):
sha256:
0 : 0xA6EB3A7417B8CFA9EBA2E7C22AD5A4C03CDB8F3FBDD7667F9C3EF2EA285A8C9F
1 : 0x0000000000000000000000000000000000000000000000000000000000000000
2 : 0x0000000000000000000000000000000000000000000000000000000000000000
3 : 0x0000000000000000000000000000000000000000000000000000000000000000
4 : 0x0000000000000000000000000000000000000000000000000000000000000000
5 : 0x0000000000000000000000000000000000000000000000000000000000000000
6 : 0x0000000000000000000000000000000000000000000000000000000000000000
7 : 0x0000000000000000000000000000000000000000000000000000000000000000
8 : 0x0000000000000000000000000000000000000000000000000000000000000000
9 : 0x0000000000000000000000000000000000000000000000000000000000000000
10: 0x0000000000000000000000000000000000000000000000000000000000000000
11: 0x0000000000000000000000000000000000000000000000000000000000000000
12: 0x0000000000000000000000000000000000000000000000000000000000000000
13: 0x0000000000000000000000000000000000000000000000000000000000000000
14: 0x0000000000000000000000000000000000000000000000000000000000000000
15: 0x0000000000000000000000000000000000000000000000000000000000000000
16: 0x0000000000000000000000000000000000000000000000000000000000000000
17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
23: 0x0000000000000000000000000000000000000000000000000000000000000000
在这个PoC中,我们只对PCR0感兴趣,它必须是非空的。这是因为引导进程记录了这个PCR中的所有映像(参见上面事件日志中的PCRIndex字段)。此时其余的记录必须为0。
【注意】:使用的fTPM服务只支持16个pcr,因此超过15个pcr的内容可以忽略。
【注意】:如前所述,Arm不提供fTPM实现,因此我们在这里不验证PCR0的内容是否正确。对于这个PoC,我们只关注事件日志可以传递给第三方fTPM,并且它的记录得到了适当的扩展。
四、微调fTPM TA
如前所述,OP-TEE工具包包括对构建第三方fTPM服务的支持。此服务的构建选项是为PoC量身定制的,并在构建环境变量FTPM_FLAGS中定义(请参阅<toolkit_home>/build/common.mk),但如果需要,可以修改它们以更好地适应特定场景。
测量引导支持最相关的选项是:
•CFG_TA_DEBUG:启用Terminal_1控制台的调试日志。
•CFG_TEE_TA_LOG_LEVEL:定义用于调试消息的日志级别。
•CFG_TA_MEASURED_BOOT:启用对fTPM上测量引导的支持。
•CFG_TA_EVENT_LOG_SIZE:定义fTPM能够存储的大事件日志的大小(以字节为单位),因为这个缓冲区是在构建时分配的。这必须至少与TF-A生成的事件日志的大小相同。如果没有定义这个构建选项,那么fTPM就会退回到1024字节的默认值,这对于这个PoC来说已经足够了,所以这个变量没有在FTPM_FLAGS中定义。