diff --git a/crypto/fscrypt/FsCrypt.cpp b/crypto/fscrypt/FsCrypt.cpp index 3f388d39..aa31fe1e 100755 --- a/crypto/fscrypt/FsCrypt.cpp +++ b/crypto/fscrypt/FsCrypt.cpp @@ -247,6 +247,10 @@ static bool get_data_file_encryption_options(EncryptionOptions* options) { << entry->encryption_options; return false; } + if (options->version == 1) { + options->use_hw_wrapped_key = + GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT)->fs_mgr_flags.wrapped_key; + } if ((options->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) && !IsEmmcStorage(entry->blk_device)) { LOG(ERROR) << "The emmc_optimized encryption flag is only allowed on eMMC storage. Remove " @@ -294,6 +298,14 @@ static bool get_volume_file_encryption_options(EncryptionOptions* options) { return true; } +bool is_metadata_wrapped_key_supported() { + if (!ReadDefaultFstab(&fstab_default)) { + PLOG(ERROR) << "Failed to open default fstab"; + return false; + } + return GetEntryForMountPoint(&fstab_default, METADATA_MNT_POINT)->fs_mgr_flags.wrapped_key; +} + static bool read_and_install_user_ce_key(userid_t user_id, const ::KeyAuthentication& auth) { if (s_ce_policies.count(user_id) != 0) return true; diff --git a/crypto/fscrypt/FsCrypt.h b/crypto/fscrypt/FsCrypt.h index f6db4b96..0cb38c1e 100755 --- a/crypto/fscrypt/FsCrypt.h +++ b/crypto/fscrypt/FsCrypt.h @@ -39,6 +39,7 @@ bool fscrypt_lock_user_key(userid_t user_id); bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial, int flags); +bool is_metadata_wrapped_key_supported(); bool fscrypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags); bool fscrypt_destroy_volume_keys(const std::string& volume_uuid); diff --git a/crypto/fscrypt/KeyStorage.cpp b/crypto/fscrypt/KeyStorage.cpp index 83800ce5..edb23a27 100755 --- a/crypto/fscrypt/KeyStorage.cpp +++ b/crypto/fscrypt/KeyStorage.cpp @@ -138,8 +138,11 @@ bool generateWrappedStorageKey(KeyBuffer* key) { if (!keymaster) return false; std::string key_temp; auto paramBuilder = km::AuthorizationSetBuilder().AesEncryptionKey(AES_KEY_BYTES * 8); - paramBuilder.Authorization(km::TAG_ROLLBACK_RESISTANCE); - paramBuilder.Authorization(km::TAG_STORAGE_KEY); + km::KeyParameter param1; + param1.tag = static_cast<::android::hardware::keymaster::V4_0::Tag>( + android::hardware::keymaster::V4_0::KM_TAG_FBE_ICE); + param1.f.boolValue = true; + paramBuilder.push_back(param1); if (!keymaster.generateKey(paramBuilder, &key_temp)) return false; *key = KeyBuffer(key_temp.size()); memcpy(reinterpret_cast(key->data()), key_temp.c_str(), key->size()); diff --git a/crypto/fscrypt/KeyUtil.cpp b/crypto/fscrypt/KeyUtil.cpp index 8ec389f7..b7119a6d 100755 --- a/crypto/fscrypt/KeyUtil.cpp +++ b/crypto/fscrypt/KeyUtil.cpp @@ -31,6 +31,7 @@ #include #include +#include "FsCrypt.h" #include "KeyStorage.h" #include "Utils.h" @@ -273,7 +274,14 @@ bool installKey(const std::string& mountpoint, const EncryptionOptions& options, // A key for a v1 policy is specified by an arbitrary 8-byte // "descriptor", which must be provided by userspace. We use the // first 8 bytes from the double SHA-512 of the key itself. - policy->key_raw_ref = generateKeyRef((const uint8_t*)key.data(), key.size()); + if (options.use_hw_wrapped_key) { + // 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. + policy->key_raw_ref = generateKeyRef((const uint8_t*)key.data(), key.size()/2); + } else { + policy->key_raw_ref = generateKeyRef((const uint8_t*)key.data(), key.size()); + } if (!isFsKeyringSupported()) { return installKeyLegacy(key, policy->key_raw_ref); } diff --git a/crypto/fscrypt/MetadataCrypt.cpp b/crypto/fscrypt/MetadataCrypt.cpp index 1504367a..b53ecd41 100755 --- a/crypto/fscrypt/MetadataCrypt.cpp +++ b/crypto/fscrypt/MetadataCrypt.cpp @@ -39,6 +39,7 @@ #include "Checkpoint.h" #include "CryptoType.h" #include "EncryptInplace.h" +#include "FsCrypt.h" #include "KeyStorage.h" #include "KeyUtil.h" #include "Keymaster.h" @@ -306,6 +307,10 @@ bool fscrypt_mount_metadata_encrypted(const std::string& blk_device, const std:: } options.cipher = legacy_aes_256_xts; options.use_legacy_options_format = true; + if (is_metadata_wrapped_key_supported()) { + options.use_hw_wrapped_key = true; + LOG(INFO) << "metadata_wrapped_key_true"; + } options.set_dun = android::base::GetBoolProperty("ro.crypto.set_dun", false); if (!options.set_dun && data_rec->fs_mgr_flags.checkpoint_blk) { LOG(ERROR) diff --git a/crypto/fscrypt/VoldUtil.h b/crypto/fscrypt/VoldUtil.h index ce6b411f..e0945bf3 100644 --- a/crypto/fscrypt/VoldUtil.h +++ b/crypto/fscrypt/VoldUtil.h @@ -21,3 +21,4 @@ extern android::fs_mgr::Fstab fstab_default; #define DATA_MNT_POINT "/data" +#define METADATA_MNT_POINT "/metadata" diff --git a/twrp.cpp b/twrp.cpp index 5f743d40..6de0e627 100644 --- a/twrp.cpp +++ b/twrp.cpp @@ -294,7 +294,6 @@ int main(int argc, char **argv) { // Recovery needs to install world-readable files, so clear umask // set by init umask(0); - Log_Offset = 0; // Set up temporary log file (/tmp/recovery.log)