Android FBE

参考文档:

https://github.com/novelinux/android/wiki/Android-FBE

前面两个章节来自上述链接,在此致以谢意!

Android FBE简介

名称: FBE,File-Based Encryption,基于文件的加密
Android官方文档:https://source.android.com/security/encryption/file-based.html
支持版本:Android 7.0支持
主要作用: Android 7.0及更高版本支持基于文件的加密(FBE)。基于文件的加密允许不同文件被不同keys加密并且解锁也是独立的。
提到Android FBE就不得不提到Android Direct Boot,下面我们就从Direct Boot开始介绍FBE。

Direct Boot

Android官方文档: https://developer.android.com/training/articles/direct-boot.html
当设备通电但用户尚未解锁设备时,Android 7.0以安全的直接引导模式(Direct boot)运行。为了支持这一点,系统提供了两个数据存储位置:

设备加密存储DE:这是在直接引导模式期间和用户解锁设备后可用的存储位置。(/data/user_de/)
凭证加密存储CE:它是默认存储位置,仅在用户解锁设备后可用。(/data/data --> /data/user/)

如下,未解锁设备时,data/data分区下面数据都是乱码

xxxx:/data/data # ls
+1przBAAAAwizOmydDSDnmSuhpM2bC7XfR9jRqjsS1cBxirM2baIjB                                            Us9kyDAAAAQN8hVX,BGKFiZuYU0LtcFXicKkKMc998iMOAOeWqG9e4WMV7XNHBTtPnDtBpPL6KK
+7euADAAAAQEYEQSkZXnTBNfTSOddnPmgwozN13nE7R+gpNx4,M89A                                            VYRlUAAAAAwMbYllyGVzyY3ayZgfkbzTiUpHZbX,1qHGBeyL44bZDIYf295x7melh2CfdQHqs8A
+AM4bCAAAAQkJ,wSGXhucLTX73pwH4Xz1wHWd9HYoUIm5iRRv0yVcB                                            VuLCbDAAAAQNHLYk+3ZqlHf1v,st1VqwMeHqhgzmZ5SPhD71tJexTA
+hAk4DAAAAQF8eOkirWvlnPJaPVxA6IwtmSCq4S,KFlK95EVtW7JLA                                            W+mHDAAAAAAgNph8Kkt67gHDwIh60HOa

当尝试新建一个文件时,会有相应提示:

xxxx:/data/data # touch a
touch: 'a': Required key not available

默认情况下,应用程序不会在直接引导模式下运行。如果您的应用程序需要在直接引导模式下采取行动,您可以注册应在此模式下运行的应用程序组件。在直接引导模式下需要运行的应用程序的一些常见用例包括:

  • 已安排通知的应用程式,例如闹钟应用
  • 提供重要用户通知的应用,例如短信应用
  • 提供无障碍服务的应用,如Talkback

如果您的应用程序需要在直接引导模式下运行时访问数据,请使用设备加密存储。设备加密存储包含使用仅在设备执行成功验证的引导后可用的密钥加密的数据。 对于应使用与用户凭据关联的密钥(如PIN或密码)加密的数据,请使用凭据加密存储。凭证加密存储仅在用户成功解锁设备后才可用,直到用户再次重新启动设备为止。 如果用户在解锁设备后启用锁定屏幕,则不会锁定凭证加密存储。

关于元数据加密

由于在元数据加密密钥可用之前,userdata 分区中的所有内容均无法读取,因此分区表必须留出一个名为“metadata 分区”的单独分区,用于存储保护该密钥的 Keymaster Blob。metadata 分区的大小应为 16MB(参考官网关于元数据加密的说明:https://source.android.com/security/encryption/metadata)。

metadata秘钥:

xxxx:/metadata/vold/metadata_encryption/key # ls -l
total 52
-rw------- 1 root root    92 1970-04-04 18:28 encrypted_key
-rw------- 1 root root   464 1970-04-04 18:28 keymaster_key_blob
-rw------- 1 root root 16384 1970-04-04 18:28 secdiscardable
-rw------- 1 root root    10 1970-04-04 18:28 stretching
-rw------- 1 root root     1 1970-04-04 18:28 version

秘钥生成过程:

05069 01-01 09:55:48.908 268 268 I vold : [voldnativeservice] encryptFstab: No such file or directory
05070 01-01 09:55:48.908 268 268 D vold : [metadatacrypt] fscrypt_mount_metadata_encrypted mount_point: /data needs_encrypt ? 1
05071 01-01 09:55:48.908 268 268 D vold : [metadatacrypt] makeGen use_hw_wrapped_key ? 0
05072 01-01 09:55:48.909 268 268 D vold : [metadatacrypt] read_key metadata_key_dir: /metadata/vold/metadata_encryption
05073 01-01 09:55:48.909 268 268 D vold : [metadatacrypt] read_key metadata_key_dir/key: /metadata/vold/metadata_encryption/key
05085 01-01 09:55:48.916 268 268 D vold : [metadatacrypt] read_key newKeyPath: /metadata/vold/metadata_encryption/key/keymaster_key_blob_upgraded
05086 01-01 09:55:48.916 268 268 D vold : [keyutil] retrieveOrGenerateKey key_path: /metadata/vold/metadata_encryption/key
05087 01-01 09:55:48.916 268 268 I vold : [keyutil] retrieveOrGenerateKey Creating new key in /metadata/vold/metadata_encryption/key
05088 01-01 09:55:48.916 268 268 D vold : [keyutil] generateStorageKey
05089 01-01 09:55:48.916 268 268 D vold : [keyutil] generateStorageKey use random key
05090 01-01 09:55:48.916 268 268 D vold : [keystorage] storeKeyAtomically key_path: /metadata/vold/metadata_encryption/key tmp_path: /metadata/vold/metadata_encryption/tmp //初始是用tmp目录,后续直接重命名
05091 01-01 09:55:48.916 268 268 D vold : [keystorage] storeKeyAtomically -> storeKey
05092 01-01 09:55:48.916 268 268 D vold : [keystorage] storeKey dir: /metadata/vold/metadata_encryption/tmp
05093 01-01 09:55:48.917 268 268 D vold : [keystorage] storeKey write string: 1 to file: /metadata/vold/metadata_encryption/tmp/version
05095 01-01 09:55:48.924 268 268 D vold : [keystorage] storeKey createSecdiscardable filename: /metadata/vold/metadata_encryption/tmp/secdiscardable hash:
05096 01-01 09:55:48.925 268 268 D vold : [keystorage] createSecdiscardable filename: /metadata/vold/metadata_encryption/tmp/secdiscardable
05097 01-01 09:55:48.928 268 268 D vold : [keystorage] storeKey write stretching to file: /metadata/vold/metadata_encryption/tmp/stretching
05098 01-01 09:55:48.931 268 268 D vold : [keystorage] generateAppId
05099 01-01 09:55:48.931 268 268 D vold : [keystorage] stretchSecret
05115 01-01 09:55:48.941 268 268 D vold : [keystorage] storeKey write kmKey to file: /metadata/vold/metadata_encryption/tmp/keymaster_key_blob
05116 01-01 09:55:48.944 268 268 D vold : [keystorage] encryptWithKeymasterKey dir: /metadata/vold/metadata_encryption/tmp
05117 01-01 09:55:48.944 268 268 D vold : [keystorage] begin kmkeypath: /metadata/vold/metadata_encryption/tmp/keymaster_key_blob
05127 01-01 09:55:48.948 268 268 D vold : [keystorage] storeKey write encryptedKey to file: /metadata/vold/metadata_encryption/tmp/encrypted_key
05129 01-01 09:55:48.951 268 268 I vold : [vold][utils] FsyncDirectory dirname: /metadata/vold/metadata_encryption/tmp
05130 01-01 09:55:48.951 268 268 D vold : [keystorage] storeKeyAtomically rename /metadata/vold/metadata_encryption/tmp to /metadata/vold/metadata_encryption/key //这里重命名
05131 01-01 09:55:48.952 268 268 D vold : [keystorage] storeKeyAtomically Created key: /metadata/vold/metadata_encryption/key
05132 01-01 09:55:48.952 268 268 D vold : [metadatacrypt] create_crypto_blk_dev dm_name: userdata blk_device: /dev/block/by-name/userdata
05133 01-01 09:55:48.955 268 268 I vold : [metadatacrypt] fscrypt_mount_metadata_encrypted after create_crypto_blk_dev crypto_blkdev: /dev/block/dm-7
05134 01-01 09:55:48.955 268 268 I vold : [metadatacrypt] fscrypt_mount_metadata_encrypted Beginning inplace encryption, nr_sec: 102219736
05660 01-01 09:55:54.464 268 268 D vold : [metadatacrypt] fscrypt_mount_metadata_encrypted Mounting metadata-encrypted filesystem:/data
05661 01-01 09:55:54.464 268 268 D vold : [metadatacrypt] mount_via_fs_mgr mount_point: /data blk_device: /dev/block/dm-7 //data分区,在此之前元数据的key已经生成

keymaster服务的启动:

metadata key的生成依赖keymaster TA,所以对keymaster的启动做个简单的了解。

Keymaster 必须在 init 尝试装载 /data 之前运行并准备就绪。(Android官网)

第三方tee方案:

android.hardware.keymaster@4.0-service.bpxxx.rc

service vendor.keymaster-4-0-bpxxx /vendor/bin/hw/android.hardware.keymaster@4.0-service.bpxxx
class early_hal
user system
group system drmrpc

init.rc中start early_hal:system/core/rootdir/init.rc

on late-fs
# Ensure that tracefs has the correct permissions.
# This does not work correctly if it is called in post-fs.
chmod 0755 /sys/kernel/tracing
chmod 0755 /sys/kernel/debug/tracing

# HALs required before storage encryption can get unlocked (FBE/FDE)
class_start early_hal

init.rc中初始化顺序参考:https://segmentfault.com/a/1190000039052983

备注:optee方案上碰到过keymaster服务无法正常启动的问题,原因为tee-supplicant用到了/data/vendor目录,但data分区需要等metadata加密处理完成之后才能正常挂载,而metadata分区加密依赖keymaster提供的服务,keymaster启动时,需要加载TA,这个过程对tee-supplicant有依赖。从而形成了死锁。最终是将tee-supplicant的secure storage目录里调整到persist分区(persist分区挂载较早),确保tee-supplicant启动后,keymaster才能正常启动。

    Fix xxxxx, use persist as secure storage

diff --git a/Android.mk b/Android.mk
index 28ccce8..08e28f9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -10,7 +10,7 @@ CFG_TEE_SUPP_LOG_LEVEL ?= 2
 # Define Android-specific configuration before including config.mk
 CFG_TEE_CLIENT_LOAD_PATH ?= /vendor/lib
 TEEC_TEST_LOAD_PATH ?= /data/vendor/tee
-CFG_TEE_FS_PARENT_PATH ?= /data/vendor/tee
+CFG_TEE_FS_PARENT_PATH ?= /mnt/vendor/persist/tee
 ifneq ($(strip $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)),)
 CFG_TEE_PLUGIN_LOAD_PATH ?= /vendor/lib64/tee-supplicant/plugins/
 else
 
posted @ 2023-03-16 16:09  xiululu  阅读(571)  评论(0编辑  收藏  举报