vold: Do not cache CE keys in vold
CE keys were cached in vold to support untrusted reset
by a device admin, this is now supported by Locksettingservice
using synthetic password. This change requires a secret to be
provided to retrieve the CE key and re-wrap without the secret
when user removes the credential.
Test: Set credential, remove credential, swipe to none
and vice-versa.
Bug: 26948053
Merged-In: I4cb1c035a472477e70c1ff5bf0b2c3fcfad495e5
Change-Id: I4cb1c035a472477e70c1ff5bf0b2c3fcfad495e5
diff --git a/FsCrypt.cpp b/FsCrypt.cpp
index c101ba8..603362f 100644
--- a/FsCrypt.cpp
+++ b/FsCrypt.cpp
@@ -23,6 +23,7 @@
#include <algorithm>
#include <map>
+#include <optional>
#include <set>
#include <sstream>
#include <string>
@@ -88,8 +89,6 @@
// Map user ids to key references
std::map<userid_t, std::string> s_de_key_raw_refs;
std::map<userid_t, std::string> s_ce_key_raw_refs;
-// TODO abolish this map, per b/26948053
-std::map<userid_t, KeyBuffer> s_ce_keys;
} // namespace
@@ -243,7 +242,6 @@
if (!read_and_fixate_user_ce_key(user_id, auth, &ce_key)) return false;
std::string ce_raw_ref;
if (!install_data_key(ce_key, &ce_raw_ref)) return false;
- s_ce_keys[user_id] = std::move(ce_key);
s_ce_key_raw_refs[user_id] = ce_raw_ref;
LOG(DEBUG) << "Installed ce key for user " << user_id;
return true;
@@ -296,7 +294,6 @@
s_de_key_raw_refs[user_id] = de_raw_ref;
std::string ce_raw_ref;
if (!install_data_key(ce_key, &ce_raw_ref)) return false;
- s_ce_keys[user_id] = ce_key;
s_ce_key_raw_refs[user_id] = ce_raw_ref;
LOG(DEBUG) << "Created keys for user " << user_id;
return true;
@@ -468,7 +465,6 @@
}
static bool evict_ce_key(userid_t user_id) {
- s_ce_keys.erase(user_id);
bool success = true;
std::string raw_ref;
// If we haven't loaded the CE key, no need to evict it.
@@ -549,6 +545,18 @@
return true;
}
+static std::optional<android::vold::KeyAuthentication> authentication_from_hex(
+ const std::string& token_hex, const std::string& secret_hex) {
+ std::string token, secret;
+ if (!parse_hex(token_hex, &token)) return std::optional<android::vold::KeyAuthentication>();
+ if (!parse_hex(secret_hex, &secret)) return std::optional<android::vold::KeyAuthentication>();
+ if (secret.empty()) {
+ return kEmptyAuthentication;
+ } else {
+ return android::vold::KeyAuthentication(token, secret);
+ }
+}
+
static std::string volkey_path(const std::string& misc_path, const std::string& volume_uuid) {
return misc_path + "/vold/volume_keys/" + volume_uuid + "/default";
}
@@ -592,30 +600,51 @@
return android::vold::destroyKey(path);
}
+static bool fscrypt_rewrap_user_key(userid_t user_id, int serial,
+ const android::vold::KeyAuthentication& retrieve_auth,
+ const android::vold::KeyAuthentication& store_auth) {
+ if (s_ephemeral_users.count(user_id) != 0) return true;
+ auto const directory_path = get_ce_key_directory_path(user_id);
+ KeyBuffer ce_key;
+ std::string ce_key_current_path = get_ce_key_current_path(directory_path);
+ if (android::vold::retrieveKey(ce_key_current_path, retrieve_auth, &ce_key)) {
+ LOG(DEBUG) << "Successfully retrieved key";
+ // TODO(147732812): Remove this once Locksettingservice is fixed.
+ // Currently it calls fscrypt_clear_user_key_auth with a secret when lockscreen is
+ // changed from swipe to none or vice-versa
+ } else if (android::vold::retrieveKey(ce_key_current_path, kEmptyAuthentication, &ce_key)) {
+ LOG(DEBUG) << "Successfully retrieved key with empty auth";
+ } else {
+ LOG(ERROR) << "Failed to retrieve key for user " << user_id;
+ 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;
+ if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, store_auth, ce_key))
+ return false;
+ if (!android::vold::FsyncDirectory(directory_path)) return false;
+ return true;
+}
+
bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
const std::string& secret_hex) {
LOG(DEBUG) << "fscrypt_add_user_key_auth " << user_id << " serial=" << serial
<< " token_present=" << (token_hex != "!");
if (!fscrypt_is_native()) return true;
- if (s_ephemeral_users.count(user_id) != 0) return true;
- std::string token, secret;
- if (!parse_hex(token_hex, &token)) return false;
- if (!parse_hex(secret_hex, &secret)) return false;
- auto auth =
- secret.empty() ? kEmptyAuthentication : android::vold::KeyAuthentication(token, secret);
- auto it = s_ce_keys.find(user_id);
- if (it == s_ce_keys.end()) {
- LOG(ERROR) << "Key not loaded into memory, can't change for user " << user_id;
- return false;
- }
- const auto& ce_key = it->second;
- auto const directory_path = get_ce_key_directory_path(user_id);
- 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;
- if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, auth, ce_key)) return false;
- if (!android::vold::FsyncDirectory(directory_path)) return false;
- return true;
+ auto auth = authentication_from_hex(token_hex, secret_hex);
+ if (!auth) return false;
+ return fscrypt_rewrap_user_key(user_id, serial, kEmptyAuthentication, *auth);
+}
+
+bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
+ const std::string& secret_hex) {
+ LOG(DEBUG) << "fscrypt_clear_user_key_auth " << user_id << " serial=" << serial
+ << " token_present=" << (token_hex != "!");
+ if (!fscrypt_is_native()) return true;
+ auto auth = authentication_from_hex(token_hex, secret_hex);
+ if (!auth) return false;
+ return fscrypt_rewrap_user_key(user_id, serial, *auth, kEmptyAuthentication);
}
bool fscrypt_fixate_newest_user_key_auth(userid_t user_id) {
@@ -642,11 +671,9 @@
LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
return true;
}
- std::string token, secret;
- if (!parse_hex(token_hex, &token)) return false;
- if (!parse_hex(secret_hex, &secret)) return false;
- android::vold::KeyAuthentication auth(token, secret);
- if (!read_and_install_user_ce_key(user_id, auth)) {
+ 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;
}
diff --git a/FsCrypt.h b/FsCrypt.h
index 03ec2e1..641991a 100644
--- a/FsCrypt.h
+++ b/FsCrypt.h
@@ -25,6 +25,8 @@
bool fscrypt_destroy_user_key(userid_t user_id);
bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token,
const std::string& secret);
+bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token,
+ const std::string& secret);
bool fscrypt_fixate_newest_user_key_auth(userid_t user_id);
bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& token,
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index cc32820..6af34d9 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -761,6 +761,15 @@
return translateBool(fscrypt_add_user_key_auth(userId, userSerial, token, secret));
}
+binder::Status VoldNativeService::clearUserKeyAuth(int32_t userId, int32_t userSerial,
+ const std::string& token,
+ const std::string& secret) {
+ ENFORCE_SYSTEM_OR_ROOT;
+ ACQUIRE_CRYPT_LOCK;
+
+ return translateBool(fscrypt_clear_user_key_auth(userId, userSerial, token, secret));
+}
+
binder::Status VoldNativeService::fixateNewestUserKeyAuth(int32_t userId) {
ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_CRYPT_LOCK;
diff --git a/VoldNativeService.h b/VoldNativeService.h
index 0718263..18551f2 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -112,6 +112,8 @@
binder::Status addUserKeyAuth(int32_t userId, int32_t userSerial, const std::string& token,
const std::string& secret);
+ binder::Status clearUserKeyAuth(int32_t userId, int32_t userSerial, const std::string& token,
+ const std::string& secret);
binder::Status fixateNewestUserKeyAuth(int32_t userId);
binder::Status unlockUserKey(int32_t userId, int32_t userSerial, const std::string& token,
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index 681e9dc..a454bd1 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -90,6 +90,8 @@
void addUserKeyAuth(int userId, int userSerial, @utf8InCpp String token,
@utf8InCpp String secret);
+ void clearUserKeyAuth(int userId, int userSerial, @utf8InCpp String token,
+ @utf8InCpp String secret);
void fixateNewestUserKeyAuth(int userId);
void unlockUserKey(int userId, int userSerial, @utf8InCpp String token,