Skip to content

Commit

Permalink
Detect factory reset and deleteAllKeys
Browse files Browse the repository at this point in the history
Where metadata encryption is enabled, if there is no metadata encryption
key present and we are generating one anew, then there has been a
factory reset, and this is the first key to be generated. We then call
deleteAllKeys to ensure data from before the factory reset is securely
deleted.

This shouldn't really be necessary; the factory reset call itself
should be doing this. However there are currently three factory reset
paths (settings, recovery, fastboot -w) and it is not clear that all
three are doing this correctly on all devices. Obviously an attacker
can prevent this code from being run by running a version of the OS
that does not include this change; however, if the bootloader is
locked, then keys will be version bound such that they will only work
on locked devices with a sufficiently recent version of the OS. If
every sufficiently recent signed version of the OS includes this change
the attack is defeated.

Bug: 187105270
Test: booted Cuttlefish twice, checked logs
Ignore-AOSP-First: no merge path to this branch from AOSP.
Merged-In: I9c5c547140e8b1bbffb9c1d215f75251f0f1354e
Change-Id: I9c5c547140e8b1bbffb9c1d215f75251f0f1354e
  • Loading branch information
ciphergoth committed Aug 11, 2021
1 parent 2ddc133 commit 0f74bd4
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
13 changes: 13 additions & 0 deletions Keymaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,5 +230,18 @@ void Keymaster::earlyBootEnded() {
logKeystore2ExceptionIfPresent(rc, "earlyBootEnded");
}

void Keymaster::deleteAllKeys() {
::ndk::SpAIBinder binder(AServiceManager_getService(maintenance_service_name));
auto maint_service = ks2_maint::IKeystoreMaintenance::fromBinder(binder);

if (!maint_service) {
LOG(ERROR) << "Unable to connect to keystore2 maintenance service for deleteAllKeys";
return;
}

auto rc = maint_service->deleteAllKeys();
logKeystore2ExceptionIfPresent(rc, "deleteAllKeys");
}

} // namespace vold
} // namespace android
3 changes: 3 additions & 0 deletions Keymaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ class Keymaster {
// be created or used.
static void earlyBootEnded();

// Tell all Keymint devices to delete all rollback-protected keys.
static void deleteAllKeys();

private:
std::shared_ptr<ks2::IKeystoreSecurityLevel> securityLevel;
DISALLOW_COPY_AND_ASSIGN(Keymaster);
Expand Down
11 changes: 11 additions & 0 deletions MetadataCrypt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ static bool read_key(const std::string& metadata_key_dir, const KeyGeneration& g
auto dir = metadata_key_dir + "/key";
LOG(DEBUG) << "metadata_key_dir/key: " << dir;
if (!MkdirsSync(dir, 0700)) return false;
if (!pathExists(dir)) {
auto delete_all = android::base::GetBoolProperty(
"ro.crypto.metadata_init_delete_all_keys.enabled", false);
if (delete_all) {
LOG(INFO) << "Metadata key does not exist, calling deleteAllKeys";
Keymaster::deleteAllKeys();
} else {
LOG(DEBUG) << "Metadata key does not exist but "
"ro.crypto.metadata_init_delete_all_keys.enabled is false";
}
}
auto temp = metadata_key_dir + "/tmp";
return retrieveOrGenerateKey(dir, temp, kEmptyAuthentication, gen, key);
}
Expand Down

0 comments on commit 0f74bd4

Please sign in to comment.