From 90edd2e867b238e71ee198e3460e289cd7dee54c Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Thu, 23 May 2019 16:32:22 +0800 Subject: 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 --- crypto/ext4crypt/KeyUtil.cpp | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'crypto/ext4crypt/KeyUtil.cpp') diff --git a/crypto/ext4crypt/KeyUtil.cpp b/crypto/ext4crypt/KeyUtil.cpp index 946c6cf9c..3dc05004c 100644 --- a/crypto/ext4crypt/KeyUtil.cpp +++ b/crypto/ext4crypt/KeyUtil.cpp @@ -27,6 +27,7 @@ #include #include "KeyStorage4.h" +#include "Ext4CryptPie.h" #include "Utils.h" #include @@ -35,6 +36,11 @@ #include #include +#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(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; -- cgit v1.2.3