vold: Support Storage keys for FBE
To prevent keys from being compromised if an attacker
acquires read access to kernel memory, some inline
encryption hardware supports protecting the keys in
hardware without software having access to or the
ability to set the plaintext keys. Instead, software
only sees "wrapped keys", which may differ on every boot.
'wrappedkey_v0' fileencryption flag is used to denote
that the device supports inline encryption hardware that
supports this feature. On such devices keymaster is used
to generate keys with STORAGE_KEY tag and export a
per-boot ephemerally wrapped storage key to install it in
the kernel.
The wrapped key framework in the linux kernel ensures the
wrapped key is provided to the inline encryption hardware
where it is unwrapped and the file contents key is derived
to encrypt contents without revealing the plaintext key in
the clear.
Test: FBE validation with Fscrypt v2 + inline crypt + wrapped
key changes kernel.
Bug: 147733587
Change-Id: I1f0de61b56534ec1df9baef075acb74bacd00758
diff --git a/KeyUtil.cpp b/KeyUtil.cpp
index d4a653b..ae4d70b 100644
--- a/KeyUtil.cpp
+++ b/KeyUtil.cpp
@@ -29,6 +29,7 @@
#include <android-base/logging.h>
#include <keyutils.h>
+#include <fscrypt_uapi.h>
#include "KeyStorage.h"
#include "Utils.h"
@@ -45,6 +46,13 @@
return true;
}
+bool generateStorageKey(const EncryptionOptions& options, KeyBuffer* key) {
+ if (options.use_hw_wrapped_key) {
+ return generateWrappedStorageKey(key);
+ }
+ return randomKey(key);
+}
+
// Return true if the kernel supports the ioctls to add/remove fscrypt keys
// directly to/from the filesystem.
bool isFsKeyringSupported(void) {
@@ -222,6 +230,7 @@
return false;
}
+ if (options.use_hw_wrapped_key) arg->flags |= FSCRYPT_ADD_KEY_FLAG_WRAPPED;
// Provide the raw key.
arg->raw_size = key.size();
memcpy(arg->raw, key.data(), key.size());
@@ -307,8 +316,8 @@
}
bool retrieveKey(bool create_if_absent, const KeyAuthentication& key_authentication,
- const std::string& key_path, const std::string& tmp_path, KeyBuffer* key,
- bool keepOld) {
+ const std::string& key_path, const std::string& tmp_path,
+ const EncryptionOptions& options, KeyBuffer* key, bool keepOld) {
if (pathExists(key_path)) {
LOG(DEBUG) << "Key exists, using: " << key_path;
if (!retrieveKey(key_path, key_authentication, key, keepOld)) return false;
@@ -318,7 +327,7 @@
return false;
}
LOG(INFO) << "Creating new key in " << key_path;
- if (!randomKey(key)) return false;
+ if (!generateStorageKey(options, key)) return false;
if (!storeKeyAtomically(key_path, tmp_path, key_authentication, *key)) return false;
}
return true;