LS10xx安全架构和安全启动
一、信任架构概述
QoriQ平台的信任架构可以使开发者仅仅靠运行”授权软件程序“来保护您设计的产品,并提供工具在运行环境的生命周期内不间断的检测硬件的安全状态,在运行时环境中检测到的异常会触发硬件状态更改,从而导致系统锁定对先前加密数据的访问或重启硬件。
所有具有信任架构的QorlQ Layerscape 设备都支持以下两种启动模式:
- 正常启动(不信任环境)
- 安全启动
预引导加载程序 pre-boot loader(PBL)允许您在正常引导或安全引导之间进行选择。有两种方法可以命令PBL启动安全启动过程:
- 对正在运行的系统的安全意图 intent to secure(ITS)保险丝进行编程
- 在原型设计之初就在RCW中设置启用安全启动 secure boot enable(SB_EN)位
在安全启动模式下,数字签名的启动映像会在启动期间进行验证。验证期间的失败要么使CPU进入自旋循环(具有ITS的系统),要么继续引导到非安全状态(具有SB_EN的环境)。
使用信任架构需要一些强制性最低配置和可选配置。
强制性最低配置和程序包括代码签名和对安全熔断器处理器(SFP)中的某些字段进行编程。
可选配置包括对一些增强功能的支持,例如篡改检测(tmp_detect)、运行时完整性检查(RTIC)、安全调试、密钥撤销和安全数据存储(加密的二进制数据)。
二、安全启动:最低要求
安全启动过程包括对现有软件必要的准备工作并对安全启动过程使用的熔丝进行编程。
在安全启动模式下,SoC的CPU是从一段包含内部安全启动代码 internal secure boot code(ISBC)的不可修改的内部启动ROM开始启动的。
ISBC的功能是去验证一段被称为外部安全启动代码 external secure boot code(ESBC)的可修改代码。
ESBC可以是一个与引导设备(U-Boot、设备树、内核、rootfs)相关的连续内存空间中的单个集成镜像,也可以是存在于软件镜像链的第一阶段中可以单独验证和调用的程序。第二阶段也称为信任链。使用信任链时,您可以为链中的每个镜像使用单个密钥对,或为不同的镜像使用不同的密钥对。
为简单起见,本文档使用单个密钥对对安全启动中涉及的所有镜像进行签名。
三、软件准备
NXP QorlQ软件开发套件(SDK)是用于编译和构建可以在QorlQ Layerscape目标系统上运行的软件映像的免费开发工具。
SDK包括一系列在构建机器上运行并协助准备系统以进行安全启动的可选工具。该工具包统称为代码签名工具(CST)。
在使用安全启动之前,请确保您创建了一个非安全启动映像并在开发板上对其进行测试。如果使用NOR 闪存进行引导,请确保非安全弓引导映像在主存储库和备用存储库上均有效。这保证了当其中一个映像/库更新以进行安全启动时,如果代码签名或映像更新过程中出现错误,另一个映像/库仍然可用。
如前所述,安全启动有两个主要阶段:
- 执行ISBC
- 执行ESBC
ISBC不可修改,但ESBC可以修改。QorlQ SDK包括两个参考ESBC。一个是与引导加载程序、引导脚本、根文件系统、设备树和Linux内核的融为一体的完整映像。另一个是信任链,其中ESBC是引导加载程序,带有一些额外的命令来验证信任链中其他阶段的签名。在未来的SDK版本中,信任链将遵循UEFI模型。然而,就本文档而言,这种区别并不重要。
如果您没有现有工具来生成对称或非对称加密密钥,则可以使用SDK中基于OpenSSL的密钥生成器软件。
3.1 代码签名工具 Code signing tool(CST)
必须向ISBC提供有关ESBC的元数据(例如ESBC和公钥的位置和大小),才能执行数字签名验证。此元数据称为CSF标头,生成它是代码签名工具的主要功能之一。有关CSF标头结构和数字签名验证算法的详细信息,请参阅信任架构用户指南。
添加CSF 标头后,代码签名涉及在包含CSF标头的镜像上创建数字签名。数字签名是对镜像进行加密的RSA私钥的SHA-256哈希值(一个私有密钥的哈希值)。对于信任链,您可以选择使用不同的RSA私钥对链中的每个阶段进行签名。
CST支持以下任务:
- 创建CSF标头并将其添加到启动映像中。
- 生成RSA公钥/私钥对。
- 生成可用作一次性可编程主密钥 one time programmable master key(OTPMK)和调试响应值 debug response value(DRV)的随机数。
- 在 OTPMK 和 DRV 中嵌入汉明码(以支持对保险丝损坏的硬件检测)。
- 计算 sh-2 哈希。
接下来的几节提供有关使用 CST 执行这些功能的详细信息。
默认情况下不安装 CST。 在您的构建机器上安装 SDK 并成功构建引导软件(U-Boot.bin、dtb、uImage 等)后,运行以下命令来安装 CST:
bitbake fsl-image-full
bitbake cst-native -c cleanall
bitbake cst-native
CST 安装在build_Is1043ardb_release/tmp/sysroots/x86_64-linux/usr/bin/cst路径下:
$ ls -l tmp/sysroots/x86_64-linux/usr/bin/cst/
total 356
-rwxr-xr-x 3 user_lab user_lab 21131 Jan 12 08:27 gen_drv
-rwxr-xr-x 3 user_lab user_lab 25500 Jan 12 08:27 gen_keys
-rwxr-xr-x 3 user_lab user_lab 21203 Jan 12 08:27 gen_otpmk
-rwxr-xr-x 3 user_lab user_lab 34024 Jan 12 08:27 gen_sign
drwxrwxr-x 6 user_lab user_lab 4096 Jan 12 08:27 input_files
-rwxr-xr-x 3 user_lab user_lab 35867 Jan 12 08:27 sign_embed
-rwxr-xr-x 3 user_lab user_lab 52250 Jan 12 08:27 uni_cfsign
-rwxr-xr-x 3 user_lab user_lab 52002 Jan 12 08:27 uni_pbi
-rwxr-xr-x 3 user_lab user_lab 100403 Jan 12 08:27 uni_sign
3.1.1 生成RSA密钥
使用gen_keys命令生成RSA密钥,包含公钥srk.pub和私钥srk.pri:
./gen_keys SIZE NAME
SIZE是以bits为单位的公钥的大小. (Modulus size).
支持的大小 -- 1024, 2048, 4096. 生成的密钥使用 PEM 格式
../cst/gen_keys 1024 -p srk.pri -k srk.pub
===============================================================
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/)
This product includes cryptographic software written by Eric Young (eay@cryptsoft.com)
===============================================================
Generated SRK pair stored in :
PUBLIC KEY srk.pub
PRIVATE KEY srk.pri
Here is an example of the srk.pri the gen_keys created.
Here is a sample of public key, srk.pub, generated from the above command:
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMh5wHLwU30zJgPbIZtQzPEjMgfeINs3LIM155El9eKNm5tdJ10Q912SsipHhshCf7+fYAcGJxtwsPqVi/Pegzoh4eGZHPoVuBLZ0p4LpJXwzhXvFnma+FyBadrju0ra8KbDaNLPBK4bgzdpPQBBq7CTTfucnQVrCHTZUtX5dSQVAgMBAAE=
-----END RSA PUBLIC KEY-----
3.1.2 为安全启动映像创建CSF标头
CST提供的脚本可以帮助您将必要的信息(如标头信息和创建U-Boot 脚本)附加到软件镜像以进行安全启动过程。
脚本文件位于CST目录中:
$ ls -l input_files/uni_sign/ls1043
total 12
-rw-rw-r-- 3 user_lab user_lab 3490 Jan 27 00:34 input_bootscript_secure
-rw-rw-r-- 3 user_lab user_lab 3537 Jan 27 00:34 input_kernel_secure
-rw-rw-r-- 3 user_lab user_lab 3604 Jan 27 00:34 input_uboot_nor_secure
对于U-Boot映像,为映像名称和要对映像签名的RSA密钥对编辑以下文件:
$ vi input_files/uni_sign/ls1043/input_uboot_nor_secure
Modify “IMAGE_1={u-boot-ls1043ardb.bin,60100000,ffffffff}”
输入字段在input_uboot_secure 文件中指定(input_uboot_nor_secure暗示这是使用NOR闪存映射)。确保input_uboot_secure中提到的文件名
与在CST目录中复制的相同。您可以保留U-boot镜像的默认地址为60100000h。
对于Linux内核和根文件系统,编辑:
$ vi input_files/uni_sign/ls1043/input_kernel_secure
Modify “IMAGE_1={kernel-fsl-ls1043a-rdb.dtb-ls1043ardb.itb,81000000,ffffffff}”
kernel-fsl-ls1043a-rdb.dtb-Is1043ardb.itb将被U-Boot 认证。这里使用的flash地址反映了U-Boot的地址映射。确保input_uimage_secure中提到的文件名与您从CST目录复制的文件名相同。
对于启动脚本,修改:
$ vi input_files/uni_sign/ls1043/input_bootscript_secure
确保引导脚本中提到的文件名与您从 CST 目录复制的文件名相同。
3.1.3 对软件镜像进行签名
当所有文件都有CSF标头和数字签名时,使用CST工具以十六进制字节的二进制哈希而不是文本的字符串哈希生成以下SHA-256哈希!
$./uni_sign --hash input_uboot_secure
./uni_sign --hash input_files/uni_sign/ls1043/input_uboot_nor_secure
===============================================================
This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/)
This product includes cryptographic software written by
Eric Young (eay@cryptsoft.com)
===============================================================
Key Hash :
5390ad44c39af1da414487399627f9847f60aa52a3675d14c60434602b970e9f
生成的Key Hash用于对超级根密钥哈希 super root key hash(SRKH)寄存器进行编程。您必须将密钥哈希值转换为多个32位卡盘,以便它与SRKH寄存器对齐。
注意
CST 以与 SFP 相同的字节顺序生成 SRKH。 要在运行 little endian 模式的 ARM 内核中对 SRKH 进行编程,需要进行字节交换。
Table 1. SRKH 值示例
Offset | Register name | Example value | Endianness swap |
---|---|---|---|
01E8_0254 | SRKH 0 255-224 | 5390ad44 | 44ad9053 |
01E8_0258 | SRKH 1 223-192 | c39af1da | daf19ac3 |
01E8_025C | SRKH 2 191-160 | 41448739 | 39874441 |
01E8_0260 | SRKH 3 159-128 | 9627f984 | 84f92796 |
01E8_0264 | SRKH 4 127-96 | 7f60aa52 | 52aa607f |
01E8_0268 | SRKH 5 95-64 | a3675d14 | 145d67a3 |
01E8_026C | SRKH 6 63-32 | c6043460 | 603404c6 |
01E8_0270 | SRKH 7 31-0 | 2b970e9f | 9f0e972b |
3.1.4 生成OTPMK
运行以下命令生成OTPMK:
>./gen_otpmk --help
Usage: ./gen_otpmk <trust_arch> [string]
string : 32 byte string
e.g. gen_otpmk 1 1111111122222222333333334444444455555555666666667777777788888888
>./gen_otpmk 2 1111111122222222333333334444444455555555666666667777777788888888
NAME | BITS | VALUE
_________|______________|____________
OTPMKR 0 | 31- 0 | 11111111
OTPMKR 1 | 63- 32 | 22222222
OTPMKR 2 | 95- 64 | 33333333
OTPMKR 3 | 127- 96 | 44444444
OTPMKR 4 | 159-128 | 55555555
OTPMKR 5 | 191-160 | 66666666
OTPMKR 6 | 223-192 | 77777777
OTPMKR 7 | 255-224 | 88888888
先这些信息放在旁边。后续的步骤中您需要它在熔丝编程步骤中对OTPMK 进行编程。
四、熔断器编程
4.1 SFP内存映射
有两组与安全启动相关的内存区域:
- 安全保险丝处理器(SFP)
- 安全监视器内存(SECMON)
安全启动相关寄存器的详细信息记录在SoC特定参考手册和信任架构用户指南中。两者都提供了与每个寄存器相关的完整详细信息和选项。
为方便起见,SFP和SECMON内存映射的布局如下所示。本文档中的示例仅对粗体字的寄存器进行编程。
注意
除了SFP_INGR,SFP中其他的所有的寄存器的变化是永久性的,不可逆的。
Table 1. 简化安全保险丝处理器内存映射
Offset | Register Name |
---|---|
01E8_0020 | Instruction Register (SFP_INGR) —— 指令寄存器 |
01E8_0024 | Secret Value Hamming Error Status Register (SFP_SVHESR) —— 秘密值汉明错误状态寄存器 |
01E8_0028 | SFP Configuration Register (SFP_SFPCR) —— SFP配置寄存器 |
01E8_0200 | OEM Security Policy Register (SFP_OSPR to 1) —— OEM安全策略寄存器 |
01E8_0208 | Debug Challenge Value Register n (SFP_DCVR0 to 1) —— 调试质询值寄存器 |
01E8_0210 | Debug Response Value Register n (SFP_DRVR0 to 1 ) —— 调试响应值寄存器 |
01E8_0218 | Freescale Section Write Protect Register (SFP_FSWPR) —— 飞思卡尔部分写保护寄存器 |
01E8_021C | Freescale Unique ID Register n (SFP_FUIDR0 to 1) —— 飞思卡尔唯一ID寄存器 |
01E8_0224 | ISBC Configuration Register (SFP_ISBCCR) —— ISBC配置寄存器 |
01E8_0228 | Freescale Scratch Pad Fuse Register n (SFP_FSPFR0 to 2) —— 飞思卡尔暂存器保险丝寄存器 |
01E8_0234 | One Time Programmable Master Key n (SFP_OTPMKR0 to 7) —— 一次性可编程主密钥 |
01E8_0254 | Super Root Key Hash n (SFP_SRKHR0 to 7) —— 超级根密钥哈希 |
01E8_0274 | OEM Unique ID/Scratch Pad Fuse Register n (SFP_OUIDR0 to 4) —— OEM唯一ID/暂存器保险丝寄存器 |
Table 2. 简化安全监视器内存内存映射
Offset | Register Name |
---|---|
01E9_0000 | SecMon_HP Lock (HPLR) —— SecMon_HP锁定 |
01E9_0004 | SecMon_HP Command (HPCOMR) —— SecMon_HP命令 |
01E9_0008 | SecMon_HP Control (HPCR) —— SecMon_HP控制 |
01E9_000C | SecMon_HP Security Interrupt Control (HPSICR) —— SecMon_HP安全中断控制 |
01E9_0010 | SecMon_HP Security Violation Control (HPSVCR) —— SecMon_HP 安全违规控制 |
01E9_0014 | SecMon_HP Status (HPSR) —— SecMon_HP 状态 |
01E9_0018 | SecMon_HP Security Violation Status (HPSVSR) —— SecMon_HP安全违规状态 |
01E9_001C | SecMon_HP High Assurance Counter IV (HPHACIVR) —— SecMon_HP高保证计数器IV |
01E9_0020 | SecMon_HP High Assurance Counter (HPHACR) —— SecMon_HP 高保证计数器 |
01E9_0024 | SecMon_HP Real-Time Counter MSB (HPRTCMR) —— SecMon_HP 实时计数器MSB |
01E9_0028 | SecMon_HP Real-Time Counter LSB (HPRTCLR) —— SecMon_HP 实时计数器LSB |
01E9_002C | SecMon_HP Time Alarm MSB (HPTAMR) —— SecMon_HP 时间警报MSB |
01E9_0030 | SecMon_HP Time Alarm LSB (HPTALR) —— SecMon_HP 时间警报LSB |
01E9_0034 | SecMon_LP Lock (LPLR) —— SecMon_LP锁定 |
01E9_0038 | SecMon_LP Control (LPCR) —— SecMon_LP控制 |
01E9_003C | SecMon_LP Master Key Control (LPMKCR) —— SecMon_LP 主密钥控制 |
01E9_0040 | SecMon_LP Security Violation Control (LPSVCR) —— SecMon_LP安全违规控制 |
01E9_0048 | SecMon_LP Tamper Detectors Configuration (LPTDCR) —— SecMon_LP篡改检测器配置 |
01E9_004C | SecMon_LP Status (LPSR) —— SecMon_LP状态 |
01E9_0050 | SecMon_LP Secure Real-Time Counter MSB (LPSRTCMR) —— SecMon_LP安全实时计数器MSB |
01E9_0054 | SecMon_LP Secure Real-Time Counter LSB (LPSRTCLR) —— SecMon_LP安全实时计数器LSB |
01E9_0058 | SecMon_LP Time Alarm (LPTAR) —— SecMon_LP时间警报 |
01E9_005C | SecMon_LP Secure Monotonic Counter MSB (LPSMCMR) —— SecMon_LP安全单调计数器MSB |
01E9_0060 | SecMon_LP Secure Monotonic Counter LSB (LPSMCLR) —— SecMon_LP安全单调计数器LSB |
01E9_0064 | SecMon_LP Power Glitch Detector (LPPGDR) —— SecMon_LP电源毛刺检测器 |
01E9_006C - 88 | SecMon_LP Zeroizable Master Key (LPZMKR0 - LPZMKR7) —— SecMon_LP可归零主密钥 |
01E9_0BF8 - FC | SecMon_HP Version ID 1 and 2 (HPVIDR1, HPVIDR2) —— SecMon_HP版本ID1和2 |
4.2 程序熔断器
安全启动需要将永久信息融合到SOC中。有两种类型的信息需要融合。
第一种类型是秘密值。一旦秘密值被融合到处理器中,通用处理器就无法将其读回。例如,您可以当系统处于信任或安全状态时使用此密钥值生成可用于所有后续加密和解密操作的加密密钥。您还可以使用此密钥值来存储硬件调试接口的密码,例如JTAG端口。
第二种必须熔断的信息是纯数据。通用处理器可以读回纯数据。例如,该永久数据可以存储密钥或软件映像的校验和。您可以使用此校验和值来验证安全启动过程的公钥。您还可以使用永久数据存储密码提示,以防忘记密码。
注意
为确保熔断值的可靠性,请尽量减少对熔断器进行编程的次数。查看SoC的具体参考手册以获取通过提高POVDD对熔断器进行编程的最大次数
4.2.1 提高POVDD电压
提高POVDD电压以对安全保险丝进行编程。
在NXP的大多数开发板中,这可以通过添加跳线或更改DIP开关设置来完成。例如,下图显示了将POVDD升高到1.89V和所需的LS1043ARDB板跳线设置对保险丝进行编程。有关您正在使用的特定开发板的详细信息,请参阅 SOC特定快速用户指南。
4.2.2.对SRKH镜像寄存器进行编程
此示例中使用的SRKH值来自《3.1.3 对软件镜像进行签名》。除非您使用相同的srk.pri,否则您系统的SRKH会有所不同。
按照以下步骤对保险丝进行编程:
1.在U-Boot 提示符下,使用mm(内存修改)命令修改和md(内存display)命令显示SRKH 寄存器。
注意
对于那些构建U-Boot 脚本的人,请使用mw(内存写入)命令而不是mm命令。
2.对SRKH寄存器进行编程:
=> mm 0x01E80254
01e80254: 00000000 ? 44ad9053
01e80258: 00000000 ? daf19ac3
01e8025c: 00000000 ? 39874441
01e80260: 00000000 ? 84f92796
01e80264: 00000000 ? 52aa607f
01e80268: 00000000 ? 145d67a3
01e8026c: 00000000 ? 603404c6
01e80270: 00000000 ? 9f0e972b
01e80274: 00000000 ? .
3.显示并验证SRKH寄存器是否已在上一步中编程
=> md 0x01E80234
01e80234: 00000000 00000000 00000000 00000000 ................
01e80244: 00000000 00000000 00000000 00000000 ................
01e80254: 44ad9053 daf19ac3 39874441 84f92796 .=J$.\6..?...%_.
01e80264: 52aa607f 145d67a3 603404c6 9f0e972b .....t....O\....
01e80274: 00000000 00000000 00000000 00000000 ................
01e80284: 00000000 00000000 00000000 00000000 ................
如果出现错误,可以重新在U-Boot输入mm命令,直到写入程序位为止。确保值正确。请注意,一旦发出程序熔丝块命令,就不能修改或复位SRKH寄存器。
4.2.3 对OTPMK镜像寄存器进行编程
一次性可编程主密钥one time programmable master key(OTPMK)是一种无法回读的保险丝。OTPMK用于生成与信任架构相关的加密操作的黑密钥。对于原型设计,可以参考《3.1.4 生成OTPMK》来生成的简单易记的密钥。
仅当OTPMK为空时才对它进行编程。“ffff”表示OTPMK寄存器不为空。
1.编写OTPMK:
=> mm 0x01E80234
01e80234: 00000000 ? 11111111
01e80238: ffffffff ? 22222222
01e8023c: ffffffff ? 33333333
01e80240: ffffffff ? 44444444
01e80244: ffffffff ? 55555555
01e80248: ffffffff ? 66666666
01e8024c: ffffffff ? 77777777
01e80250: ffffffff ? 88888888
01e80254: 00000000 ? .
2.验证OTPMK不为空:
=> md 0x01E80234
01e80234: ffffffff ffffffff ffffffff ffffffff ................
01e80244: ffffffff ffffffff ffffffff ffffffff ................
01e80254: 44ad9053 daf19ac3 39874441 84f92796 .=J$.\6..?...%_.
01e80264: 52aa607f 145d67a3 603404c6 9f0e972b .....t....O\....
01e80274: 00000000 00000000 00000000 00000000 ................
01e80284: 00000000 00000000 00000000 00000000 ................
4.2.4 提交更改
SFP 指令寄存器(SFP_INGR)允许您读取或编程SFP熔丝阵列。但是,该寄存器没有写保护,因为指令寄存器中的值不会反映在熔丝阵列中。SFP是一个大端设备!因此,向SFP_INGR @ 0x1E8_0020发出编程熔丝块命令(progFB = x02000000)以提交熔丝编程过程。
=> mw.l 1e80020 02000000;md 1e80000
!!! The Fuse Programming is permanent !!!
=> reset
=> md 0x01E80234
01e80234: ffffffff ffffffff ffffffff ffffffff ................
01e80244: ffffffff ffffffff ffffffff ffffffff ................
01e80254: 44ad9053 daf19ac3 39874441 84f92796 .=J$.\6..?...%_.
01e80264: 52aa607f 145d67a3 603404c6 9f0e972b .....t....O\....
注意
作为开发人员,请记住对产品中系统的写保护(WP)保险丝进行编程。
否则,黑客可能能够修改SFP中的SRKH、OTPMK和其他熔断器值。
五、启用安全启动
5.1 闪存NOR存储器
对于原型设计,LS1043A将安全启动映像存储在备用存储区(在本例中为存储区4)。
下面是LS1043ARDB板NOR闪存映射,因此您可以将正常引导存储器映射(当前存储库)与安全启动(替代存储库)进行比较。
此处显示的地址映射到《3.1.2 为安全启动映像创建CSF标头》中的脚本文件。请参阅适用于所有其他开发板的QorlQ SDK安全启动文档(即QorlQ SDK1.9文档、U-boot、安全启动、安全启动的用户启用[PBL平台],以及用于演示)。
Table 4. LS1043A RDB NOR flash 映射
Start address | End address | Image | Max size |
---|---|---|---|
60000000h | 600FFFFFh | RCW + PBI (current bank) | 1 M |
60100000h | 601FFFFFh | U-Boot (current bank) | 1 M |
60300000h | 603FFFFFh | FMan ucode (current bank) | 1 M |
61100000h | 638FFFFFh | Flattened image tree (FIT) (current bank) | 40 MB |
64000000h | 6401FFFFh | RCW + PBI (alt bank) | 128 K |
64060000h | 6407FFFFh | U-Boot (alt bank) | 128 K |
64080000h | 6409FFFFh | ESBC U-Boot header (alt bank) | 128 K |
640A0000h | 640BFFFFh | Boot script header (alt bank) | 128 K |
64A00000h | 67EFFFFFh2 | Kernel FIT image (alt bank) | 54272 K |
67F40000h | 67F5FFFFh | Kernel header (alt bank) | 128 K |
使用CST签名的所有修改后的镜像,以下是将镜像加载到NOR闪存中的步骤:
1.使用TFTP下载并烧写SDK文件:
=> setenv serverip 192.168.1.1; setenv ipaddr 192.168.1.100; ping $serverip
=> tftp a0000000 $tftproot/rcw_1500_sben.bin && erase 64000000 +$filesize && cp.b a0000000 64000000 $filesize
=> tftp a0000000 $tftproot/u-boot.bin && erase 64060000 +$filesize && cp.b a0000000 64060000 $filesize
…
2.使用U-Boot 命令cpld reset altbank 重置为vBank4。这使能了RCW中的 SB_EN开启。
对于LS1043A启动脚本,内核映像必须在发出esbc_validate命令之前复制到DDR地址81000000h。LS1043A的启动脚本是:
# Copy the Kernel Image from Flash to DDR
cp.b 0x60A00000 0x81000000 0x1000000
# Validate the Kernel Image (The header has Image address as 0x81000000)
esbc_validate 0x63F40000
# Boot the validated Kernel FIT Image.
bootm $img_addr
5.2.修改RCW以实现安全启动
有两种方法可以在SoC中启用安全启动过程。
一种选择是打开RCW中的安全启动使能位(SB_EN)以进行测试和验证。
第二种选择是在生产系统的SoC熔丝块中对Intent to Secure(ITS)位进行编程。当为生产系统设置ITS时,安全启动过程中的任何故障都会导致CPU在自旋循环周期中渲染并变得无法运行。这与打开SB_EN不同——在这种情况下系统可以继续以软故障状态引导,因此您可以诊断故障原因。
本文档的范围集中在测试和验证安全启动,因此它仅涵盖设置SB_EN的选项。在QorlQSDK中,有预编译了SB_EN的 RCW文件供您选择。打开了SB_EN的RCW可以在以下目录中找到:
$ cd .../tmp/deploy/images/ls1043ardb/rcw/ls1043ardb/RR_FQPP_1455/rcw_1500_sben.bin
$ ll
-rw-r--r-- 2 user_lab user_lab 136 Feb 3 12:32 rcw_1200.bin
-rw-r--r-- 2 user_lab user_lab 136 Feb 3 12:32 rcw_1400.bin
-rw-r--r-- 2 user_lab user_lab 136 Feb 3 12:32 rcw_1500_1300.bin
-rw-r--r-- 2 user_lab user_lab 136 Feb 3 12:32 rcw_1500.bin
-rw-r--r-- 2 user_lab user_lab 136 Feb 3 12:32 rcw_1500_qetdm.bin
-rw-r--r-- 2 user_lab user_lab 128 Feb 3 12:32 rcw_1500_sben.bin
-rw-r--r-- 2 user_lab user_lab 136 Feb 3 12:32 rcw_uefi_1400.bin
-rw-r--r-- 2 user_lab user_lab 136 Feb 3 12:32 rcw_uefi_1500.bin
从U-Boot 控制台验证SB_EN设置。偏移×19处的RCW为22或62,如下所示:
U-Boot 2015.01QorIQ-SDK-V1.7+g503273b (Nov 06 2015 - 13:29:13)
Clock Configuration:
CPU0(A53):1500 MHz CPU1(A53):1500 MHz CPU2(A53):1500 MHz
CPU3(A53):1500 MHz
Bus: 400 MHz DDR: 1600 MT/s FMAN: 500 MHz
Reset Configuration Word (RCW):
00000000: 0810000f 0c000000 00000000 00000000
00000010: 14550002 80004012 e0625000 61002000
00000020: 00000000 00000000 00000000 00038800
00000030: 00000000 00001101 00000096 00000000
Board: LS1043ARDB, boot from vBank 4CPLD: V1.4
使用SB_EN配置RCW后,系统将执行PBI以进行安全启动过程并使用ISBC和ESBC代码验证映像。收到U-Boot 或Linux提示后。运行以下命令以显示 SecMon_HP状态寄存器,以验证安全启动过程是否完整且没有任何问题
=> md 0x01e90000
01e90000: 00000000 00000000 00000000 00000000 ................
01e90010: 00000000 00ad0080 00000000 00000000 ................ <-Trusted state, OTPMK programmed
01e90020: 00000000 00000000 00000000 00000000 ................
01e90030: 00000000 00000000 00000000 00000000 ................
01e90010: 00000000 00ad0080 00000000 00000000 ……………. <-Trusted state, OTPMK programmed
请参阅 SOC 特定参考手册 SecMon_HP状态(HPSR)以解码当前运行环境的当前安全状态。
为了您的方便,这里是系统安全监控状态(SSM_STATE)定义:
0×00或0000b - 初始化
0×01或0001b - 硬失败
0×03或0011b - 软失败
0x08或1000b - Init Intermediate(Init和Check之间的转换状态-SSM仅在一个时钟周期内保持此状态)
0x09或1001b - 检查
0x0b或1011b - 不安全
0x0d或1101b - 受信任
0x0f或1111b - Secure
如果SSM_STATE不是×0d或×0f,则意味着安全启动过程失败。要解决安全引导问题,请检查HPSVCR和SCRATCHRW2以获取ISBC验证错误代码。错误代码告诉您这是核心异常、系统状态故障、一般标头检查失败还是与密钥/签名/UID相关的错误。
(——未完待续)
缩略语释义:
Name | Definition |
---|---|
ATMU | Address Translation and Mapping Unit —— 地址转换和映射单元 |
Blobs | A cryptographic data structure providing both confidentiality and integrity protection —— 提供机密性和完整性保护的加密数据结果 |
CPC | Corenet Platform Cache —— Corenet 平台缓存 |
CSF | Command Sequences File —— 命令序列文件 |
CST | Code Signing Tool —— 代码签名工具 |
ESBC | External Secure Boot Code —— 外部安全引导代码 |
ISBC | Internal Secure Boot Code —— 内部安全引导代码 |
IVOR | Interrupt Vector Offset Registers —— 中断向量偏移寄存器 |
LAW | Local Access Window —— 本地访问窗口 |
OTPMK | One Time Programmable Master Key —— 一次性可编程主密钥 |
PAMU | Physical Access Management Unit —— 物理访问管理单元 |
PBL | Pre-Boot Loader —— 预引导加载程序 |
RCW | Reset Configuration Word —— 复位配置字 |
RTIC | Run Time Integrity Checker —— 运行时完整性检查器 |
SEC | Security Engine —— 安全引擎 |
SFP | Security Fuse Processor —— 安全保险丝处理器 |
SRKH | Super Root Key Hash —— 超级根密钥哈希 |
ZMK | Zeroizable Master Key —— 可归零主密钥 |
补充翻译:在QORIQTRUST2.1UG_RevA.pdf手册中的《7.1.2.5 OEM Security Policy Register 0 (SFP_OSPR 0)》章节中
翻译内容如下:
此寄存器配置 OEM 在关心平台信任时需要做出的关键安全策略决策。 密钥撤销。 ISBC 支持最多四个密钥的密钥列表,其中三个可以使用此寄存器中的密钥撤销熔断器撤销。
安全意图 (ITS) 表示 OEM 对系统安全的意图。设置 ITS 会强制引导内核开始在 IBR 中执行,执行内部引导 ROM 和 ISBC 中描述的 ISBC 签名验证步骤。复位配置字 (RCW) 中的 SB_EN 位也可以触发芯片执行安全启动,但是没有其他方法可以保证在存在对系统进行物理访问的攻击者的情况下有效。系统是否真正转换到受信任/安全状态取决于成功的签名验证和不存在硬件安全违规。
敏感触发器是任何持有密钥或中间明文数据的触发器,它们不符合离开安全监视器、安全引擎 (SEC)、SFP 或 SDC 的条件。清除敏感触发器 (CSFF) 是与阻止专家级调试模式(统称为扫描)相关的安全策略决策。扫描是可用的最先进的非破坏性调试机制,即使是老练的攻击者也不太可能在不访问详细的恩智浦设计文件的情况下利用扫描。扫描可以到达无法通过内存映射读取和写入访问的触发器。当 CSFF 是 置位,进入扫描模式后,所有敏感触发器都被清除,防止任何提取秘密值的可能性。通过在扫描进入时清除这些触发器,可以防止专家模式调试器提取秘密值。强烈建议 OEM 始终在生产系统上设置 CSFF。
设置写保护 (WP) 位可防止进一步写入 OEM 部分的镜像寄存器,直到下一次 SoC 复位。一旦 WP 熔丝被编程,写入镜像寄存器和对熔丝块的进一步编程将被永久禁用。
恩智浦提供引脚兼容的出口控制(启用加密加速)和非出口控制(禁用加密加速)版本的芯片。恩智浦还在 SFP 的 OEM 部分实施了永久加密加速禁用位。这允许客户购买单个版本的芯片(启用加密加速),并在存在出口管制时将其永久转换为禁用加密加速的芯片 系统中的处理器使系统级出口控制复杂化。请注意,芯片的部件标记将指示出口受控芯片,通常要求 OEM 记录处理器和系统可以合法地被认为不受出口受控加密技术的影响。用户只有在打算永久禁用加密加速时才应设置 NSEC 保险丝。请注意,禁用加密加速的芯片无法执行安全启动。加密加速禁用会关闭以太网控制器中的 SEC、Arm 核心特殊加密指令以及 MACSEC(如果存在)。