freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

浅谈可信启动
2020-05-18 14:20:57

最近看了一些关于可信启动的文章,所以我想把可信启动的知识做一下梳理。

本文主要从抽象层面介绍可信启动原理,分别从启动过程,可信启动原理,模拟可信启动三个方面展开介绍。

计算机启动过程简介

我将按两类平台的启动过程分开描述,分别是x86/x86_64平台设备的启动和嵌入式平台设备的启动

x86/x86_64 平台设备的启动

x86 平台启动过程如下图所示

2020-05-17-01.png

简略流程: cpu --> BIOS --> GRUB --> Kernel --> OS

嵌入式设备的启动

嵌入式平台启动过程如下图所示

2020-05-17-02.png

简略流程: cpu --> u-boot --> Kernel --> OS

可信启动思路

可信启动的两个关键概念分别是可信根和可信链,可信根。

大家对 PKI 体系应该都有了解,可信启动的两个概念可类比与证书体系,当我们访问一个 https 站点时,站点会把证书传送给客户端。客户端要去校验证书的合法性和有效性,就需要验证两点,第一点,该站点的根证书(CA)在客户端所在机器是否是可信的,第二点,从 CA 到站点证书的证书链是否是完整的。

要实现可信启动,首先需要 cpu 的支持,其次还需要 TPM(Trusted Platform Module)芯片的支持,TPM 有两个作用,作用一:提供加解密算法的支持,作用 二:存储对称密钥及私钥。可能部分嵌入式产品还需要 OTP(One Time Programmable)芯片。下面以嵌入式环境为例,说明可信启动的实现方式。

环境

支持可信启动的主芯片,OTP 芯片,Flash 芯片

假设 flash 芯片的分区结构如下
| u-boot | kernel | romfs | config |

u-boot 分区结构如下
| 4 字节:公钥长度 | 1024 字节:RSA 公钥 | 4 字节:u-boot 的 hash 签名长度 | 1024 字节:u-boot 的 hash 签名 | 4 字节:u-boot 版本号 | 4 字节:u-boot 长度 | u-boot 内容 |

OTP 存储结构如下
| RSA 公钥的 sha256 值 | u-boot 版本号 |

可信启动流程

启动设备,cpu 判断是否使能可信启动,如果是,则按照可信启动流程执行

step1 读取Flash中u-boot分区里的RSA公钥,并计算hash值
step2 读取OTP中的RSA公钥hash值
step3 比较step1和step2的hash值,如果不一致则退出启动流程
step4 读取Flash中u-boot从版本号开始的内容,对 u-boot 内容做 hash 运算,记hash值为A
step5 读取 Flash中u-boot 的 hash 签名,使用step1的公钥验签,记验签结果为 B
step6 判断结果 A 和 结果 B 是否一致,如果不一致则退出启动流程
step7 读取 Flash中u-boot 的版本,记版本C
step8 读取 OTP 中的 u-boot 版本,记版本D
step9 判断版本D 是否大于 版本C,如果是则退出启动流程

stepx u-boot 验证 kernel 的完整性

stepy kernel 验证 romfs 的完整性

可信启动最关键的是从 cpu 到 bootloader 的过程,从 bootloader 开始到 kernel,到 romfs 等阶段都和前面的校验过程类似,就不再赘述了。

可信启动模拟实现

我用 python 写了一个可信启动从 cpu 到 u-boot 的模拟器,把我所理解的可信启动的过程呈现出来

模拟器文件结构如下

Kafrocs:Trusted Boot Emulate kafroc$ ls -R
CPU        Flash        OTP        power.py    vendor

./CPU:
cpu.config    cpu.py

./Flash:
config    kernel    romfs    uboot

./Flash/config:
config

./Flash/kernel:
kernel

./Flash/romfs:
romfs

./Flash/uboot:
RSA_Pub            uboot.py    uboot_Version    uboot_signature

./OTP:
RSA_Pub_Hash    u-boot_Version

./vendor:
RSA_Pri        RSA_Pub        rsa-sig.py    uboot-partition

./vendor/uboot-partition:
RSA_Pub        uboot.py    uboot_Version    uboot_signature

其中 CPU Flash OTP power.py 模拟嵌入式设备,vendor 模拟设备制造厂商

下面是关于模拟器的使用介绍
假设用户A是厂商人员,负责uboot开发以及固件打包
假设用户B是设备用户,负责升级固件包

1 用户A进入 vendor/uboot-partition 目录,对uboot(即uboot.py)进行开发,并更新uboot_Version

2 用户A进入vendor目录,执行 python3 rsa-sig.py 生成新固件(固件即为uboot-partition所有文件)

3 用户B升级新版本固件(把 vendor/uboot_signature 下的文件复制到 Flash/uboot/下面)

4 用户B配置 CPU/cpu.config 使能可信启动

5 用户B通过 python3 power.py On 来启动设备

在启动设备时,cpu 会按照可信启动流程执行,如果校验失败,则停止启动
如果成功,则加载 uboot 执行

python3 power.py On演示结果如下

Kafrocs:Trusted Boot Emulation kafroc$ python3 power.py On
system starting ...
Read RSA Public Key from Flash and Calculate the hash value
Read the hash of RSA Public Key in OTP
Verify RSA Public Key OK.
Calculate the sha256 of uboot
verify u-boot signature
uboot verify OK.
Check u-boot version ...
u-boot running ...

模拟器代码:https://github.com/kafroc/Trusted-Boot-Emulation

总结

可信启动的关键,一要有cpu的支持,二要保证设备上有一处地方是只读不可写的(无论是cpu内部的存储器,还是安全芯片,或者是OTP芯片)把公钥的hash放到只读空间,保证公钥的完整性,公钥和私钥唯一匹配,只要保证私钥不泄露,这样的设计理论上是能保证安全的。

可信启动是设备安全的根基,理论上其他的安全功能都应该在可信启动的基础上建立。后续我想写一篇文章把可信执行也介绍一下。

如果你喜欢我的文章,请帮忙点个赞。

由于笔者水平有限,文章难免会有错误的,欢迎读者批评指正。笔者个人邮箱:kafrocyang@gmail.com

# 可信启动 # security boot # 安全启动 # Trusted boot
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者