1. 概览
1.1 设计概览
采用文件级加密时:
- 可以使用不同的密钥对不同的文件进行加密,也可以对加密文件单独解密
- 可以有的放矢,没有安全要求的文件可以不加密
- 支持多用户,不同用户使用不同的密钥
基于这些特性,Google 对 Android 用户数据分区的目录做了安全等级划分,一些非用户隐私数据可以在设备启动后直接可以访问,解决了 FDE(Full Disk Encryption)的弊端,在 【数据安全】1. Android 保护用户隐私数据的技术介绍_zs.w的博客-CSDN博客 或者 direct-boot 已经做了介绍。
在 FBE 的设计中,根据文件内容的私密性,Google 把用户数据分区的存储位置划分安全等级,包括下几类:
①. 不加密的存储位置
- Unencrypted
②. 加密的存储位置
- 与用户无关的系统设备存储位置
- System Device Encrypted (DE) Storage :一般存储一些设备相关,Framework 相关等用户无关的数据。
- 与用户相关的存储位置 :
- Device Encrypted (DE) Storage :与用户相关的数据,安全性要求一般,在设备启动后以及用户解锁设备后都可以直接访问。
- Credential Encrypted (CE) Storage :与用户相关的数据,安全性等级高,如果用户设置了锁屏密码,必须在用户解锁设备后这些存储位置的数据才可用。
Unencrypted Storage | System DE Storage | User.0 DE Storage | User.0 CE Storage | |
---|---|---|---|---|
/data/lost+found /data/unencrypted /data/media /data/system_ce /data/system_de /data/misc_ce /data/misc_de /data/user /data/user_de /data/vendor_ce /data/vendor_de | /data/misc /data/local /data/vendor /data/property /data/tombstones /data/dalvik-cache /data/resource-cache /data/backup /data/system /data/cache /data/adb /data/anr /data/app | /data/app-asec /data/app-ephemeral /data/app-lib /data/app-private /data/bootchart /data/dpm /data/drm /data/mediadrm /data/nfc /data/ota /data/ota_package /data/ss | /data/system_de/0 /data/misc_de/0 /data/vendor_de/0 /data/user_de/0 | /data/system_ce/0 /data/misc_ce/0 /data/vendor_ce/0 /data/media/0 /data/data |
需要注意的点:
①. 从 User.x DE/CE 以及对应文件夹的命名可知,FBE 天然支持多用户 :
- 每个用户都拥有2个单独的加密密钥: DE Master Key 和 CE Master Key。
②. 当用户未设置锁屏密码时:
- DE 密钥和 CE 密钥安全等级一致,即开机过程中,APP 就可以直接访问 Device Encrypted (DE) Storage 和 Credential Encrypted (CE) Storage。
③. 当用户设置锁屏密码时:
- 只有校验用户密码成功后,用户的 CE 密钥才可用。即用户输入锁屏密码解锁设备后,APP 才可访问 Credential Encrypted (CE) Storage,同时访问到文件的明文数据。
- 用户 0 由于是特殊用户,必须先登录设备(设备启动后会自动登录用户0);
- 不同存储位置的加解密顺序存在依赖关系:
- 解密 System DE Storage 所需的密钥信息被存储在未加密目录 /data/unencrypted;
- 解密 User Device Encrypted (DE) Storage 和 User Credential Encrypted (CE) Storage 所需的密钥信息被存储在 System DE Storage 路径 /data/misc/vold/user_keys;
这里再次重复磁盘数据加密解决的问题,对于后面理解 FBE 的设计很重要。
解决设备被盗,丢失或者送修等机器不在用户手中的情况下,依然保护用户的隐私数据不被窃取。但是对于用户正常使用过程中,黑客通过提权等手段窃取数据的行为,这些技术基本无能为力,目前主要还是靠传统的 DAC(user、group、others) 和 MAC(selinux)。
FBE 至少要解决以下特殊场景,用户数据的安全性,做到无法解密:
- 直接把存储器从主板拆下后,换到另一台设备或者使用专业的工具直接读存储器;
- 设备主板的 CPU 或者存储器被更换;
- 软件回滚,软件或固件回滚到存在 bug 的版本;
按照上述的要求,FBE 必须要解决的核心技术问题至少包括:安全的密钥管理和高效的 I/O。
1.2 密钥管理
①.对不同安全等级的加密存储位置,至少涉及 3 个密钥,包括:
- System DE key
- User DE key for user 0
- User CE key for user 0
②. 密钥的安全管理,包括:
- 在安全的内核密钥环(kernel keyring)和 ARM TZ 环境中管理密钥
- 密钥不允许出现在 HLOS
- 每个文件及其名称都应使用不同且唯一的密钥进行加密
- 根据 HLOS 请求,创建,更新和失效密钥等(支持远程擦除密钥)
- ......
1.3 高效 I/O
在文件读写时,文件数据加解密对 APP 应该是透明的,高效的,那么需要需要回答这些问题:
①. 在 I/O statck 中,怎么根据文件的存储位置以使用不同的密钥加解密数据?
②. 根据 FDE 设计的经验,FBE 必须借助 ICE 才可能有效的减少对 I/O 性能的影响,这里衍生出一些子问题:
- 在 I/O 过程中,对于不同的文件,怎么使用唯一的密钥加密文件名和内容?这些密钥存储在哪里?
- 在 HLOS 端的 ICE 驱动怎么为不同的文件对应的I/O请求设置不同的密钥?
- ......
密钥管理和高效的 I/O 是 FBE 核心,后面会专门详细介绍。
2. FBE 架构
截止 Android 11,FBE 已经经历了两代的发展,下文介绍 V1 和 V2 架构。升级 V2 的目的主要包括:
- 上游不支持硬件加密 :
- 在启动期间,存在繁琐工作;
- 每个新内核的移植工作可以减少 3-4 周;
- 更合理的 Linux 分层,包括:文件系统、通用块层以及设备驱动;
- Fscrypt v1 → Fscrypt v2
- 支持 wrapped keys
- 适配 GKI
2.1 FBE V1 Architecture
![](https://i-blog.csdnimg.cn/blog_migrate/04658918c8e1f371bfa3405ae4c4d0d5.png)
2.2 FBE V2 Architecture
![](https://i-blog.csdnimg.cn/blog_migrate/25356066a5641360829373dcb5207322.png)
这里简单介绍以下 V2 版本中的几个组件:
①. KeySlot Manager
VFS 层和存储层之间的密钥槽管理器 KSM 桥的作用如下:
- KSM ops (由 UFS 驱动实现)
- Keyslot program
- Keyslot evict
- Get raw secret
- 向底层暴露 APIs
- Keyslot manager create
- Keyslot manager destroy
- 向上层暴露 API APIs
- Get slot for key
- Evict key
- Derive raw secret
keyslot 定义:
// drivers/scsi/ufs/ufshcd-crypto-qti.c
static const struct blk_ksm_ll_ops ufshcd_ksm_ops = {
.keyslot_program = ufshcd_crypto_qti_keyslot_program,
.keyslot_evict = ufshcd_crypto_qti_keyslot_evict,
.derive_raw_secret = ufshcd_crypto_qti_derive_raw_secret,
};
②. UFS Crypto
供应商可以实现 UFS crypto 特定的 variant ops,不同的芯片厂商按照硬件的设计可以提供差异化的解决方案。
UFS crypto 支持的 variant ops 包括:
- Setup keyslot manager
- Destroy keyslot manager
- Init crypto
- Enable crypto
- Disable crypto
- Suspend
- Resume
比如高通平台的实现:
// linux-next/drivers/scsi/ufs/ufshcd-crypto.c
/*
* struct ufs_hba_qcom_vops - UFS QCOM specific variant operations
*
* The variant operations configure the necessary controller and PHY
* handshake during initialization.
*/
static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
.name = "qcom",
.init = ufs_qcom_init,
.exit = ufs_qcom_exit,
.get_ufs_hci_version = ufs_qcom_get_ufs_hci_version,
.clk_scale_notify = ufs_qcom_clk_scale_notify,
.setup_clocks = ufs_qcom_setup_clocks,
.hce_enable_notify = ufs_qcom_hce_enable_notify,
.link_startup_notify = ufs_qcom_link_startup_notify,
.pwr_change_notify = ufs_qcom_pwr_change_notify,
.apply_dev_quirks = ufs_qcom_apply_dev_quirks,
.suspend = ufs_qcom_suspend,
.resume = ufs_qcom_resume,
.dbg_register_dump = ufs_qcom_dump_dbg_regs,
.device_reset = ufs_qcom_device_reset,
.config_scaling_param = ufs_qcom_config_scaling_param,
.program_key = ufs_qcom_ice_program_key,
};
3. HLOS 软件流程
3.1 Native 软件流程
Android 在 init rc 中 触发 FBE 软件流程:
- 在启动过程中,准备 FBE Master key,设置和校验各加密存储位置的加密策略(Encryption Policy)。
- 真正数据加密和解密是发生在文件 I/O 时,而加密和解密所需的信息来源于文件的 Encryption Policy。Encryption Policy 包括:
- 使用哪个 Master Key 加密;
- 文件数据的加密算法;
- 文件名的加密算法;
关于 Encryption Policy 后续在密钥管理章节详细介绍。
![](https://i-blog.csdnimg.cn/blog_migrate/bbdb6d7ea9c1f8014246f12e83c65df2.png)
① installkey /data
软件流程进入 Vold 函数 fscrypt_initialize_systemwide_keys()。
设备第一次启动时:
- 创建 System DE Master Key 和生成 System DE Encryption Policy;
- 把 System DE Encryption Policy 保存到文件 /data/unencrypted/ref;
后续每次启动时:
- 加载 System DE Master Key;
② mkdir <system de storage>
- 如果 System DE Storage 不存在,创建并为文件夹设置 System DE Encryption Policy;
- 如果 System DE Storage 已经存在,则校验 System DE Encryption Policy;
- 校验失败会强制设备启动到 recovery ,格式化 userdata 分区;
③ init_user0
软件流程进入 Vold 函数 fscrypt_init_user0()。
设备第一次启动时:
- 创建 User 0 DE Master Key 和生成 User 0 DE Encryption Policy;
- 创建 User 0 CE Master Key 和生成 User 0 CE Encryption Policy;
- 创建 User 0 DE Storage,并为这些文件夹设置 User 0 DE Encryption Policy
后续每次启动时:
- 加载 User 0 DE Master Key;
- 准备 User 0 DE Storage,并校验文件夹 Encryption Policy;
- 校验失败,不会强制格式化 userdata ,但是用户数据将无法使用,可能无法开机。
3.2 Framework 软件流程
可以发现在 Native 软件流程中, init_user0 中关于 User 0 CE 的流程相比 User 0 DE 存在缺失,主要包括:
(1) 第一次启动时, User 0 CE Storage 是什么时候创建的呢?
设备继续启动,由框架 UserController 通过 binder 触发 Vold 创建 User 0 CE Storage 和为相关文件夹设置 User 0 CE Encryption Policy
(2) 后续每次启动时,加载 User 0 DE Master Key、准备 User 0 DE Storage 、校验 User 0 CE Encryption Policy 是什么时候发生?
① 用户未设置锁屏密码时,设备启动 completed 后,ActivityManagerService 层层触发 Vold 完成这些任务;
![](https://i-blog.csdnimg.cn/blog_migrate/b5b394f0ed31499fe46276927f801cf4.png)
② 用户设置锁屏密码时,用户输入密码并校验通过后,LockSettingsService 层层触发 Vold 完成这些任务;
![](https://i-blog.csdnimg.cn/blog_migrate/28396792a36a7e861082662b49af66bb.png)
从图中可以看到,无论是设置用户密码,软件流程又回到了 Vold:
- fscrypt_unlock_user_key : 加载 User 0 CE Master Key
- fscrypt_prepare_user_storage:准备 User 0 CE Storage,并校验文件夹 Encryption Policy;
软件流程就介绍到这里,FBE 的密钥管理贯穿在上面介绍的这些流程中,在后文 《【数据安全】4. Android 文件级加密(File-based Encryption)之密钥管理》详细介绍 FBE 的核心之一密钥管理
。