Android 安全启动介绍
1. 背景¶
由于目前SigmaStar(后文统称为SStar)的pure Linux平台版本已经设计了一套Secureboot的流程,其中涉及到IPL、IPL_CUST、U-boot、Kernel、rootfs的镜像完整性校验以及镜像明文加密,而Android已经有了Android Verify Boot 2.0(后文统称为AVB)方案,涉及校验Android平台的镜像,但不包括bootloader的完整性校验,所以在SigmaStar Android平台将这两个流程整合到了一起以构建完整的Secure Boot流程。下文将会对整个方案做大致介绍。
2. 密码学常用概念以及名词解释¶
-
哈希(Hash)
通常指哈希运算,Hash算法能保证不同长度、内容的输入经过计算后可以得到长度相同但内容唯一的哈希值。
-
私钥(private key)/ 公钥(public key)
非对称加密的概念,在非对称加密中会先生成一把私钥,再由私钥派生出公钥,最常见的场景就是内容发布者持有私钥,多个内容接收者持有公钥,发布者利用私钥对内容做签章,接收者使用公钥解签验证内容完整且来源合法。
-
摘要(Digest)
因为非对称加密如果数据越大,整个加密/解密的过程就越长,于是利用哈希算法的特性,将需要加密的内容先计算成一个长度固定(128、256)的哈希值,这个哈希值因为对于加密内容唯一且简短,故形象地称为摘要。
-
签名(Signature)
签名在生活中用于标识内容作者的唯一性,在非对称加密中私钥的一般只有发布者持有,所以通过私钥加密过的内容摘要一般称为签名。
通过下图(典型的非对称加密流程)可以辅助理解:
3. 整体secure boot flow¶
注:上图不包含aosp common kernel启动后运行时init对system、vendor等镜像挂载、读写时的hash tree校验。统一用desc表标识保存在vbmeta.img以及保存链式分区中的AVB Vbmeta Descriptor。
总体的大致流程:
1a:上电ROM code开始运行。
2a:从storage中读取IPL.bin镜像中的签章,从OTP取出OTP public key,对IPL.bin进行验签。
2b:加载并运行IPL。
3a:从storage中读取IPL_CUST.bin镜像中的签章,读取嵌入在IPL.bin中的cust public key,对IPL_CUST.bin进行验签。
3b:加载并运行IPL_CUST。
4a:从storage中读取u-boot.bin镜像中的签章,读取嵌入在IPL_CUST.bin中的cust public key,对u-boot.bin进行验签。
4b:加载并运行U-boot。
5a:从storage中读取vbmeta.img中的签章,读取嵌入在u-boot.bin中的oem public key对vbmeta.img进行验签。
5b:读取vbmeta.img中所有vbmeta描述符,校验描述符的合法性。
5b:对boot image做哈希,与vbmeta中boot描述符保存的摘要做比较,保证boot.img的完整性。
5c:加载并运行Kernel。
4. 信任链的建立¶
4.1. 概览¶
- 信任链的建立在于信任根的建立,首先ROM code是无法被篡改的,OTP中的公钥在设备熔断之后就无法再修改。基于以上两个前提完成对IPL的验签,保证了IPL的来源可信且完整。这是整个secure boot流程的基础。
- 可信来源的IPL中被预置了合法的公钥,用于校验IPL_CUST,这就保证了IPL_CUST的来源可信且完整,同样的逻辑可以依次保证u-boot.bin可信且完整。
- AVB的流程中首先会校验vbmeta.img的完整性(AVB校验vbmeta的步骤有点繁琐,章节4.2.2中介绍)。
- 由于vbmeta.img的来源可信且完整,vbmeta.img包含的后续镜像的AVB Descriptors也都是完整可信的,AVB会利用AVB Descriptors中的摘要对boot.img、vendor_boot.img、vendor.img、等镜像做完整性校验。
综上,该方案的信任链是完整的。
4.2. vbmeta信任链建立¶
4.2.1. 典型的AOSP device分区布局与概念解释¶
分区布局:
有vbmeta、boot、system、vendor、xyz等分区(上图红色部分分区不受avb保护,忽略)。
分区功能:
-
紫色部分是vbmeta分区,里面包含了AVB功能的核心信息:
签名vbmeta的私钥对应的公钥key0
boot镜像的hash值,system、vendor镜像hash tree的根hash
签名链式分区xyz私钥对应的公钥key1,用于校验链式分区
-
蓝色部分分别是boot、system、vendor,这部分镜像是AVB保护完整性的镜像
-
黄色部分是链式分区可能是厂商自己创建的分区:
链式分区除了镜像之外还包含了独立的被私钥key1签名的vbmeta数据结构,并且保存了xyz镜像的hash值或者hash tree的根hash
4.2.2. 基于vbmeta的信任链建立¶
-
首先通过4.1章已知u-boot是可信的,那u-boot镜像内嵌的key0是可信的。
-
参考第3章中的步骤5a:
从vbmeta中取出签名vbmeta的私钥对应的公钥对应的key0,取出vbmeta中的签章校验vbmeta的完整性(流程参考第2章中的图例)。同样的用vbmeta中key1去校验链式分区中的vbmeta的完整性。
-
参考第3章中的步骤5b:
此时因为已知vbmeta都是完整可信的,那么利用vbmeta中保存的其他镜像的hash、root hash就可以去校验其他镜像的完整性。
5. Secure Boot配置¶
5.1. 密钥制作¶
5.1.1. 生成私钥¶
生成RSA2048或者RSA4096的私钥,例如生成一把名为releasekey_rsa4096.pem的pem格式的私钥:
openssl genrsa -out releasekey_rsa4096.pem 4096
5.1.2. 基于私钥生成pem格式的公钥¶
openssl rsa -in releasekey_rsa4096.pem -pubout -out releasekey_rsa4096_pub.pem -outfrom PEM
5.1.3. 基于私钥生成AVB使用的二进制公钥¶
avbtool extract_public_key --key releasekey_rsa4096.pem --output releasekey_rsa4096_pub.bin
5.2. 公钥写入¶
5.2.1. OTP 中的公钥¶
执行:
key_proc.py --exportkey --rsa= releasekey_rsa4096_pub.pem
key_proc.py是由SigmaStar自主开发用于SecureBoot的工具,当前操作不需要指定输出,会在执行命令的当前目录生成:
-
rsaKey.bin:二进制公钥文件
-
rsaKey.txt:烧录公钥的uboot命令行脚本,由otpctrl命令组成。
5.2.2. IPL.bin/IPL_CUST.bin中的公钥¶
key_proc.py --insert --rsa=pubilc.pem -f IPL[_CUST].bin
该命令会生成IPL[_CUST].cipher.bin,紧接着执行下列命令为IPL header加入信息,标记启动SecureBoot的正式模式或者调试模式。
add_ipl_header.py ./IPL[_CUST].cipher.bin ./IPL[_CUST].cipher1.bin 0 <0|1> //0:调试模式 1:正式模式
5.2.3. U-boot中的AVB公钥¶
将5.1.3中生成的releasekey_rsa4096_pub.bin放到U-boot代码中,将CONFIG_AVB_PUBKEY_FILE设置位公钥文件的路径,编译U-boot即可。
5.2.4. vbmeta中的公钥¶
AOSP镜像不需要单独预置公钥,只需要设定加密算法和私钥路径即可,在章节5.3.3会提到。
5.3. 镜像签名¶
5.3.1. IPL.bin/IPL_CUST.bin签名¶
对5.2.2章中的生成的IPL[_CUST].cipher1.bin进行签名
key_proc.py –sign –rsa=<OTP/CUST private key path> -f IPL[_CUST].cipher1.bin
该命令生成IPL[_CUST].cipher1.sign.bin
5.3.2. U-boot签名¶
key_proc.py –sign –rsa=<CUST private key path> -f u-boot.bin
该命令生成u-boot.sign.bin
5.3.3. AOSP镜像签名¶
首先将5.1.1、5.1.2、5.1.3章中生成的公私钥放到自己指定的目录,例如:
<AOSP path>/device/sigmastar/common/avb_keys/releasekey_rsa4096.pem <AOSP path>/device/sigmastar/common/avb_keys/releasekey_rsa4096_pub.pem <AOSP path>/device/sigmastar/common/avb_keys/releasekey_rsa4096_pub.bin
则可在device.mk添加设定:
BOARD_AVB_KEY_PATH := SHA256_RSA4096 BOARD_AVB_ALGORTHM := device/sigmastar/common/avb_keys/releasekey_rsa4096.pem
同时设定其他链式分区的配置,形如:
BOARD_AVB_<image name>_KEY_PATH := <algorthm> BOARD_AVB_<image name>_ALGORTHM := <abs key path>
例如boot.img
BOARD_AVB_BOOT_KEY_PATH := SHA256_RSA4096 BOARD_AVB_ BOOT_ALGORTHM := device/sigmastar/infinity7/avb/releasekey_rsa4096.pem
也可以同时生成多把key,用于签名不同的链式分区。