fde加密与解锁
加锁状态
有以下 几种加锁状态:
- 默认
- PIN 码
- 密码
- 解锁图案
- 指纹
- 人脸解锁
其中指纹加锁的前提是必须有pin/密码/解锁图案的其中一种。所以可以只看pin/密码/pattern图案解锁即可
首次启动默认密码的情况
首次启动时,设备会创建一个随机生成的 128 位主密钥,然后会使用默认密码
和存储的盐
对其进行哈希处理。默认密码是default_password
。不过,设备还会通过 TEE(例如 TrustZone)为生成的哈希签名。TEE 会使用相应签名的哈希来加密主密钥。
在已加密的设备上设置安全密码或更改安全密码
当用户在设备上设置 PIN 码/pattern图案密码或password时,只有 128 位的密钥会被重新加密并存储起来,加密设备的主密钥并不会改变。
当用户选择在设置中更改或移除密码时,界面会向 vold 发送 cryptfs changepw 命令,然后 vold 会使用新密码重新加密磁盘主密钥。
默认密码和用户设置的安全密码都是用来加密磁盘主密钥master_key的。
设置了安全密码下解密手机流程
手机开机后,通过FallbackHome会 startActivity(homeIntent),
在开机过程中,会先跑到CryptKeeper.java(定义了intent-filter android.intent.category.HOME
,且priority比较靠前)
1 | <activity android:name=".CryptKeeper" |
先调用setupUi方法
1 | // 如果部分加密失败,跳转到恢复出厂设置 |
通过StorageManagerService查询passwordType,最终传递到vold中通过cryptfs_get_password_type
方法查询密钥类型是pattern/passwd/pin的哪个。这个方法是通过查询userdata块设备尾部存储的footer信息查出来的,而在加密的时候,也会根据用户密码的类似保存这样的type信息最终存储到设备的footer中
CryptKeeper根据用户密码类型显示对应的密码输入页面,即refreshUnlockEntry(passwordType)
函数
对于密码类型,注册了监听类passwordEntryInit
1 | if (mPasswordEntry != null && !mCooldown){ |
mKeyboardActionListener的onKeyBoardOK
时,即按了发送enter键后,会将输入的密码传出,发送给StorageManagerService
最终传给vold,decryptStorage(String password)-> cryptfs_check_passwd(passwd.c_str)
测试密码
vold通过test_mount_encrypted_fs
对用户密码解密出磁盘主密钥,通过磁盘主密钥对设备进行挂载,如果能挂载上,则说明用户密码是正确的
1 | decrypt_master_key(passwd, decrypted_master_key, crypt_ftr, &intermediate_key, |
小结
通过上述解密过程,用户密码是明文的形式,并没有再次对用户密码进行加密。这个过程应该是可以模拟的,如果可以在recovery模式下模拟出pattern/passwd/pattern三种模式的输入,是可以在recovery模式下解密用户设置了安全密码的fde的数据的