FBE 文件级加密过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# system/core/rootdir/init.rc
on post-fs-data
mark_post_data
# 在访问 data 分区之前先执行 checkpoint
exec - system system -- /system/bin/vdc checkpoint prepareCheckpoint
# 由于 data 分区默认是以 root 权限挂载的,此处调整用户群组读写可执行权限。
chown system system /data
chmod 0771 /data
# We restorecon /data in case the userdata partition has been reset.
// 恢复 data 分区的 selinux 权限
restorecon /data
# 确保有设备加密密钥(DE Key)
installkey /data
# 初始化 user0 (CE key)
init_user0

一、installkey

1.1 builtins::do_installkey

1
2
3
4
5
6
7
8
9
10
11
// system/core/init/builtins.cpp
static Result<void> do_installkey(const BuiltinArguments& args) {
// 如果 ro.crypto.type 属性对应的不是 file 则表明不是文件级加密,返回空退出。
if (!is_file_crypto()) return {};
// 创建未加密目录:/data/unencrypted 。
auto unencrypted_dir = args[1] + fscrypt_unencrypted_folder;
if (!make_dir(unencrypted_dir, 0700) && errno != EEXIST) {
return ErrnoError() << "Failed to create " << unencrypted_dir;
}
return ExecVdcRebootOnFailure("enablefilecrypto");
}

1.2 builtins::ExecVdcRebootOnFailure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// system/core/init/builtins.cpp
static Result<void> ExecVdcRebootOnFailure(const std::string& vdc_arg) {
bool should_reboot_into_recovery = true;
auto reboot_reason = vdc_arg + "_failed";
// 用户空间重启(软重启)失败处理-android 11新功能。
if (android::sysprop::InitProperties::userspace_reboot_in_progress().value_or(false)) {
should_reboot_into_recovery = false;
reboot_reason = "userspace_failed," + vdc_arg;
}
auto reboot = [reboot_reason, should_reboot_into_recovery](const std::string& message) {
if (should_reboot_into_recovery) {
// 烧录 GSI 后重启进入 recovery 模式执行恢复出厂操作。
if (fscrypt_is_native() && !android::gsi::IsGsiRunning()) {
LOG(ERROR) << message << ": Rebooting into recovery, reason: " << reboot_reason;
if (auto result = reboot_into_recovery(
{"--prompt_and_wipe_data", "--reason="s + reboot_reason});
!result.ok()) {
LOG(FATAL) << "Could not reboot into recovery: " << result.error();
}
} else {
LOG(ERROR) << "Failure (reboot suppressed): " << reboot_reason;
}
} else {
LOG(ERROR) << message << ": rebooting, reason: " << reboot_reason;
trigger_shutdown("reboot," + reboot_reason);
}
};
// 执行 "/system/bin/vdc --wait cryptfs enablefilecrypto" 命令。
std::vector<std::string> args = {"exec", "/system/bin/vdc", "--wait", "cryptfs", vdc_arg};
return ExecWithFunctionOnFailure(args, reboot);
}

1.3 vdc::main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// system/vold/vdc.cpp
int main(int argc, char** argv) {
setenv("ANDROID_LOG_TAGS", "*:v", 1);
if (getppid() == 1) {
// If init is calling us then it's during boot and we should log to kmsg
// 如果是 init 启动时候调用,则需要将日志写入kmsg。
android::base::InitLogging(argv, &android::base::KernelLogger);
} else {
android::base::InitLogging(argv, &android::base::StderrLogger);
}
std::vector<std::string> args(argv + 1, argv + argc);
// 忽略 "--wait" 参数。
if (args.size() > 0 && args[0] == "--wait") {
args.erase(args.begin());
}
// 新参数个数检查,小于2则退出。
if (args.size() < 2) {
usage(argv[0]);
exit(5);
}
// 获取 vold binder。
android::sp<android::IBinder> binder = getServiceAggressive();
if (!binder) {
LOG(ERROR) << "Failed to obtain vold Binder";
exit(EINVAL);
}
auto vold = android::interface_cast<android::os::IVold>(binder);
// 启用文件级加密。
if (args[0] == "cryptfs" && args[1] == "enablefilecrypto") {
checkStatus(args, vold->fbeEnable());
// 初始化 user0 。
} else if (args[0] == "cryptfs" && args[1] == "init_user0") {
checkStatus(args, vold->initUser0());
// 启用全盘加密。
} else if (args[0] == "cryptfs" && args[1] == "enablecrypto") {
int passwordType = android::os::IVold::PASSWORD_TYPE_DEFAULT;
int encryptionFlags = android::os::IVold::ENCRYPTION_FLAG_NO_UI;
checkStatus(args, vold->fdeEnable(passwordType, "", encryptionFlags));
// 默认加密挂载。
} else if (args[0] == "cryptfs" && args[1] == "mountdefaultencrypted") {
checkStatus(args, vold->mountDefaultEncrypted());
...
// 挂载 fstab 表中分区。
} else if (args[0] == "cryptfs" && args[1] == "mountFstab" && args.size() == 4) {
checkStatus(args, vold->mountFstab(args[2], args[3]));
// 加密 fstab 表。
} else if (args[0] == "cryptfs" && args[1] == "encryptFstab" && args.size() == 4) {
checkStatus(args, vold->encryptFstab(args[2], args[3]));
// 支持用户空间检查点。
} else if (args[0] == "checkpoint" && args[1] == "supportsCheckpoint" && args.size() == 2) {
bool supported = false;
checkStatus(args, vold->supportsCheckpoint(&supported));
return supported ? 1 : 0;
// 支持块检查点。
} else if (args[0] == "checkpoint" && args[1] == "supportsBlockCheckpoint" &&
args.size() == 2) {
bool supported = false;
checkStatus(args, vold->supportsBlockCheckpoint(&supported));
return supported ? 1 : 0;
// 支持文件检查点。
} else if (args[0] == "checkpoint" && args[1] == "supportsFileCheckpoint" && args.size() == 2) {
bool supported = false;
checkStatus(args, vold->supportsFileCheckpoint(&supported));
return supported ? 1 : 0;
// 开始 checkpoint 。
} else if (args[0] == "checkpoint" && args[1] == "startCheckpoint" && args.size() == 3) {
int retry;
if (!android::base::ParseInt(args[2], &retry)) exit(EINVAL);
checkStatus(args, vold->startCheckpoint(retry));
// 需要 checkpoint 。
} else if (args[0] == "checkpoint" && args[1] == "needsCheckpoint" && args.size() == 2) {
bool enabled = false;
checkStatus(args, vold->needsCheckpoint(&enabled));
return enabled ? 1 : 0;
// 需要回滚 checkpoint 。
} else if (args[0] == "checkpoint" && args[1] == "needsRollback" && args.size() == 2) {
bool enabled = false;
checkStatus(args, vold->needsRollback(&enabled));
return enabled ? 1 : 0;
// 提交 checkpoint 变更。
} else if (args[0] == "checkpoint" && args[1] == "commitChanges" && args.size() == 2) {
checkStatus(args, vold->commitChanges());
// 准备 checkpoint 。
} else if (args[0] == "checkpoint" && args[1] == "prepareCheckpoint" && args.size() == 2) {
checkStatus(args, vold->prepareCheckpoint());
// 恢复 checkpoint 。
} else if (args[0] == "checkpoint" && args[1] == "restoreCheckpoint" && args.size() == 3) {
checkStatus(args, vold->restoreCheckpoint(args[2]));
// 恢复部分 checkpoint 。
} else if (args[0] == "checkpoint" && args[1] == "restoreCheckpointPart" && args.size() == 4) {
int count;
if (!android::base::ParseInt(args[3], &count)) exit(EINVAL);
checkStatus(args, vold->restoreCheckpointPart(args[2], count));
// 试图标记启动。
} else if (args[0] == "checkpoint" && args[1] == "markBootAttempt" && args.size() == 2) {
checkStatus(args, vold->markBootAttempt());
// 中断 checkpoint 变更。
} else if (args[0] == "checkpoint" && args[1] == "abortChanges" && args.size() == 4) {
int retry;
if (!android::base::ParseInt(args[2], &retry)) exit(EINVAL);
checkStatus(args, vold->abortChanges(args[2], retry != 0));
// 重置 checkpoint 。
} else if (args[0] == "checkpoint" && args[1] == "resetCheckpoint") {
checkStatus(args, vold->resetCheckpoint());
} else {
LOG(ERROR) << "Raw commands are no longer supported";
exit(EINVAL);
}
return 0;
}

1.4 VoldNativeService::fbeEnable

1
2
3
4
5
6
7
8
9
// system/vold/VoldNativeService.cpp
binder::Status VoldNativeService::fbeEnable() {
// 强制 system 或 root 用户群组。
ENFORCE_SYSTEM_OR_ROOT;
// 获取加密锁。
ACQUIRE_CRYPT_LOCK;
// 初始化系统范围加密 keys 。
return translateBool(fscrypt_initialize_systemwide_keys());
}

1.5 FsCrypt::fscrypt_initialize_systemwide_keys

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// system/vold/FsCrypt.cpp
bool fscrypt_initialize_systemwide_keys() {
LOG(INFO) << "fscrypt_initialize_systemwide_keys";
EncryptionOptions options;
// 检索用于 /data 文件系统上的加密策略的选项。
if (!get_data_file_encryption_options(&options)) return false;
KeyBuffer device_key;
// 如果检索或生成 key 失败则返回 false。
// device_key_path--/data/unencrypted/key。
// device_key_path--/data/unencrypted/temp。
if (!retrieveOrGenerateKey(device_key_path, device_key_temp, kEmptyAuthentication,
makeGen(options), &device_key))
return false;
EncryptionPolicy device_policy;
// 在 /data 目录安装 device key。
if (!install_storage_key(DATA_MNT_POINT, options, device_key, &device_policy)) return false;
std::string options_string;
if (!OptionsToString(device_policy.options, &options_string)) {
LOG(ERROR) << "Unable to serialize options";
return false;
}
std::string options_filename = std::string(DATA_MNT_POINT) + fscrypt_key_mode;
if (!android::vold::writeStringToFile(options_string, options_filename)) return false;
std::string ref_filename = std::string(DATA_MNT_POINT) + fscrypt_key_ref;
if (!android::vold::writeStringToFile(device_policy.key_raw_ref, ref_filename)) return false;
LOG(INFO) << "Wrote system DE key reference to:" << ref_filename;
KeyBuffer per_boot_key;
// 如果生成存储 key 失败则返回 false 。
if (!generateStorageKey(makeGen(options), &per_boot_key)) return false;
EncryptionPolicy per_boot_policy;
if (!install_storage_key(DATA_MNT_POINT, options, per_boot_key, &per_boot_policy)) return false;
std::string per_boot_ref_filename = std::string("/data") + fscrypt_key_per_boot_ref;
if (!android::vold::writeStringToFile(per_boot_policy.key_raw_ref, per_boot_ref_filename))
return false;
LOG(INFO) << "Wrote per boot key reference to:" << per_boot_ref_filename;
if (!android::vold::FsyncDirectory(device_key_dir)) return false;
return true;
}

1.6 FsCrypt::get_data_file_encryption_options

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// system/vold/FsCrypt.cpp
static bool get_data_file_encryption_options(EncryptionOptions* options) {
// 从 fstab 中获取 data 分区挂载点-/data。
auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
if (entry == nullptr) {
LOG(ERROR) << "No mount point entry for " << DATA_MNT_POINT;
return false;
}
if (!ParseOptions(entry->encryption_options, options)) {
LOG(ERROR) << "Unable to parse encryption options for " << DATA_MNT_POINT ": "
<< entry->encryption_options;
return false;
}
// emmc flag -- FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32--0x10。
if ((options->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) &&
!IsEmmcStorage(entry->blk_device)) {
LOG(ERROR) << "The emmc_optimized encryption flag is only allowed on eMMC storage. Remove "
"this flag from the device's fstab";
return false;
}
return true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// system/vold/FsCrypt.cpp
static bool IsEmmcStorage(const std::string& blk_device) {
// 处理符号链接。
std::string real_path;
if (!Realpath(blk_device, &real_path)) {
real_path = blk_device;
}
// 处理逻辑卷。
auto& dm = DeviceMapper::Instance();
for (;;) {
auto parent = dm.GetParentBlockDeviceByPath(real_path);
if (!parent.has_value()) break;
real_path = *parent;
}
// 真实的块设备。
LOG(DEBUG) << "IsEmmcStorage(): blk_device = " << blk_device << ", real_path=" << real_path;
return StartsWith(Basename(real_path), "mmcblk");
}

1.7 KeyUtil::retrieveOrGenerateKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// system/vold/KeyUtil.cpp
bool retrieveOrGenerateKey(const std::string& key_path, const std::string& tmp_path,
const KeyAuthentication& key_authentication, const KeyGeneration& gen,
KeyBuffer* key, bool keepOld) {
// 如果 /data/unencrypted/key 目录存在则检查是否存在 key 。
if (pathExists(key_path)) {
LOG(DEBUG) << "Key exists, using: " << key_path;
if (!retrieveKey(key_path, key_authentication, key, keepOld)) return false;
} else {
// 不允许生成 key 则返回 false 。
if (!gen.allow_gen) {
LOG(ERROR) << "No key found in " << key_path;
return false;
}
LOG(INFO) << "Creating new key in " << key_path;
// 如果生成存储 key 失败则返回 false 。
if (!generateStorageKey(gen, key)) return false;
// 如果保存 key 失败则返回 false 。
if (!storeKeyAtomically(key_path, tmp_path, key_authentication, *key)) return false;
}
return true;
}

1.8 KeyStorage::retrieveKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// system/vold/KeyStorage.cpp
bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, KeyBuffer* key,
bool keepOld) {
std::string version;
// 若读取 /data/unencrypted/key/version 失败返回 false 。
if (!readFileToString(dir + "/" + kFn_version, &version)) return false;
// 如果读取的版本不等于 1 则返回 false 。
if (version != kCurrentVersion) {
LOG(ERROR) << "Version mismatch, expected " << kCurrentVersion << " got " << version;
return false;
}
std::string secdiscardable_hash;
// 若读取 /data/unencrypted/key/secdiscardable 失败返回 false 。
if (!readSecdiscardable(dir + "/" + kFn_secdiscardable, &secdiscardable_hash)) return false;
std::string stretching;
// 若读取 /data/unencrypted/key/stretching 失败返回 false 。
if (!readFileToString(dir + "/" + kFn_stretching, &stretching)) return false;
std::string salt;
// 若读取 /data/unencrypted/key/stretching 的返回结果不是 nopassword 或 none 则需要读取 /data/unencrypted/key/salt 。
if (stretchingNeedsSalt(stretching)) {
// 若读取 /data/unencrypted/key/salt 失败返回 false 。
if (!readFileToString(dir + "/" + kFn_salt, &salt)) return false;
}
std::string appId;
// 生成 app id 失败则返回 false。
if (!generateAppId(auth, stretching, salt, secdiscardable_hash, &appId)) return false;
std::string encryptedMessage;
// 若读取 /data/unencrypted/key/encrypted_key 失败返回 false 。
if (!readFileToString(dir + "/" + kFn_encrypted_key, &encryptedMessage)) return false;
// 如果 "token" 是非空的,则将其作为必需的 Gatekeeper 身份验证令牌传递。
// 如果 "token" 和 "secret" 为非空值,则 "secret" 将附加到解锁所需的特定于应用程序的二进制文件中。
// 如果只有 "token" 是非空的,则在非 Keymaster 进程中将其用于解密。
if (auth.usesKeymaster()) {
Keymaster keymaster;
if (!keymaster) return false;
km::AuthorizationSet keyParams;
km::HardwareAuthToken authToken;
std::tie(keyParams, authToken) = beginParams(auth, appId);
// 若使用 keymaster key 解密失败则返回 false 。
if (!decryptWithKeymasterKey(keymaster, dir, keyParams, authToken, encryptedMessage, key,
keepOld))
return false;
} else {
// 此时解密若有 keymaster 则返回 false 。
if (!decryptWithoutKeymaster(appId, encryptedMessage, key)) return false;
}
return true;
}

1.9 KeyUtil::generateStorageKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// system/vold/KeyUtil.cpp
bool generateStorageKey(const KeyGeneration& gen, KeyBuffer* key) {
if (!gen.allow_gen) return false;
// 判断是否使用硬件 wrapped key 。
if (gen.use_hw_wrapped_key) {
// 如果 key 大小不等于32则生成 wrapped key 失败。
if (gen.keysize != FSCRYPT_MAX_KEY_SIZE) {
LOG(ERROR) << "Cannot generate a wrapped key " << gen.keysize << " bytes long";
return false;
}
// 通过 keymaster 生成 wrapper key 。
return generateWrappedStorageKey(key);
} else {
// 随机生成 key 。
return randomKey(gen.keysize, key);
}
}

1.10 KeyStorage::generateWrappedStorageKey

1
2
3
4
5
6
7
8
9
10
11
12
13
// system/vold/KeyStorage.cpp
bool generateWrappedStorageKey(KeyBuffer* key) {
Keymaster keymaster;
if (!keymaster) return false;
std::string key_temp;
auto paramBuilder = km::AuthorizationSetBuilder().AesEncryptionKey(AES_KEY_BYTES * 8);
paramBuilder.Authorization(km::TAG_ROLLBACK_RESISTANCE);
paramBuilder.Authorization(km::TAG_STORAGE_KEY);
if (!keymaster.generateKey(paramBuilder, &key_temp)) return false;
*key = KeyBuffer(key_temp.size());
memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
return true;
}

1.11 KeyStorage::storeKeyAtomically

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// system/vold/KeyStorage.cpp
bool storeKeyAtomically(const std::string& key_path, const std::string& tmp_path,
const KeyAuthentication& auth, const KeyBuffer& key) {
// 如果 /data/unencrypted/key 目录存在则不再创建 key ,返回 false 。
if (pathExists(key_path)) {
LOG(ERROR) << "Already exists, cannot create key at: " << key_path;
return false;
}
// 如果 /data/unencrypted/temp 目录存在则不再创建 key ,返回 false 。
if (pathExists(tmp_path)) {
LOG(DEBUG) << "Already exists, destroying: " << tmp_path;
destroyKey(tmp_path);
}
// 如果 /data/unencrypted/temp 目录存储 key 失败则返回 false 。
if (!storeKey(tmp_path, auth, key)) return false;
if (rename(tmp_path.c_str(), key_path.c_str()) != 0) {
PLOG(ERROR) << "Unable to move new key to location: " << key_path;
return false;
}
LOG(DEBUG) << "Created key: " << key_path;
return true;
}

1.12 KeyStorage::destroyKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// system/vold/KeyStorage.cpp
bool destroyKey(const std::string& dir) {
bool success = true;
// 如果 /data/unencrypted/temp/keymaster_key_blob 存在则说明使用了 keymaster ,则删除 key。
bool uses_km = pathExists(dir + "/" + kFn_keymaster_key_blob);
if (uses_km) {
success &= deleteKey(dir);
}
// 执行 "/system/bin/secdiscard --/data/unencrypted/temp/encrypted_key /data/unencrypted/temp/secdiscardable" 命令。
auto secdiscard_cmd = std::vector<std::string>{
kSecdiscardPath,
"--",
dir + "/" + kFn_encrypted_key,
dir + "/" + kFn_secdiscardable,
};
// 使用 keymaster 则执行 "/system/bin/secdiscard --/data/unencrypted/temp/encrypted_key /data/unencrypted/temp/keymaster_key_blob" 命令 。
if (uses_km) {
secdiscard_cmd.emplace_back(dir + "/" + kFn_keymaster_key_blob);
}
if (ForkExecvp(secdiscard_cmd) != 0) {
LOG(ERROR) << "secdiscard failed";
success = false;
}
success &= recursiveDeleteKey(dir);
return success;
}

1.13 KeyStorage::deleteKey

1
2
3
4
5
6
7
8
9
10
11
// system/vold/KeyStorage.cpp
static bool deleteKey(const std::string& dir) {
std::string kmKey;
// 如果读取 /data/unencrypted/temp/keymaster_key_blob 失败则返回 false 。
if (!readFileToString(dir + "/" + kFn_keymaster_key_blob, &kmKey)) return false;
Keymaster keymaster;
if (!keymaster) return false;
// 如果调用 keymaster 删除 key 失败则返回 false 。
if (!keymaster.deleteKey(kmKey)) return false;
return true;
}

1.14 KeyStorage::recursiveDeleteKey

1
2
3
4
5
6
7
8
9
// system/vold/KeyStorage.cpp
static bool recursiveDeleteKey(const std::string& dir) {
// 执行 "/system/bin/rm -rf /data/unencrypted/temp/" 命令。
if (ForkExecvp(std::vector<std::string>{kRmPath, "-rf", dir}) != 0) {
LOG(ERROR) << "recursive delete failed";
return false;
}
return true;
}

1.15 KeyStorage::storeKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// system/vold/KeyStorage.cpp
bool storeKey(const std::string& dir, const KeyAuthentication& auth, const KeyBuffer& key) {
// 赋予 0700 权限创建 /data/unencrypted/temp 目录失败则返回 false 。
if (TEMP_FAILURE_RETRY(mkdir(dir.c_str(), 0700)) == -1) {
PLOG(ERROR) << "key mkdir " << dir;
return false;
}
// 往 /data/unencrypted/temp/version 写1失败则返回 false 。
if (!writeStringToFile(kCurrentVersion, dir + "/" + kFn_version)) return false;
std::string secdiscardable_hash;
// 往 /data/unencrypted/temp/secdiscardable 写数据失败则返回 false 。
if (!createSecdiscardable(dir + "/" + kFn_secdiscardable, &secdiscardable_hash)) return false;
std::string stretching = getStretching(auth);
// 往 /data/unencrypted/temp/stretching 写数据则返回 false 。
if (!writeStringToFile(stretching, dir + "/" + kFn_stretching)) return false;
std::string salt;
if (stretchingNeedsSalt(stretching)) {
if (ReadRandomBytes(SALT_BYTES, salt) != OK) {
LOG(ERROR) << "Random read failed";
return false;
}
// 往 /data/unencrypted/temp/salt 写数据则返回 false 。
if (!writeStringToFile(salt, dir + "/" + kFn_salt)) return false;
}
std::string appId;
// 生成 app id 失败则返回 false 。
if (!generateAppId(auth, stretching, salt, secdiscardable_hash, &appId)) return false;
std::string encryptedKey;
if (auth.usesKeymaster()) {
Keymaster keymaster;
if (!keymaster) return false;
std::string kmKey;
// 生成 keymaster key 失败则返回 false 。
if (!generateKeymasterKey(keymaster, auth, appId, &kmKey)) return false;
// 往 /data/unencrypted/temp/keymaster_key_blob 写数据失败则返回 false 。
if (!writeStringToFile(kmKey, dir + "/" + kFn_keymaster_key_blob)) return false;
km::AuthorizationSet keyParams;
km::HardwareAuthToken authToken;
std::tie(keyParams, authToken) = beginParams(auth, appId);
// 使用 keymaster key 加密失败则返回 false 。
if (!encryptWithKeymasterKey(keymaster, dir, keyParams, authToken, key, &encryptedKey,
false))
return false;
} else {
// 没有使用 keymaster key 加密则返回 false 。
if (!encryptWithoutKeymaster(appId, key, &encryptedKey)) return false;
}
// 往 /data/unencrypted/temp/encrypted_key 目录写 key 失败则返回 false 。
if (!writeStringToFile(encryptedKey, dir + "/" + kFn_encrypted_key)) return false;
if (!FsyncDirectory(dir)) return false;
return true;
}

1.16 FsCrypt::install_storage_key

1
2
3
4
5
6
7
8
9
10
11
12
13
// system/vold/FsCrypt.cpp
static bool install_storage_key(const std::string& mountpoint, const EncryptionOptions& options,
const KeyBuffer& key, EncryptionPolicy* policy) {
KeyBuffer ephemeral_wrapped_key;
if (options.use_hw_wrapped_key) {
if (!exportWrappedStorageKey(key, &ephemeral_wrapped_key)) {
LOG(ERROR) << "Failed to get ephemeral wrapped key";
return false;
}
}
return installKey(mountpoint, options, options.use_hw_wrapped_key ? ephemeral_wrapped_key : key,
policy);
}

1.17 KeyUtil::installKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// system/vold/KeyUtil.cpp
bool installKey(const std::string& mountpoint, const EncryptionOptions& options,
const KeyBuffer& key, EncryptionPolicy* policy) {
policy->options = options;
KeyBuffer arg_buf(sizeof(struct fscrypt_add_key_arg) + key.size(), 0);
struct fscrypt_add_key_arg* arg = (struct fscrypt_add_key_arg*)arg_buf.data();
switch (options.version) {
case 1:
// v1策略的密钥由任意8字节的“descriptor”指定,该描述符必须由用户空间提供。使用密钥本身的双SHA-512中的前8个字节。
policy->key_raw_ref = generateKeyRef((const uint8_t*)key.data(), key.size());
if (!isFsKeyringSupported()) {
return installKeyLegacy(key, policy->key_raw_ref);
}
if (!buildKeySpecifier(&arg->key_spec, *policy)) {
return false;
}
break;
case 2:
// v2策略的密钥由16字节的“identifier”指定,这是内核自身计算并返回的密钥本身的加密哈希。
// 用户提供的任何值都会被忽略;只需要设置说明符类型以表明正在添加这种类型的密钥。
arg->key_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
break;
default:
LOG(ERROR) << "Invalid encryption policy version: " << options.version;
return false;
}
arg->raw_size = key.size();
memcpy(arg->raw, key.data(), key.size());
if (!installFsKeyringKey(mountpoint, options, arg)) return false;
if (arg->key_spec.type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
// 检索内核计算的密钥标识符。
policy->key_raw_ref =
std::string((char*)arg->key_spec.u.identifier, FSCRYPT_KEY_IDENTIFIER_SIZE);
}
std::string ref = keyrefstring(policy->key_raw_ref);
LOG(DEBUG) << "Installed fscrypt key with ref " << ref << " to " << mountpoint;
if (!installProvisioningKey(key, ref, arg->key_spec)) return false;
return true;
}

1.18 KeyUtil::installKeyLegacy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// system/vold/KeyUtil.cpp
// 将类型为“logon”的加密密钥添加到全局会话密钥环。
static bool installKeyLegacy(const KeyBuffer& key, const std::string& raw_ref) {
// 将fscrypt_key放入自动归零缓冲区。
KeyBuffer fsKeyBuffer(sizeof(fscrypt_key));
fscrypt_key& fs_key = *reinterpret_cast<fscrypt_key*>(fsKeyBuffer.data());
if (!fillKey(key, &fs_key)) return false;
key_serial_t device_keyring;
if (!fscryptKeyring(&device_keyring)) return false;
for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
auto ref = buildLegacyKeyName(*name_prefix, raw_ref);
key_serial_t key_id =
add_key("logon", ref.c_str(), (void*)&fs_key, sizeof(fs_key), device_keyring);
if (key_id == -1) {
PLOG(ERROR) << "Failed to insert key into keyring " << device_keyring;
return false;
}
LOG(DEBUG) << "Added key " << key_id << " (" << ref << ") to keyring " << device_keyring
<< " in process " << getpid();
}
return true;
}

1.19 KeyUtil::installFsKeyringKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// system/vold/KeyUtil.cpp
// 将密钥安装到安装在挂载点上的文件系统的密钥环中。
// 填写密钥说明符负责调用arg->raw或arg->key_id。
// 如果arg->key_spec.type等于FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER,则arg-> ey_spec.u.identifier将使用内核生成的原始密钥引用进行填充。
static bool installFsKeyringKey(const std::string& mountpoint, const EncryptionOptions& options,
fscrypt_add_key_arg* arg) {
if (options.use_hw_wrapped_key) arg->flags |= FSCRYPT_ADD_KEY_FLAG_WRAPPED;
android::base::unique_fd fd(open(mountpoint.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
if (fd == -1) {
PLOG(ERROR) << "Failed to open " << mountpoint << " to install key";
return false;
}
if (ioctl(fd, FS_IOC_ADD_ENCRYPTION_KEY, arg) != 0) {
PLOG(ERROR) << "Failed to install fscrypt key to " << mountpoint;
return false;
}
return true;
}

1.20 KeyUtil::installProvisioningKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// system/vold/KeyUtil.cpp
// 将fscrypt-provisioning密钥安装到会话级内核密钥环中。
// 这样就可以将给定密钥重新安装到文件系统密钥环中。
static bool installProvisioningKey(const KeyBuffer& key, const std::string& ref,
const fscrypt_key_specifier& key_spec) {
key_serial_t device_keyring;
if (!fscryptKeyring(&device_keyring)) return false;
// 将fscrypt_provisioning_key_payload放入自动归零缓冲区。
KeyBuffer buf(sizeof(fscrypt_provisioning_key_payload) + key.size(), 0);
fscrypt_provisioning_key_payload& provisioning_key =
*reinterpret_cast<fscrypt_provisioning_key_payload*>(buf.data());
memcpy(provisioning_key.raw, key.data(), key.size());
provisioning_key.type = key_spec.type;
key_serial_t key_id = add_key("fscrypt-provisioning", ref.c_str(), (void*)&provisioning_key,
buf.size(), device_keyring);
if (key_id == -1) {
PLOG(ERROR) << "Failed to insert fscrypt-provisioning key for " << ref
<< " into session keyring";
return false;
}
LOG(DEBUG) << "Added fscrypt-provisioning key for " << ref << " to session keyring";
return true;
}

二、init_user0

2.1 do_init_user0

1
2
3
4
// system/core/init/builtins.cpp
static Result<void> do_init_user0(const BuiltinArguments& args) {
return ExecVdcRebootOnFailure("init_user0");
}

2.2 VoldNativeService::initUser0

1
2
3
4
5
6
// system/vold/VoldNativeService.cpp
binder::Status VoldNativeService::initUser0() {
ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_CRYPT_LOCK;
return translateBool(fscrypt_init_user0());
}

2.3 FsCrypt::fscrypt_init_user0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// system/vold/FsCrypt.cpp
bool fscrypt_init_user0() {
LOG(DEBUG) << "fscrypt_init_user0";
if (fscrypt_is_native()) {
// /data/misc/vold/user_keys root:root 0700
if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;
// /data/misc/vold/user_keys/ce root:root 0700
if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false;
// /data/misc/vold/user_keys/de root:root 0700
if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false;
if (!android::vold::pathExists(get_de_key_path(0))) {
if (!create_and_install_user_keys(0, false)) return false;
}
// 一旦框架明确调用为二级用户安装DE键,就切换到仅加载DE_0。
if (!load_all_de_keys()) return false;
}
// 只能在这里安全地准备DE存储,因为CE密钥可能与用户凭证纠缠在一起。一旦安装了CE密钥,框架将始终准备CE存储。
if (!fscrypt_prepare_user_storage("", 0, 0, android::os::IVold::STORAGE_FLAG_DE)) {
LOG(ERROR) << "Failed to prepare user 0 storage";
return false;
}
// 如果这是最近退出模拟器模式的非FBE设备,则将用户数据目录还原到已知良好状态。
// persist.sys.emulate_fbe=false
if (!fscrypt_is_native() && !fscrypt_is_emulated()) {
fscrypt_unlock_user_key(0, 0, "!", "!");
}
// 在某些情况下(重启用户空间),可能会在不进行硬重启的情况下卸载用户数据。如果CE密钥存储在fs密钥环中,则在卸载后它们将丢失。尝试重新安装它们。
if (fscrypt_is_native() && android::vold::isFsKeyringSupported()) {
if (!try_reload_ce_keys()) return false;
}
return true;
}

2.4 FsCrypt::create_and_install_user_keys

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// system/vold/FsCrypt.cpp
// 这假定只有一个线程在监听crypt命令,因为它在固定位置创建密钥。
static bool create_and_install_user_keys(userid_t user_id, bool create_ephemeral) {
EncryptionOptions options;
if (!get_data_file_encryption_options(&options)) return false;
KeyBuffer de_key, ce_key;
// 创建 DE key
if (!generateStorageKey(makeGen(options), &de_key)) return false;
// 创建 CE key
if (!generateStorageKey(makeGen(options), &ce_key)) return false;
if (create_ephemeral) {
// 如果所创建的 key 是临时的,则无需存储它。
s_ephemeral_users.insert(user_id);
} else {
// /data/misc/vold/user_keys/ce/$user_id root:root 0700
auto const directory_path = get_ce_key_directory_path(user_id);
if (!prepare_dir(directory_path, 0700, AID_ROOT, AID_ROOT)) return false;
auto const paths = get_ce_key_paths(directory_path);
std::string ce_key_path;
if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
// 将 ce key 存储到 /data/misc/vold/user_keys/temp
if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, kEmptyAuthentication,
ce_key))
return false;
fixate_user_ce_key(directory_path, ce_key_path, paths);
// 将 de key 存储到 /data/misc/vold/user_keys/temp
if (!android::vold::storeKeyAtomically(get_de_key_path(user_id), user_key_temp,
kEmptyAuthentication, de_key))
return false;
}
EncryptionPolicy de_policy;
// 将 de key 存储到 /data/
if (!install_storage_key(DATA_MNT_POINT, options, de_key, &de_policy)) return false;
s_de_policies[user_id] = de_policy;
EncryptionPolicy ce_policy;
// 将 ce key 存储到 /data/
if (!install_storage_key(DATA_MNT_POINT, options, ce_key, &ce_policy)) return false;
s_ce_policies[user_id] = ce_policy;
LOG(DEBUG) << "Created keys for user " << user_id;
return true;
}

2.5 FsCrypt::load_all_de_keys

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// system/vold/FsCrypt.cpp
static bool load_all_de_keys() {
EncryptionOptions options;
if (!get_data_file_encryption_options(&options)) return false;
// /data/misc/vold/user_keys/de
auto de_dir = user_key_dir + "/de";
auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(de_dir.c_str()), closedir);
if (!dirp) {
PLOG(ERROR) << "Unable to read de key directory";
return false;
}
for (;;) {
errno = 0;
auto entry = readdir(dirp.get());
if (!entry) {
if (errno) {
PLOG(ERROR) << "Unable to read de key directory";
return false;
}
break;
}
if (entry->d_type != DT_DIR || !is_numeric(entry->d_name)) {
LOG(DEBUG) << "Skipping non-de-key " << entry->d_name;
continue;
}
userid_t user_id = std::stoi(entry->d_name);
auto key_path = de_dir + "/" + entry->d_name;
KeyBuffer de_key;
if (!retrieveKey(key_path, kEmptyAuthentication, &de_key)) return false;
EncryptionPolicy de_policy;
if (!install_storage_key(DATA_MNT_POINT, options, de_key, &de_policy)) return false;
auto ret = s_de_policies.insert({user_id, de_policy});
if (!ret.second && ret.first->second != de_policy) {
LOG(ERROR) << "DE policy for user" << user_id << " changed";
return false;
}
LOG(DEBUG) << "Installed de key for user " << user_id;
}
// 遍历所有DE目录,确保所有用户目录都在其上设置了正确的策略,并且不存在流氓目录。
return true;
}

2.6 FsCrypt::fscrypt_prepare_user_storage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// system/vold/FsCrypt.cpp
bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
int flags) {
LOG(DEBUG) << "fscrypt_prepare_user_storage for volume " << escape_empty(volume_uuid)
<< ", user " << user_id << ", serial " << serial << ", flags " << flags;
if (flags & android::os::IVold::STORAGE_FLAG_DE) {
// DE_sys key
auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
// DE_n key
auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
if (volume_uuid.empty()) {
// /data/system/users/$user_id system:system 0700
if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
#if MANAGE_MISC_DIRS
// /data/misc/users/$user_id system:everybody 0750
if (!prepare_dir(misc_legacy_path, 0750, multiuser_get_uid(user_id, AID_SYSTEM),
multiuser_get_uid(user_id, AID_EVERYBODY)))
return false;
#endif
// /data/misc/profiles/$user_id system:system 0771
if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
// /data/system_de/$user_id system:system 071
if (!prepare_dir(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
// /data/misc_de/$user_id system:misc 0771
if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false;
// /data/vendor_de/$user_id system:root 0771
if (!prepare_dir(vendor_de_path, 0771, AID_ROOT, AID_ROOT)) return false;
}
// /data/user_de/$user_id system:system 0711
if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
if (fscrypt_is_native()) {
EncryptionPolicy de_policy;
if (volume_uuid.empty()) {
if (!lookup_policy(s_de_policies, user_id, &de_policy)) return false;
if (!EnsurePolicy(de_policy, system_de_path)) return false;
if (!EnsurePolicy(de_policy, misc_de_path)) return false;
if (!EnsurePolicy(de_policy, vendor_de_path)) return false;
} else {
if (!read_or_create_volkey(misc_de_path, volume_uuid, &de_policy)) return false;
}
if (!EnsurePolicy(de_policy, user_de_path)) return false;
}
}
if (flags & android::os::IVold::STORAGE_FLAG_CE) {
// CE_n key
auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
if (volume_uuid.empty()) {
if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false;
if (!prepare_dir(vendor_ce_path, 0771, AID_ROOT, AID_ROOT)) return false;
}
if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
if (fscrypt_is_native()) {
EncryptionPolicy ce_policy;
if (volume_uuid.empty()) {
if (!lookup_policy(s_ce_policies, user_id, &ce_policy)) return false;
if (!EnsurePolicy(ce_policy, system_ce_path)) return false;
if (!EnsurePolicy(ce_policy, misc_ce_path)) return false;
if (!EnsurePolicy(ce_policy, vendor_ce_path)) return false;
} else {
if (!read_or_create_volkey(misc_ce_path, volume_uuid, &ce_policy)) return false;
}
if (!EnsurePolicy(ce_policy, media_ce_path)) return false;
if (!EnsurePolicy(ce_policy, user_ce_path)) return false;
}
if (volume_uuid.empty()) {
// 现在已经安装了凭据,可以在这些路径上运行restorecon,这些路径需要与libselinux保持同步。
android::vold::RestoreconRecursive(system_ce_path);
android::vold::RestoreconRecursive(vendor_ce_path);
android::vold::RestoreconRecursive(misc_ce_path);
}
}
if (!prepare_subdirs("prepare", volume_uuid, user_id, flags)) return false;
return true;
}

2.7 FsCrypt::read_or_create_volkey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// system/vold/FsCrypt.cpp
static bool read_or_create_volkey(const std::string& misc_path, const std::string& volume_uuid,
EncryptionPolicy* policy) {
auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
std::string secdiscardable_hash;
if (android::vold::pathExists(secdiscardable_path)) {
if (!android::vold::readSecdiscardable(secdiscardable_path, &secdiscardable_hash))
return false;
} else {
if (fs_mkdirs(secdiscardable_path.c_str(), 0700) != 0) {
PLOG(ERROR) << "Creating directories for: " << secdiscardable_path;
return false;
}
if (!android::vold::createSecdiscardable(secdiscardable_path, &secdiscardable_hash))
return false;
}
auto key_path = volkey_path(misc_path, volume_uuid);
if (fs_mkdirs(key_path.c_str(), 0700) != 0) {
PLOG(ERROR) << "Creating directories for: " << key_path;
return false;
}
android::vold::KeyAuthentication auth("", secdiscardable_hash);
EncryptionOptions options;
if (!get_volume_file_encryption_options(&options)) return false;
KeyBuffer key;
if (!retrieveOrGenerateKey(key_path, key_path + "_tmp", auth, makeGen(options), &key))
return false;
if (!install_storage_key(BuildDataPath(volume_uuid), options, key, policy)) return false;
return true;
}

2.8 FsCrypt::fscrypt_unlock_user_key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// system/vold/FsCrypt.cpp
// 重命名为“install”以保持一致性,并带有标志以了解要安装的密钥。
bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& token_hex,
const std::string& secret_hex) {
LOG(DEBUG) << "fscrypt_unlock_user_key " << user_id << " serial=" << serial
<< " token_present=" << (token_hex != "!");
if (fscrypt_is_native()) {
if (s_ce_policies.count(user_id) != 0) {
LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
return true;
}
auto auth = authentication_from_hex(token_hex, secret_hex);
if (!auth) return false;
if (!read_and_install_user_ce_key(user_id, *auth)) {
LOG(ERROR) << "Couldn't read key for " << user_id;
return false;
}
} else {
// 在模拟器模式下,仅使用chmod。但是,当不处于模拟器模式时,还会解锁目录,以使设备恢复为正常状态。
if (!emulated_unlock(android::vold::BuildDataSystemCePath(user_id), 0771) ||
!emulated_unlock(android::vold::BuildDataMiscCePath(user_id), 01771) ||
!emulated_unlock(android::vold::BuildDataMediaCePath("", user_id), 0770) ||
!emulated_unlock(android::vold::BuildDataUserCePath("", user_id), 0771)) {
LOG(ERROR) << "Failed to unlock user " << user_id;
return false;
}
}
return true;
}

2.9 FsCrypt::read_and_install_user_ce_key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// system/vold/FsCrypt.cpp
static bool read_and_install_user_ce_key(userid_t user_id,
const android::vold::KeyAuthentication& auth) {
if (s_ce_policies.count(user_id) != 0) return true;
EncryptionOptions options;
if (!get_data_file_encryption_options(&options)) return false;
KeyBuffer ce_key;
if (!read_and_fixate_user_ce_key(user_id, auth, &ce_key)) return false;
EncryptionPolicy ce_policy;
if (!install_storage_key(DATA_MNT_POINT, options, ce_key, &ce_policy)) return false;
s_ce_policies[user_id] = ce_policy;
LOG(DEBUG) << "Installed ce key for user " << user_id;
return true;
}

2.10 FsCrypt::read_and_fixate_user_ce_key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// system/vold/FsCrypt.cpp
static bool read_and_fixate_user_ce_key(userid_t user_id,
const android::vold::KeyAuthentication& auth,
KeyBuffer* ce_key) {
auto const directory_path = get_ce_key_directory_path(user_id);
auto const paths = get_ce_key_paths(directory_path);
for (auto const ce_key_path : paths) {
LOG(DEBUG) << "Trying user CE key " << ce_key_path;
if (retrieveKey(ce_key_path, auth, ce_key)) {
LOG(DEBUG) << "Successfully retrieved key";
fixate_user_ce_key(directory_path, ce_key_path, paths);
return true;
}
}
LOG(ERROR) << "Failed to find working ce key for user " << user_id;
return false;
}

2.10 FsCrypt::try_reload_ce_keys

1
2
3
4
5
6
7
8
9
10
11
// system/vold/FsCrypt.cpp
// 尝试为认为已解锁的用户重新安装CE密钥。
static bool try_reload_ce_keys() {
for (const auto& it : s_ce_policies) {
if (!android::vold::reloadKeyFromSessionKeyring(DATA_MNT_POINT, it.second)) {
LOG(ERROR) << "Failed to load CE key from session keyring for user " << it.first;
return false;
}
}
return true;
}

三、unlockUserKey

3.1 StorageManagerService::Lifecycle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// frameworks/base/services/core/java/com/android/server/StorageManagerService.java
public static class Lifecycle extends SystemService {
private StorageManagerService mStorageManagerService;
public Lifecycle(Context context) {
super(context);
}
@Override
public void onStart() {
mStorageManagerService = new StorageManagerService(getContext());
publishBinderService("mount", mStorageManagerService);
mStorageManagerService.start();
}
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mStorageManagerService.servicesReady();
} else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mStorageManagerService.systemReady();
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mStorageManagerService.bootCompleted();
}
}
...
}

3.2 StorageManagerService::bootCompleted

1
2
3
4
5
6
// frameworks/base/services/core/java/com/android/server/StorageManagerService.java
private void bootCompleted() {
mBootCompleted = true;
mHandler.obtainMessage(H_BOOT_COMPLETED).sendToTarget();
updateFusePropFromSettings();
}

3.3 StorageManagerService::StorageManagerServiceHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// frameworks/base/services/core/java/com/android/server/StorageManagerService.java
class StorageManagerServiceHandler extends Handler {
public StorageManagerServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case H_SYSTEM_READY: {
handleSystemReady();
break;
}
case H_BOOT_COMPLETED: {
handleBootCompleted();
break;
}
case H_DAEMON_CONNECTED: {
handleDaemonConnected();
break;
}
...
}
}
}

3.4 StorageManagerService::handleBootCompleted

1
2
3
4
5
// frameworks/base/services/core/java/com/android/server/StorageManagerService.java
private void handleBootCompleted() {
initIfBootedAndConnected();
resetIfBootedAndConnected();
}

3.5 StorageManagerService::initIfBootedAndConnected

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// frameworks/base/services/core/java/com/android/server/StorageManagerService.java
private void initIfBootedAndConnected() {
Slog.d(TAG, "Thinking about init, mBootCompleted=" + mBootCompleted
+ ", mDaemonConnected=" + mDaemonConnected);
if (mBootCompleted && mDaemonConnected
&& !StorageManager.isFileEncryptedNativeOnly()) {
// 当启动没有 native 支持的设备时,需确保根据当前模拟器状态锁定或解锁用户目录。
final boolean initLocked = StorageManager.isFileEncryptedEmulatedOnly();
Slog.d(TAG, "Setting up emulation state, initlocked=" + initLocked);
final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
for (UserInfo user : users) {
try {
if (initLocked) {
mVold.lockUserKey(user.id);
} else {
mVold.unlockUserKey(user.id, user.serialNumber, encodeBytes(null),
encodeBytes(null));
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
}
}

3.6 StorageManagerService::unlockUserKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// frameworks/base/services/core/java/com/android/server/StorageManagerService.java
@Override
public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) {
boolean isFsEncrypted = StorageManager.isFileEncryptedNativeOrEmulated();
Slog.d(TAG, "unlockUserKey: " + userId
+ " isFileEncryptedNativeOrEmulated: " + isFsEncrypted
+ " hasToken: " + (token != null)
+ " hasSecret: " + (secret != null));
enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
if (isFsEncrypted) {
try {
mVold.unlockUserKey(userId, serialNumber, encodeBytes(token),
encodeBytes(secret));
} catch (Exception e) {
Slog.wtf(TAG, e);
return;
}
}
synchronized (mLock) {
mLocalUnlockedUsers.append(userId);
}
}

3.7 VoldNativeService::unlockUserKey

1
2
3
4
5
6
7
8
// system/vold/VoldNativeService.cpp
binder::Status VoldNativeService::unlockUserKey(int32_t userId, int32_t userSerial,
const std::string& token,
const std::string& secret) {
ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_CRYPT_LOCK;
return translateBool(fscrypt_unlock_user_key(userId, userSerial, token, secret));
}