Merge RP1A.200123.001
Change-Id: Ibfa73fd7557ebaa4aa61105a5661d1036cf7b474
diff --git a/FsCrypt.cpp b/FsCrypt.cpp
index 0d4f02e..0020cf2 100644
--- a/FsCrypt.cpp
+++ b/FsCrypt.cpp
@@ -25,6 +25,7 @@
#include <algorithm>
#include <map>
+#include <optional>
#include <set>
#include <sstream>
#include <string>
@@ -92,8 +93,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
@@ -282,7 +281,6 @@
ce_key = std::move(ephemeral_wrapped_key);
}
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;
@@ -362,7 +360,6 @@
}
if (!install_data_key(de_key, &de_raw_ref)) return false;
if (!install_data_key(ce_key, &ce_raw_ref)) return false;
- s_ce_keys[user_id] = std::move(ce_key);
s_de_key_raw_refs[user_id] = de_raw_ref;
s_ce_key_raw_refs[user_id] = ce_raw_ref;
@@ -555,22 +552,6 @@
drop_caches_if_needed();
}
- if(is_wrapped_key_supported()) {
- KeyBuffer key;
- key = s_ce_keys[user_id];
-
- std::string keystr(key.data(), key.size());
- Keymaster keymaster;
-
- if (!keymaster) {
- s_ce_keys.erase(user_id);
- s_ce_key_raw_refs.erase(user_id);
- return false;
- }
- keymaster.deleteKey(keystr);
- }
-
- s_ce_keys.erase(user_id);
s_ce_key_raw_refs.erase(user_id);
return success;
}
@@ -644,6 +625,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";
}
@@ -689,44 +682,42 @@
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 const directory_path = get_ce_key_directory_path(user_id);
- auto const paths = get_ce_key_paths(directory_path);
-
- KeyBuffer ce_key;
- if(is_wrapped_key_supported()) {
- std::string ce_key_current_path = get_ce_key_current_path(directory_path);
- if (android::vold::retrieveKey(ce_key_current_path, kEmptyAuthentication, &ce_key)) {
- LOG(DEBUG) << "Successfully retrieved key";
- } else {
- if (android::vold::retrieveKey(ce_key_current_path, auth, &ce_key)) {
- LOG(DEBUG) << "Successfully retrieved key";
- }
- }
- } else {
- 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;
- }
- ce_key = it->second;
- }
-
- 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,
@@ -734,39 +725,9 @@
LOG(DEBUG) << "fscrypt_clear_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;
-
- if (is_wrapped_key_supported()) {
- auto const directory_path = get_ce_key_directory_path(user_id);
- auto const paths = get_ce_key_paths(directory_path);
-
- KeyBuffer ce_key;
- std::string ce_key_current_path = get_ce_key_current_path(directory_path);
-
- auto auth = android::vold::KeyAuthentication(token, secret);
- /* Retrieve key while removing a pin. A secret is needed */
- if (android::vold::retrieveKey(ce_key_current_path, auth, &ce_key)) {
- LOG(DEBUG) << "Successfully retrieved key";
- } else {
- /* Retrieve key when going None to swipe and vice versa when a
- synthetic password is present */
- if (android::vold::retrieveKey(ce_key_current_path, kEmptyAuthentication, &ce_key)) {
- LOG(DEBUG) << "Successfully retrieved key";
- }
- }
-
- 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, kEmptyAuthentication, ce_key))
- return false;
- } else {
- if(!fscrypt_add_user_key_auth(user_id, serial, "!", "!")) 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, *auth, kEmptyAuthentication);
}
bool fscrypt_fixate_newest_user_key_auth(userid_t user_id) {
@@ -793,11 +754,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;
}