ext4crypt: support wrappedkey for FBE
Qualcomm devices use a special `wrappedkey` mode for FBE. This is ported from CAF https://source.codeaurora.org/quic/la/platform/system/vold/commit/?h=LA.UM.7.8.r4-01000-SDM710.0&id=9229262d893a8592f7bc1b4e8a8dab7aad8df68c, originally by folks at Mokee for vold https://mokeedev.review/c/MoKee/android_system_vold/+/34102. This patch ports the above changes to `ext4crypt`, which we can use in recovery. Note that since we do not have `fs_mgr` in the recovery, we cannot read the `wrappedkey` flag from fstab. Instead, similar to `fbe.contents`, we use a special property `fbe.data.wrappedkey` to indicate support for wrappedkey mode. Devices that need to use this should set this property to `true` to activate corresponding code. Change-Id: I79c2855d577156670b45c10c7c7b1fcd9fece8d9
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include <keyutils.h>
|
||||
|
||||
#include "KeyStorage4.h"
|
||||
#include "Ext4CryptPie.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include <iostream>
|
||||
@@ -35,6 +36,11 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define MAX_USER_ID 0xFFFFFFFF
|
||||
|
||||
using android::hardware::keymaster::V4_0::KeyFormat;
|
||||
using android::vold::KeyType;
|
||||
|
||||
namespace android {
|
||||
namespace vold {
|
||||
|
||||
@@ -128,7 +134,14 @@ bool installKey(const KeyBuffer& key, std::string* raw_ref) {
|
||||
ext4_encryption_key &ext4_key = *reinterpret_cast<ext4_encryption_key*>(ext4KeyBuffer.data());
|
||||
|
||||
if (!fillKey(key, &ext4_key)) return false;
|
||||
*raw_ref = generateKeyRef(ext4_key.raw, ext4_key.size);
|
||||
if (is_wrapped_key_supported()) {
|
||||
/* When wrapped key is supported, only the first 32 bytes are
|
||||
the same per boot. The second 32 bytes can change as the ephemeral
|
||||
key is different. */
|
||||
*raw_ref = generateKeyRef(ext4_key.raw, (ext4_key.size)/2);
|
||||
} else {
|
||||
*raw_ref = generateKeyRef(ext4_key.raw, ext4_key.size);
|
||||
}
|
||||
key_serial_t device_keyring;
|
||||
if (!e4cryptKeyring(&device_keyring)) return false;
|
||||
for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
|
||||
@@ -171,7 +184,7 @@ bool evictKey(const std::string& raw_ref) {
|
||||
|
||||
bool retrieveAndInstallKey(bool create_if_absent, const KeyAuthentication& key_authentication,
|
||||
const std::string& key_path, const std::string& tmp_path,
|
||||
std::string* key_ref) {
|
||||
std::string* key_ref, bool wrapped_key_supported) {
|
||||
KeyBuffer key;
|
||||
if (pathExists(key_path)) {
|
||||
LOG(DEBUG) << "Key exists, using: " << key_path << std::endl;
|
||||
@@ -182,10 +195,23 @@ bool retrieveAndInstallKey(bool create_if_absent, const KeyAuthentication& key_a
|
||||
return false;
|
||||
}
|
||||
LOG(INFO) << "Creating new key in " << key_path << std::endl;
|
||||
if (!randomKey(&key)) return false;
|
||||
if (wrapped_key_supported) {
|
||||
if(!generateWrappedKey(MAX_USER_ID, KeyType::DE_SYS, &key)) return false;
|
||||
} else {
|
||||
if (!randomKey(&key)) return false;
|
||||
}
|
||||
if (!storeKeyAtomically(key_path, tmp_path, key_authentication, key)) return false;
|
||||
}
|
||||
|
||||
if (wrapped_key_supported) {
|
||||
KeyBuffer ephemeral_wrapped_key;
|
||||
if (!getEphemeralWrappedKey(KeyFormat::RAW, key, &ephemeral_wrapped_key)) {
|
||||
LOG(ERROR) << "Failed to export key in retrieveAndInstallKey";
|
||||
return false;
|
||||
}
|
||||
key = std::move(ephemeral_wrapped_key);
|
||||
}
|
||||
|
||||
if (!installKey(key, key_ref)) {
|
||||
LOG(ERROR) << "Failed to install key in " << key_path << std::endl;
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user