固件安全之 TF-A 和 SecureBoot

linux 2022-07-26 820 次浏览 次点赞


这里详细介绍基于 ARMv8-A AArch64 固件安全相关,包含 TF-A(Trust Firmware A)。以及基于TF-A OEM厂商对 U-Boot 和 Kernel 实现的安全启动流程 SecureBoot。

I. TBBR-CLIENT

对于 TF-A,ARMv8-A AArch64 架构需要满足如下设计需求。

  • 区分不同的异常等级(Exception Level);

异常等级

对于不同的安全等级区分了可信的世界(Trust World)和非可信世界(Non-Trusted World)。我们的应用程序,内核都工作它认为不可信世界,所以没有办法直接访问一些资源。

权限等级描述实现方
EL-0应用权限CPU支持
EL-1内核权限CPU支持
EL2虚拟权限等级CPU支持
EL-3安全权限等级CPU或者内部安全模块支持

  • 不同安全等级下访问不同的硬件资源。

    硬件资源

例如一些 OTP/eFUSE区域,在 EL0-EL2 异常等级应用程序是没有办法直接访问的。如果需要访问这些资源,通过 SMC 共享内存通过工作更高等级例如 EL3 的程序实现间接访问。

有了如上认识,接下来我们梳理 TF-A 约定的在不同 EL下的引导程序。

II. 固件设计

通常地,对于ARM AArch64 如下开机执行如下引导顺序。

boot sequence

提示:对于 AArch32 ,这里 BL31 为 BL32。

BL1

BL1 作为 ROM Bootloader 工作在最高安全等级 EL3,它拥有独立的 Trusted ROM 和 SRAM 区域。

BL1 会在平台指定的基地址载入 BL2,并且传递控制权到 BL2,此时 BL2 工作在SE-L1。

BL2

BL2 初始化终端 Console;

初始化次级引导的存储,用以接下来的加载。

使能 MMU 和以及它需要访问的存储空间;

保留部分存储用以次级 EL3 的引导;

BL31

BL2 载入 BL31,移交控制权 EL3 到 BL31。

BL31 执行如下架构初始化:

  • 初始化其关注的系统寄存器;
  • 初始化每个 CPU 的数据架构,提供 Cache 访问,用以提速。该初始化并行在多个 CPU 进行。

同时 BL31还会执行如下平台初始化:

  • 初始化终端 Console;
  • 初始化 MMU;
  • 初始化通用中断控制器;

BL33

BL33 通常就是 U-Boot,此次往后的应用都工作平台不信任的世界。但是此时 BL31 已经常驻内存,如果需要访问安全世界的资源,需要通过 SMC(共享内存) 方式调用BL31接口。

III. 证书链

如上引导,除了 BL1 是固化在 ROM,其他都是在非可信的外部存储,例如 Flash、EMMC。那么平台又是如何保证其的安全的。

如下证书链导出过程指示了多个用以不同固件签名的私钥生成。

images/cot_export.png

如上框图指示,厂商会预制一个公钥到硬件,基于该公钥的私钥我们签名了多个证书。

  • Non-Trusted Firmware Updater certificate

    该证书对应私钥用以非可信固件的签名,公钥用以升级过程的验签。

  • Trusted Boot Firmware certificate

    该证书对应私钥用以可信固件的签名,公钥用以升级过程的验签。

  • Trusted Key certificate

    可信秘钥证书对应私钥(OEM Private KEY)又签发了 Trusted Key certificate,包含三个公钥,分别对应:

    1. Debug Public Key。
    2. Trusted World Public Key。

      该证书用以 BL2 和 BL31 的认证。

    3. Non-Trusted World Public Key。

      这里用以 BL33,即 U-Boot 的认证。

提示:这里有个关键点:对于 Trusted Key certificate 的签发通常芯片厂商会释放工具,相当于开放私钥。之前一直想不明白既然厂商公开了私钥任何人都可以更改后续证书?其实是因为Trusted Key certificate 是烧写在固定地址的 OTP (eFUSE)区域,只可以烧写一次。所以一旦在生产环节烧写了 Trusted Key certificate,那么芯片对应的 OEM Private KEY 也就唯一了。

最后我们确认下 BL31 的验签流程。

如下图指示,通过厂商预制根公钥 ROTPK 对生产阶段烧写的 Trusted Key Certificate 验签,之后得到可信的 Trusted World Public Key ,用该公钥验证 BL31 Key Certificate,得到 BL31 Content Certificate PK ,使用改公钥验证BL31 Content Certificate,之后得到 BL31固件的hash值。确认 BL31 Image 的可信。

+------------------+       +-------------------+
| ROTPK/ROTPK Hash |------>| Trusted Key       |
+------------------+       | Certificate       |
                           | (Auth Image)      |
                          /+-------------------+
                         /            |
                        /             |
                       /              |
                      /               |
                     L                v
+------------------+       +-------------------+
| Trusted World    |------>| BL31 Key          |
| Public Key       |       | Certificate       |
+------------------+       | (Auth Image)      |
                           +-------------------+
                          /           |
                         /            |
                        /             |
                       /              |
                      /               v
+------------------+ L     +-------------------+
| BL31 Content     |------>| BL31 Content      |
| Certificate PK   |       | Certificate       |
+------------------+       | (Auth Image)      |
                           +-------------------+
                          /           |
                         /            |
                        /             |
                       /              |
                      /               v
+------------------+ L     +-------------------+
| BL31 Hash        |------>| BL31 Image        |
|                  |       | (Data Image)      |
+------------------+       |                   |
                           +-------------------+

DIAGRAM 2.

相同的流程,通过厂商预制根公钥 ROTPK 对生产阶段烧写的 Trusted Key Certificate 验签,之后得到可信的 Non-Trusted World Public Key 对于BL33 的验证流程以及后续的对 Kernel 的验证流程就是 SecureBoot。


本文由 Jay 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处,点赞2

还不快抢沙发

添加新评论