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:
Peter Cai
2019-05-23 16:32:22 +08:00
committed by big biff
parent 69ab4a6000
commit 90edd2e867
8 changed files with 163 additions and 6 deletions

View File

@@ -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;