前言android 系统安全内容总结
1、签名验签
启动验证链核心技术就是签名验签,这里复习下,流程如上图:
android基础算法使用的是RSA
红色部分是编译时对需要验签的镜像与文件进行签名操作;需要用到私钥,这个私钥一般放在编译代码或者签名服务器。
黄色部分是开机启动时对启动镜像与文件的验签;需要用到公钥,这个公钥集成到镜像中,一般对开发与使用者都是可见的。
2、安全启动验证链
极简的开机启动流程如下
红色部分是secure boot部分,黄色部分是AVB部分(AVB包括verify-boot与dm-verity)。
https://blog.csdn.net/dongyi1988/article/details/103995737
以MTK为例:
Secure Boot验证阶段,Boot Rom程序段上电直接运行,这段程序不能修改或者跳过,它将获取芯片内部非易失只读性存储中的公钥or公钥HASH;用于验证引导加载程序(preloader)镜像末尾的root公钥,验证成功后启动preloader;然后preloader代码段的公钥头文件(oemkey.h)验证ATF、TEE、lk;在启动到lk后,利用TEE提供的加密库使用公钥头文件(oemkey.h)验证md1、scp、logo等。
AVB(android verify boot)校验阶段,启动到lk会用公钥头文件(avbkey.h)验证vbmeta分区,再用验证通过的vbmeta分区里面存的公钥对一般较小的分区(例如boot、dtbo)进行hash校验;验证完毕后进入kernel,kernel使用dm-verity对动态分区(一般较大的分区,例如system,vendor)进行hash tree的校验,所有分区校验成功后正常挂载,设备继续进入android启动流程。
2.1、secure boot
发现有价值文章:浅析安全启动(Secure Boot)
现在网上内容很多,不再赘述,解答标红的三个问题
QCOM启动流程图参考
https://www.cnblogs.com/schips/p/how_qualcomm_soc_boot.html
MTK启动流程图参考
https://blog.csdn.net/forever_2015/article/details/53000643
https://blog.csdn.net/forever_2015/article/details/53047993
MTK的secure boot配置参考:
https://blog.csdn.net/qq_43805880/article/details/108062898
QCOM的secure boot 配置参考:
https://blog.csdn.net/tq501501/article/details/94719382
1、只是刷入efuse.img镜像设备就熔丝了?
fastboot flash efuse只是刷写emmc/ufs上的分区数据,熔丝并不是fastboot做的事。如果还在调试,efuse熔丝公钥与preloader签名不匹配那不就完蛋了吗?
我们看不到Boot Rom代码,在secure boot安全验证上,以及芯片手册上能猜测其流程。其实从QCOM网站看到,文档名记不住了,大概意思如下流程图。
熔丝真正操作在TEE,efuse公钥hash判断有效后,重启才真正生效,从此每次开机进行secure boot校验。
硬件关闭公钥存储写入能力,也就是熔断操作,会耗电;如同读写标志位强制拉低,从此此段存储再也无法篡改。
熔丝寄存器位也置为有效,再也无法关闭。
这就创建了一个值得信任的根。
2、为什么secure boot有多级验证?
MTK对其使用的镜像md1、scp、logo等等进行二次签名,那么开机需要进行二次验证增加启动耗时,安全性只是倍增,而不是指数级增加,有必要吗?
先了解多级认证的作用https://www.wenmi.com/article/q04bcq008upf.html
我理解这是供应商自己玩的隔离,即md1、scp、logo部分使用MTK自己签名授权的一级签名,二级签名交给ODM。这样MTK就控制了md1、scp等部分的芯片功能。(貌似还是跟QCOM学的。)
3、如何联网签名?
软件架构方案已经有了,但开发人员随意签名漏洞版本、可恶意窃取数据版本怎么办?如何降低开发人员的攻击呢?
ODM只需要管理好发布版本,管理好私钥即可,这就是非对称密钥的好处。将私钥存储到服务器,开发人员编译镜像需要授予签名权限,控制版本输出。MTK与QCOM的secboot签名都做好了接口,修改非常方便,有钱也可直接请人搭建👌。
MTK的secure boot最终签名接口调用hsm.py,路径应该在vendor/mediatek/proprietary/scripts/secure_chip_tools,如注释部分描述,替换lib.cert.sig_gen的实现即可。
hsm_rsa_sign(data, key, padding, sig)函数中,data是镜像hash、key私钥名、padding加密方式,sig返回签名后内容。
def hsm_rsa_sign(data, key, padding, sig):
"""
sign data with HSM
"""
# note that key is pubk actually, use it as index for
# HSM parameters such as key selection
hsm_param_obj = HsmParam()
key_table = create_key_table()
hsm_param_obj.m_prvk = query_key_table(key_table, key)
if hsm_param_obj.m_prvk is None:
print 'not valid HSM parameter'
return -1
print "========================"
print "HSM parameter:"
print " m_prvk = " + hsm_param_obj.m_prvk
print "========================"
# place hsm request here -- start
# we re-direct it to signing with private key to mimic HSM
# data is not hashed here, you can hash data here to reduce
# network usage
lib.cert.sig_gen(data, hsm_param_obj.m_prvk, padding, sig)
# place hsm request here -- end
return 0
联网签名步骤参考:
连接服务器
透传前面三个参数
服务器解析
验证账号与密钥对应权限
使用指定的密钥签名,
返回签名数据
联网签名使用的是镜像hash,联网签名时间不受被签名镜像的大小影响。
2.2、AVB
现在网上内容很多,不再赘述,解答标红的问题
android启动流程
https://source.android.google.cn/docs/security/features/verifiedboot/boot-flow?hl=zh-cn
android的AVB配置:
开启只需要打开AVB开关即可
BOARD_AVB_ENABLE:=True
BOARD_AVB_ALGORITHM := SHA256_RSA2048
BOARD_AVB_KEY_PATH := device/mediatek/common/oem_prvk.pem
如果是MTK需要开启kernel的config
MTK_AVB20_SUPPORT default y
换密钥参考:
https://blog.csdn.net/dongyi1988/article/details/103995737#t1
其中2、3步生成公钥头文件,MTK有现成转换工具der_extractor
AVB工具
https://android.googlesource.com/platform/external/avb/+/master/README.md
vbmeta结构
https://android.googlesource.com/platform/external/avb/+/master/libavb/avb_vbmeta_image.h
1、AVB如何联网签名?
google当然帮你想好了。avbtool有两个参数(--signing_helper与--signing_helper_with_files)均能达到联网签名的目的。
2、新增镜像如何纳入验证链?
如果放入secureboot流程,在env_cfg文件配置;
如果放入verify-boot流程,用vbmeta结构进行hash验证,可额外定制密钥,avbtool add_hash_footer 进行镜像签名,avbtool make_vbmeta_image制作vbmeta镜像时增加相关参数。
如果放入dm-verity流程,用vbmeta结构进行hashtree验证,可额外定制密钥,avbtool add_hashtree_footer进行镜像签名,avbtool make_vbmeta_image制作vbmeta镜像时增加相关参数。
3、安全启动验证链总结
安全启动验证链说明:
整个启动验证链的信任根是一次性写入的只读性存储中的公钥or公钥HASH;
这个信任根验证芯片厂商(vendor)所用到的所有镜像,关键是会验证lk和TEE;
lk与TEE证明可信之后,才能进一步验证kernel、dtbo、vbmeta,并确认结果;如果vbmeta有hash校验的分区,在此步直接校验;
kernel与vbmeta证明可信后,才能进一步验证system、vendor,odm等hashtree校验的分区,并确认结果。
所有不会改动的分区都应该纳入到这个验证链中,芯片厂商相关镜像一般放到secure boot,小镜像一般用verify-boot,大镜像一般放到动态分区进行dm-verity。
android安全启动验证链说明有类似Blog,参考https://www.cnblogs.com/azwhikaru/p/17063938.html,我们要学的是这个链式验证的思想,其中vbmeta结构还能扩展很多密钥,android的APEX功能就利用vbmeta结构也挂在这个验证链上。
版权归原作者 Kael.dong 所有, 如有侵权,请联系我们删除。