2、消息摘要算法应用
主要有包括OTA包传输、dm-verity、fs-verity、selinux重编译判断、bootconfig数据check、
签名验签中的校验数据完整性(查看非对称算法)。
后续还有,将继续更新。
2.1、下载包的完整性确认
OTA全包现在小则2G,传输过程、存储过程难免发生错误,为确保完整性会计算OTA全包的消息摘要,各家ODM方案不一致,拿官网GSI的zip包举例:
https://developer.android.com/topic/generic-system-image/releases?hl=zh-cn官网的包名与sha256校验和如下:
包下载后windows sha256计算命令与结果如下:
得到校验和一致,可以确认包完整。
在验签的时候会用到消息摘要算法,拿libavb深入解读为例,load_and_verify_hash_partition就是分区的hash计算对比,确认数据完整性。
2.2、dm-verity
dm-verity首先是个linux内核功能,https://gitlab.com/cryptsetup/cryptsetup/-/wikis/DMVerityDevice-mapper 它提供了一种创建块设备虚拟层的通用方法。Device-mapper verity target 使用内核加密 API 提供块设备的只读透明完整性检查。可用于android的全盘加密和块设备hashtree校验。
设计原理https://blog.csdn.net/feelabclihu/article/details/120232172这篇描述简单明了,但代码流程没看太懂。
更深代码流程看不懂,那就看看android怎么使用dm-verity的,https://stackdump.cn/dm-verity%E7%9A%84%E8%AF%A6%E7%BB%86%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4/
Mapping table for verity target基本语法如下:
<ver> <data_dev> <hash_dev> <data_blk_size> <hash_blk_size> <#blocks> <hash_start> <alg> <digest> <salt> [<#opt_params> <opt_params>]
ver:0用于Chromium OS,android设备一般是1
data_dev:需要检查其完整性的数据块
hash_dev:hash树存储的数据块
data_blk_size:数据设备上的块大小(以字节为单位)。 每个块对应哈希设备上的一个摘要。
hash_blk_size:哈希块的大小(以字节为单位)。
#blocks:数据设备上的数据块数。不算附加的。
hash_start:偏移量,以hash_blk_size块为单位,从hash_device开始到哈希树的根块。
alg:用于此设备的加密哈希算法。 这应该是算法的名称,例如“sha256”。
digest:根哈希块和盐的加密哈希的十六进制编码。这个散列应该是可信的。
salt:盐值的十六进制编码。
#opt_params:其他可选参数。
实例参考:
在制作镜像时很多参数存入vbmeta的hashtree描述符。
typedef struct AvbHashtreeDescriptor {
AvbDescriptor parent_descriptor;
uint32_t dm_verity_version;
uint64_t image_size;
uint64_t tree_offset;
uint64_t tree_size;
uint32_t data_block_size;
uint32_t hash_block_size;
uint32_t fec_num_roots;
uint64_t fec_offset;
uint64_t fec_size;
uint8_t hash_algorithm[32];
uint32_t partition_name_len;
uint32_t salt_len;
uint32_t root_digest_len;
uint32_t flags;
uint8_t reserved[60];
} AVB_ATTR_PACKED AvbHashtreeDescriptor;
上图时GSI的system hashtree描述符。dm-verity需要数据基本都能对应,hash_dev数据存储在tree_offset(偏移0xB2E0A000,大小0x168B0)。
2.3、fs-verity
官网描述https://source.android.google.cn/docs/security/features/apk-verity?hl=da
fs-verity 是一项 Linux 内核功能,可让系统持续通过受信任的数字证书来验证 APK 文件。在平台提供这种访问时验证机制的情况下,有了来自某个受支持商店(例如 Play)的受信任证书,该商店便可以安装具有 fs-verity 签名的 APK 文件来进行持续验证。受 fs-verity 保护的文件是不可变的,并且仅在内容通过验证后读取请求才会成功。
内核支持 fs-verity 后,合作伙伴可以将来自其受信任商店的新型证书存放在产品分区 /product/etc/security/fsverity 内,证书会在启动期间加载到内核密钥环。在支持此功能的设备上,受信任的商店可以安装具有相应 fs-verity 签名的 APK。
fs-verity模块详细描述参考
https://www.kernel.org/doc/html/latest/filesystems/fsverity.html
己见
这是相对与dm-verity的内核功能,dm-verity用于块设备,fs-verity用于文件系统;类似于全盘加密和文件系统加密;
fs-verity保护的文件在/product/etc/security/fsverity内;
目前ext4、f2fs 和 btrfs 文件系统支持它,使能后这些文件(/product/etc/security/fsverity目录下文件)计算hash另外保存起来,原文件成为只读文件,差异于dm-verity(块设备hash计算的内核模块);
受保护文件在读时出现篡改,将阻止;所以fs-verity没有数字证书的验证功能,他只有hash计算对比,保证数据完整性的功能;
受保护文件如果是受信任商店的新型证书,那么就可以直接授信对应签名的apk文件;
当然还有其它用处,目前google资料上看,文件系统加密、apk验签用到这个功能。
内核密钥环keyrings
https://man7.org/linux/man-pages/man7/keyrings.7.html
其中全盘加密和文件级加密用到,有了密钥环可以透明访问加密文件。
2.4、selinux重编译判断
selinux预编译判断,如果hash对比有差异将重新编译组合https://source.android.google.cn/docs/security/features/selinux/build#precompiled-policy
以下情况需要重新编译,编译时间1-2s,会导致开机变慢。
Both /system/etc/selinux/plat_sepolicy_and_mapping.sha256 and /{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 存在但是不一致。
Both /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256 and /{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 不存在或者都存在但是不一致。
Both /product/etc/selinux/product_sepolicy_and_mapping.sha256 and /{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 不存在或者都存在但是不一致。
2.5、bootconfig数据checksum
这里就是简单计算和,但也算消息摘要计算;后续应该会更新使用hash计算。