相关背景
linux系统本身支持对kernel文件的签名验签功能,即通过its文件配置相关签名信息,在u-boot中开启相关配置,即可实现启动过程中uboot对kernel的验签功能。不过需要注意的是,这种原生的实现仅支持bootm的启动方式,如果你的uboot使用booti启动kernel,则需要自行实现对kernel的签名验签。
本文简单介绍带签名信息的kernel二进制文件的生成方式,以及u-boot验签功能开启的重要步骤。
工作目录的结构
~/dev/verify-boot$ tree -L 2
.
|-- linux
| |-- Image
| |-- fsl-s32g-verified-boot.dtb
| |-- sign-images.its
`-- uboot
|-- dts
|-- sign-image
|-- tools
第一步:使用openssl生成密钥和证书
openssl genpkey -algorithm RSA -out dev.key -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537
openssl req -batch -new -x509 -key dev.key -out dev.crt
第二步:在linux目录创建its文件
创建sign-images.its,指定待签名kernel文件和签名算法等信息:
/dts-v1/;
/ {
description = "kernel image with one or more FDT blobs";
#address-cells = <1>;
images {
kernel {
data = /incbin/("Image");
type = "kernel";
arch = "arm64";
os = "linux";
compression = "none";
load = <0x80080000>;
entry = <0x80080000>;
kernel-version = <1>;
signature {
algo = "sha1,rsa2048";
key-name-hint = "dev";
};
};
fdt-1 {
description = "DTB for kernel";
data = /incbin/("verified-boot.dtb");
type = "flat_dt";
arch = "arm64";
compression = "none";
fdt-version = <1>;
signature {
algo = "sha1,rsa2048";
key-name-hint = "dev";
};
};
};
configurations {
default = "conf-1";
conf-1 {
kernel = "kernel";
fdt = "fdt-1";
};
};
};
第三步:创建uboot dts
创建arch/arm/dts/xxx-verified-boot.dts文件,指定系统启动时u-boot验签用到的算法、验签设备名称等:
/dts-v1/;
/ {
model = "S32xx public key";
compatible = "xxx,yyy";
signature {
key-dev {
required = "conf";
algo = "sha1,rsa2048";
key-name-hint = "dev";
};
};
};
第四步:uboot配置
首先根据dts文件生成dtb文件:
dtc verified-boot.dts -O dtb -o verified-boot.dtb
接着修改u-boot配置,启动对验签功能的支持:
make s32g2xxaevb_qspi_defconfig
make menuconfig
CONFIG_OF_CONTROL=y //default on
CONFIG_DM=y //default on
CONFIG_FIT=y //default on
// CONFIG_FIT_SIGNATURE=y
Enable signature verification of FIT uImages
CONFIG_OF_SEPARATE=y
//CONFIG_DEFAULT_DEVICE_TREE=<dts-filename>
CONFIG_DEFAULT_DEVICE_TREE="xxx-yyy"//verified-boot
第五步:生成fit
首先执行make tools生成相关工具,工具二进制文件在tools目录下。
然后执行mkimage命令生成fit文件:
tools/mkimage -f ../linux/sign-images.its -K ../linux/fsl-s32g-verified-boot.dtb -k ~/dev/keys -r sign-image
运行结果
FIT description: XCU kernel image with one or more FDT blobs
Created: Wed Aug 4 17:09:18 2021
Image 0 (kernel)
Description: unavailable
Created: Wed Aug 4 17:09:18 2021
Type: Kernel Image
Compression: uncompressed
Data Size: 7817224 Bytes = 7634.01 KiB = 7.46 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x80080000
Entry Point: 0x80080000
Sign algo: sha1,rsa2048:dev
Sign value: 482cc03fb72adad2364d1b0239b6eb7218efeb85d6e4fe4e7340be2b63a80d0a7aad5eb9ba7aed5622e0d82ed8eb3db0ef170c175270dc17f1cb11996ccd61af2f857a5e1f392895b4f41e50d5bc436f59bd44b37e5069c7989c45f8bc05c00840143a538244deb7312361a13f54188168be8e30f36ee59c099af772f760a56abe60bd9ea79aabda5302375172438ec5a3407b49c9c27aeeca2da9a3c215e0716045b592f26b487b593869491fc5f2767d8035a7126f270c1e0a2280099038120848ff2272d978af3c2d7d243f057c412fa0545a5f53b52f2b088cbdda6846a620982d6e501da1dc7d6efe4a4899ed680e5b4fbc329d4513967f7a0301a14389
Timestamp: Wed Aug 4 17:09:18 2021
Image 1 (fdt-1)
Description: DTB for kernel
Created: Wed Aug 4 17:09:18 2021
Type: Flat Device Tree
Compression: uncompressed
Data Size: 2309 Bytes = 2.25 KiB = 0.00 MiB
Architecture: AArch64
Sign algo: sha1,rsa2048:dev
Sign value: 47376420c1dd34512612d0fa18a59052c91a0562a2a68fb87a569cc2c6dea50650b05fa4c0706b55a804a0dd18031a7c19449807ee9852ad7ac62c8ad0cc48ccf39a22ea641a27f2cd268ea37f9667770ad92fbc1f519a9e3a42eea29c7fe37e0edb58894c29e56a6dae876f6c0c8927c0a04be2446f11709bc90d58b6860e360e13816772f8959e50855079c719c42add08f29884c4d478984fcd2696d244e1b5d251556906b87254ddeadbbe51c52f08ba7855be3aa2df0e816cfbef19281916822ffd615a826af509f5a6056896909bd846ad41287edd6dcaea31b020d0d62a38790f3334051011a441455053efc794c7b3c1972c104461e761f9dd724e87
Timestamp: Wed Aug 4 17:09:18 2021
Default Configuration: 'conf-1'
Configuration 0 (conf-1)
Description: unavailable
Kernel: kernel
FDT: fdt-1
第六步:验证fit
执行fit_check_sign命令在本地验证fit签名:
./tools/fit_check_sign -f sign-image.fit -k ../linux/fsl-s32g-verified-boot.dtb
结果:
Verifying Hash Integrity for node 'conf-1'... Verified OK, loading images
## Loading kernel from FIT Image at 7f6dd9dcf000 ...
Using 'conf-1' configuration
Verifying Hash Integrity ...
OK
Trying 'kernel' kernel subimage
Description: unavailable
Created: Thu Aug 5 10:09:08 2021
Type: Kernel Image
Compression: uncompressed
Data Size: 7817224 Bytes = 7634.01 KiB = 7.46 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x80080000
Entry Point: 0x80080000
Sign algo: sha1,rsa2048:dev
Sign value: 482cc03fb72adad2364d1b0239b6eb7218efeb85d6e4fe4e7340be2b63a80d0a7aad5eb9ba7aed5622e0d82ed8eb3db0ef170c175270dc17f1cb11996ccd61af2f857a5e1f392895b4f41e50d5bc436f59bd44b37e5069c7989c45f8bc05c00840143a538244deb7312361a13f54188168be8e30f36ee59c099af772f760a56abe60bd9ea79aabda5302375172438ec5a3407b49c9c27aeeca2da9a3c215e0716045b592f26b487b593869491fc5f2767d8035a7126f270c1e0a2280099038120848ff2272d978af3c2d7d243f057c412fa0545a5f53b52f2b088cbdda6846a620982d6e501da1dc7d6efe4a4899ed680e5b4fbc329d4513967f7a0301a14389
Timestamp: Thu Aug 5 10:09:08 2021
Verifying Hash Integrity ...
sha1,rsa2048:dev+
OK
Loading Kernel Image
## Loading fdt from FIT Image at 7f6dd9dcf000 ...
Using 'conf-1' configuration
Verifying Hash Integrity ...
OK
Trying 'fdt-1' fdt subimage
Description: DTB for kernel
Created: Thu Aug 5 10:09:08 2021
Type: Flat Device Tree
Compression: uncompressed
Data Size: 5381 Bytes = 5.25 KiB = 0.01 MiB
Architecture: AArch64
Sign algo: sha1,rsa2048:dev
Sign value: 99d1ef7dccfca061c22095c68849cdc0889cdc2fef2d4884b7dabc1aa886213717428349db8cc98550a5e7798aaeaf4a53d102a39002f55fb8fde65405ff9f911c63d8ed79a4c42b2ae07bff9e08bada281933f42472f80a017fc146a39de477d460e11e829723efb7bed41b628e164ae923599de82de313a3e5586b0d09ba999c5507445c22502316adbe5c77db20b629a755aad8cb8a028da1bd4b7969058907da80eb450dd92f0bd8f0c5c616b1c882c3b2051cbfd6939ed1afdf95974b51a11958a3f8531c38fd236a4eb03a336638781d36e1a9559f80e7d591d1a63fe31a645b9550e544b893bb54d363e9f0d675b698eb3865ff52174d80d6cfcaeb07
Timestamp: Thu Aug 5 10:09:08 2021
Verifying Hash Integrity ...
sha1,rsa2048:dev+
OK
Loading Flat Device Tree
## Loading ramdisk from FIT Image at 7f6dd9dcf000 ...
Using 'conf-1' configuration
Verifying Hash Integrity ...
OK
Could not find subimage node type 'ramdisk'
Signature check OK
第七步:编译uboot
make EXT_DTB=../linux/verified-boot.dtb
第八步:生成image
cat u-boot.bin u-boot.dtb > u-boot.img
最后刷入u-boot镜像和fit镜像,验证系统是否正常启动以及u-boot对kernel的验签是否生效,可以通过修改签名信息或直接使用未签名的kernel替换已签名的kernel来检验验签功能。