1、前言
本文介绍uboot启动linux内核时,开启对kernel的签名认证功能,防止kernel和device tree被任意修改。
2、fitimage简介
fitimage本质上是dtb类型的结构,可用于打包不同的数据到一个文件中。
我们知道uboot启动kernel时可以使用bootm命令,bootm启动fitimage可以使用如下命令:
bootm <fitimage address>
这样做也是为了方便SecureBoot的实现,方便对kernel,system.dtb,rootfs进行RSA签名和认证。
如何制作fitImage以及fitImage的结构的详细的介绍可以参考如下文档:
《u-boot FIT image介绍》提供了详细的结构解析,以及如何制作的命令。
fitimage格式支持存储镜像的hash值,并且在加载镜像时会校验hash值。这可以保护镜像免受破坏,但是,它并不能保护镜像不被替换。
而如果对hash值使用私钥签名,在加载镜像时使用公钥验签则可以保护镜像不被替换。
3、secure boot 基本概念和框架
-
3.1、secure boot签名的大致流程:
- 计算镜像的hash值
- 利用私钥对hash值签名
- 签名结果存在FIT Image 中。
-
3.2、secure boot验签的大致流程:
- 读取FIT Image
- 获得pubkey
- 从FIT Image 提取签名
- 计算镜像的hash
- 使用公钥验签获得hash值,与计算得到的hash值进行对比
签名是由mkimage工具完成的,验签由uboot完成。
-
3.3、签名算法
原则上讲,任何合适的算法都可以用来签名和验签。在uboot中,目前只支持一类算法:SHA&RSA。
RSA 算法使用提前准备好的公钥就可以完成验签,验签相关的代码量也很少。在验签时,RSA只是在FDT中提取必要的数据进行校验。
当然也可以在uboot中添加合适的算法,如果有其他签名算法(如DSA),可以直接替换rsa.c,并在image-sig.c中添加对应算法即可。
4、制作fitimage
- 4.1、创建
images.ids
文件,如下:
/dts-v1/;
/{
description = "kernel image with one or more FDT blobs";
#address-cells = <1>;
images {
kernel_1 {
description = "Linux kernel";
data = /incbin/("./zImage");
type = "kernel";
arch = "arm64";
os = "linux";
compression = "lzma";
load = <0x90100000>;
entry = <0x90100000>;
hash-1 {
algo = "crc32";
};
hash-2 {
algo = "sha1";
};
signature {
algo = "sha1,rsa2048";
key-name-hint = "dev";
};
};
fdt_1{
description = "e2000d demo board";
data = /incbin/("./e2000-openwrt.dtb");
type = "flat_dt";
arch = "arm64";
compression = "none";
load = <0x90000000>;
hash-1 {
algo = "crc32";
};
hash-2 {
algo = "sha1";
};
signature {
algo = "sha1,rsa2048";
key-name-hint = "dev";
}</