diff --git a/FsCrypt.cpp b/FsCrypt.cpp index 2be685f..61f62cd 100644 --- a/FsCrypt.cpp +++ b/FsCrypt.cpp @@ -278,6 +278,10 @@ static bool init_data_file_encryption_options() { "this flag from the device's fstab"; return false; } + if (s_data_options.version == 1) { + s_data_options.use_hw_wrapped_key = + GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT)->fs_mgr_flags.wrapped_key; + } return true; } diff --git a/KeyStorage.cpp b/KeyStorage.cpp index 5090b4e..650222c 100644 --- a/KeyStorage.cpp +++ b/KeyStorage.cpp @@ -65,6 +65,8 @@ static const char* kFn_secdiscardable = "secdiscardable"; static const char* kFn_version = "version"; // Note: old key directories may contain a file named "stretching". +static const int32_t KM_TAG_FBE_ICE = static_cast(7 << 28) | 16201; + namespace { // Storage binding info for ensuring key encryption keys include a @@ -139,6 +141,12 @@ bool generateWrappedStorageKey(KeyBuffer* key) { std::string key_temp; auto paramBuilder = km::AuthorizationSetBuilder().AesEncryptionKey(AES_KEY_BYTES * 8); paramBuilder.Authorization(km::TAG_STORAGE_KEY); + + km::KeyParameter param1; + param1.tag = (km::Tag) (KM_TAG_FBE_ICE); + param1.value = km::KeyParameterValue::make(true); + paramBuilder.push_back(param1); + if (!keystore.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/KeyUtil.cpp b/KeyUtil.cpp index bd2ccdd..b6fb9e0 100644 --- a/KeyUtil.cpp +++ b/KeyUtil.cpp @@ -143,7 +143,17 @@ 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); + } if (!buildKeySpecifier(&arg->key_spec, *policy)) { return false; }