SoPC 安全启动模型与设计实现
2021-12-22苏振宇徐峥刘雁鸣
苏振宇,徐峥,刘雁鸣
(浪潮电子信息产业股份有限公司 安全技术部,山东 济南 250101)
0 引言
可编程片上系统(System on a Programmable Chip,SoPC)是一种特殊的嵌入式系统[1],由单个芯片完成整个系统的主要逻辑功能,通过软硬件在系统可编程的功能使得设计方式具备可裁剪、可扩充、可升级等灵活特性。在SoPC 启动过程中存在一定的安全风险,恶意软件有可能会修改引导加载程序等固件,使SoPC 受到Rootkit 攻击[2]。Rootkit 等恶意软件通过修改系统的启动过程,安装到系统内以达到持久驻留系统的目的[3],SoPC 一旦受到Rootkit等恶意代码感染,即使重新安装系统也无法清除。因此有必要对SoPC 进行安全保护,防止在启动过程中固件被恶意篡改。安全启动对于保护设计的知识产权和防止恶意软件在系统上运行至关重要。相关研究工作存在的问题主要有:(1)采用外接可信平台模块(Trusted Platform Module,TPM)[4]实现可信启动[5],该方式增加了硬件成本且系统集成度低;(2)在构建信任链的过程中仅采用杂凑算法进行度量[6],缺少验证的过程,因此安全性较低;(3)嵌入式系统上电时由最先启动的引导加载程序Boot Loader 调用TPM 对后续加载的模块进行度量[7-8],Boot Loader 默认是安全的,但Boot Loader 一旦被攻击篡改,整个信任链就处于非可信的状态。
1 SoPC 安全启动模型
基于现有技术的不足,提出一种SoPC 安全启动模型,目的是确保SoPC 的引导加载程序等固件是可信的,安全启动模型如图1 所示。信任根是创建安全启动最关键的部分,能够确保安全级别配置正确并且安全密钥受到保护。在该模型中信任根是SoPC 中受信任的第一阶段的引导固件Boot ROM,作为引导SoPC 可信的、固有的安全起点。
图1 SoPC 安全启动模型
为了确保可信性,在安全启动过程中通过建立信任链,使每个固件在加载运行前都经过数字签名的验证,只有当前阶段对后续待启动的模块进行验证通过后,才会加载和执行后续的模块。具体为:依次对第二、三、四阶段的Boot Loader、操作系统和应用程序的镜像文件添加数字签名后存储,在SoPC 上电启动建立信任链的过程中,首先由第一阶段的Boot ROM 验证第二阶段Boot Loader的签名,确保Boot Loader 是受信任的;之后由Boot Loader验证操作系统的签名,依次类推,从而确保各模块是受信任的。为了进一步提高启动过程的安全性,可以对固件镜像加密后再进行数字签名操作,并且将相关的密钥存储于SoPC 的安全区域中。
在安全启动之前,对Xi的数字签名SIGi 定义如下:
其中每阶段待启动的模块为Xi,第一阶段的引导程序X0为信任根。E 代表加密运算,D 代表解密运算,H 代表杂凑运算,K为对称密码算法的密钥,PK、SK为非对称密码算法的公钥、私钥。SIGi为数字签名值,H(Xi)表示对Xi进行杂凑运算后生成的摘要值。式(1)表示用私钥SK 对H(Xi)进行数字签名,即对H(Xi)做解密运算;为进一步提高安全性,式(2)在进行数字签名之前,利用密钥K 对H(Xi)进行了对称加密运算。
在启动过程中,由Xi-1对Xi进行校验。验证Xi的数字签名SIGi的定义为:
式(3)与式(1)对应,验证签名时利用公钥PK 对数字签名值SIGi进行加密运算后恢复出Xi的标准摘要值H(Xi),之后计算待加载模块Xi镜像的摘要值H(),并与H(Xi)进行比对,当H()=H(Xi)时说明Xi未篡改(即=Xi),数字签名验证通过;如果Xi的镜像被篡改为,由于Xi′≠Xi,故H()≠H(Xi),校验不通过。式(4)与式(2)对应,先利用公钥PK 对SIGi进行加密运算,再利用K 进行解密运算后恢复出标准摘要值H(Xi)。
以信任根X0为信任起点逐级进行验证,如果每个模块Xi的数字签名都验证通过,则启动过程是安全可信的,最终构建一个安全可信的信任链:X0→X1→X2…→Xi,如果在启动过程中任意Xi的数字签名验证不通过,则信任链的建立终止,系统不会启动。
2 模型设计
2.1 SoPC 硬件架构设计
安全启动模型采用了Intel Arria10 现场可编程门阵列(Field Programmable Gate Array,FPGA)开发平台[9]进行设计和验证,EDA 工具采用的是Quartus II 19.1[10]、嵌入式开发套件为EDS[11]、操作系统为Linux Ubuntu 14.0。SoPC 安全启动硬件架构设计如图2 所示,包括硬件处理器系统(Hard Processor System,HPS)和FPGA 可编程逻辑区域,其中HPS 包括微控制器MPU、安全管理器(Security Manager,SM)、Boot ROM、On-chip RAM 等;FPGA区域包括配置逻辑(Configuration Logic,CL)、安全熔丝Fuse、Flash/SD 卡等。
图2 SoPC 安全启动硬件架构
主要功能模块的作用如下:
(1)SM:用于系统初始化和引导,在SoPC 上电复位后根据熔丝寄存器(Fuse_REG)对系统进行配置。
(2)Boot ROM:管理安全引导过程的第一阶段,并对第二阶段的引导程序Boot Loader 进行验证。
(3)CL:发送配置信息给SM,另外包括256 位椭圆曲线数字签名算法(Elliptic Curve Digital Signature Algorithm,ECDSA-256)[12]、256 位安全散列算法(Secure Hash Algorithm,SHA-256)[13]和高级加密标准(Advanced Encryption Standard,AES)[14],作为对镜像加密和签名的密码算法模块。
(4)Fuse:一次性可编程区域,作为安全存储区存储公钥PK、对称密钥K 以及系统安全配置信息。
(5)Flash/SD 卡:为片外非易失存储器,存储经过加密和签名的Boot Loader、OS 等镜像文件,启动过程中镜像验证通过后才能加载到SoPC 片内RAM 运行。
SoPC 上电复位后,CL 初始化并将Fuse 安全配置信息发送到HPS 中的SM,配置信息保存在SM 中的Fuse_REG寄存器中。SM 根据Fuse_REG 中的配置信息执行安全检查并发送系统初始化信号,控制Fuse 信息自动发送到时钟管理器,内存控制Fuse 信息自动发送到复位管理器,认证、加密、公钥等配置信息存储在相应的存储器映射位置,由Boot ROM 代码读取。
之后HPS 在安全状态下退出复位状态,Boot ROM 开始执行。此时,HPS 处于受信任状态,并且保证Boot ROM代码按预期执行。Boot ROM 读取安全报头,如图3 所示,确定根密钥的存储位置并验证第二阶段Boot Loader 镜像安全报头中的数字签名值。如果校验通过,Boot ROM允许Boot Loader 镜像加载和执行。
图3 Boot Loader 镜像的验证报头和安全报头
2.2 镜像签名
ECDSA-256 算法的私钥用于对镜像进行签名,公钥用于对镜像进行验证。公钥可通过Fuse_REG 寄存器选择配置为3 种类型,如表1 所示。
表1 公钥类型
(1)安全密钥:安全性最高,公钥PK 经过SHA-256杂凑运算后的摘要值H(PK)存储于Fuse 中,使用前先验证公钥完整性,校验通过才允许加载;若公钥被篡改为PK′,则H(PK′)≠H(PK),禁止公钥加载。
(2)FPGA 密钥:安全性较高,公钥直接存储于FPGA区域的RAM 中,未经过杂凑运算。
(3)测试密钥:安全性最差,公钥直接存储于镜像文件的报头中,仅在测试阶段使用。
3 模型验证
3.1 安全镜像文件创建
镜像文件有两种创建方式,对应两种安全级别,可通过Fuse_REG 寄存器进行选择配置。
(1)签名验证方式
该方式首先需要利用OpenSSL[15]生成签名密钥对,OpenSSL 是一个支持安全套接字协议SSL 的开源工具包,集成于EDS 嵌入式命令shell 中。生成密钥对的具体方式是在Linux 中启动Boot Loader 生成器后调用OpenSSL,运行如下命令使OpenSSL 生成密钥对:# openssl ecparam-genkey -name prime256v1 -out root_key.pem。
创建的签名密钥对存储于root_key.pem 文件中,使用安全引导镜像工具alt-secure-boot 对镜像进行签名的命令为:# alt-secure-boot sign-i Image.bin-o Image_sign.bin-t user。
其中user 代表的公钥类型是测试密钥,在测试阶段的安全启动过程中,直接读取镜像文件中的公钥,不对公钥进行SHA-256 杂凑校验比对。Image.bin和Image_sign.bin 分别为签名之前和添加数字签名之后镜像文件,将Image_sign.bin 文件存储于片外SD 卡中。
(2)加密+签名验证方式
为了在引导期间提供最高级别的安全性,可以对镜像文件加密后再添加数字签名,以便在校验阶段提供双重保护。在Boot Loader 生成器中通过文件encrypt.key生成加密密钥key,用于对镜像加密。具体为EDS 工具调用Boot Loader 生成器读取encrypt.key 文件中的二进制位流生成加密密钥key。对镜像进行加密的命令为:# alt-secure-boot encrypt-i Image.bin-o Image_enc.bin-k key。
其中key为AES 对称算法的密钥,Image.bin和Image_enc.bin 分别为加密之前和加密之后镜像文件。
3.2 安全启动功能测试验证
验证过程如图4 所示,具体说明如下。启动过程的每个阶段利用公钥PK和杂凑算法校验下一阶段镜像的数字签名,首先恢复出镜像文件的标准摘要值H(Xi),如果镜像被加密了,根据式(3)需要利用PK和对称密钥K 恢复出标准摘要值H(Xi)。在镜像加载之前计算其摘要值H(Xi′),并与H(Xi)进行比对,如果H(Xi)=H(Xi′),说明镜像未篡改,即Xi=,允许镜像加载执行;如果H(Xi)≠H(),说明镜像Xi已被篡改为,信任链为非可信状态,启动过程失败。例如在引导过程中,Boot ROM 首先验证Boot Loader 镜像的数字签名,验证通过后才能加载运行,之后由Boot Loader 对后续阶段的Linux 系统镜像进行验证和加载。如果验证数字签名失败,启动过程终止。
图4 安全启动验证流程图
表2为Boot Loader和Linux 的镜像文件经过杂凑运算后的摘要值。为了验证安全启动的功能,对原始值的前2 个字节分别篡改为了“0x12,0x34”。
表2 镜像文件摘要值篡改
表3为两种安全启动方式的测试结果,如果镜像未篡改,SoPC 正常启动;如果对Boot Loader 或Linux 系统镜像文件进行了篡改,信任链建立终止,启动失败。
表3 安全启动测试结果
图5 所示为启动方式的启动时间对比,正常启动时因未对镜像进行签名和验证,所以启动时间最短,但安全性最差;若采用签名验证方式启动,从SoPC 上电到应用程序加载的时间总共为15 s;采用签名+加密验证方式的整个启动时间最长,为25 s,但安全性最高。
图5 安全启动模式的启动时间对比
4 结论
SoPC 在启动过程中通过校验启动阶段各固件镜像的数字签名方式提升了安全性,保证了启动过程中引导加载程序、操作系统及应用程序的安全可信,从而构建起完整的信任链。此外,测试阶段为了避免把密钥永久写入一次性可编程区域而造成Fuse 资源浪费,灵活采用了把密钥写入文件和FPGA RAM 区域的方式进行功能的验证。后续工作可以将该安全启动模型应用于实际SoPC 的设计开发过程,实现对SoPC 启动过程的安全保护,并且将密钥固化在安全区域以防止被非法篡改,提高安全性。