summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2020-06-15 09:30:51 -0700
committerEric Biggers <ebiggers@google.com>2020-06-16 13:49:02 -0700
commit31dcbfe436024f3c1ce9a66bfb5f073fdaa57cd9 (patch)
tree4fae320447846891d4d8ab76f5dfdaf522377dbc
parent40e8b1d4de8b3ed6c3bc512f935a366997033cd2 (diff)
downloadplatform_test_vts-testcase_kernel-31dcbfe436024f3c1ce9a66bfb5f073fdaa57cd9.tar.gz
platform_test_vts-testcase_kernel-31dcbfe436024f3c1ce9a66bfb5f073fdaa57cd9.tar.bz2
platform_test_vts-testcase_kernel-31dcbfe436024f3c1ce9a66bfb5f073fdaa57cd9.zip
VtsKernelEncryptionTest: fix skip condition for wrapped key test
TestAesInlineCryptOptimizedHwWrappedKeyPolicy can't run if the device's inline encryption hardware doesn't support 64-bit DUNs, even if it otherwise supports wrapped keys. We can detect this case by checking if creating a file in the encrypted directory fails with EINVAL. (See setup_per_mode_enc_key() in the Android common kernels.) While fixing this, tighten the checks in SetEncryptionPolicy() so that we only allow the tests to be skipped in the expected ways. Bug: 144046242 Bug: 153730132 Test: I don't have the hardware to properly test this, but there's no regression in 'atest vts_kernel_encryption_test' on Cuttlefish. Also tested on one other device. Change-Id: I48c69d81a58d1edf27c6a37fc30d91e21e76a530 Merged-In: I48c69d81a58d1edf27c6a37fc30d91e21e76a530
-rw-r--r--encryption/file_based_encryption_tests.cpp80
1 files changed, 53 insertions, 27 deletions
diff --git a/encryption/file_based_encryption_tests.cpp b/encryption/file_based_encryption_tests.cpp
index 45bbda5d..0120eed7 100644
--- a/encryption/file_based_encryption_tests.cpp
+++ b/encryption/file_based_encryption_tests.cpp
@@ -351,9 +351,9 @@ class FBEPolicyTest : public ::testing::Test {
bool required = true);
bool CreateAndSetHwWrappedKey(std::vector<uint8_t> *enc_key,
std::vector<uint8_t> *sw_secret);
- bool IsInoBasedEncryptionGuaranteed();
+ int GetSkipFlagsForInoBasedEncryption();
bool SetEncryptionPolicy(int contents_mode, int filenames_mode, int flags,
- bool required);
+ int skip_flags);
bool GenerateTestFile(TestFileInfo *info);
bool VerifyKeyIdentifier(const std::vector<uint8_t> &master_key);
bool DerivePerModeEncryptionKey(const std::vector<uint8_t> &master_key,
@@ -481,8 +481,15 @@ bool FBEPolicyTest::CreateAndSetHwWrappedKey(std::vector<uint8_t> *enc_key,
return true;
}
-// Returns true if encryption policies that include the inode number in the IVs
+enum {
+ kSkipIfNoPolicySupport = 1 << 0,
+ kSkipIfNoCryptoAPISupport = 1 << 1,
+ kSkipIfNoHardwareSupport = 1 << 2,
+};
+
+// Returns 0 if encryption policies that include the inode number in the IVs
// (e.g. IV_INO_LBLK_64) are guaranteed to be settable on the test filesystem.
+// Else returns kSkipIfNoPolicySupport.
//
// On f2fs, they're always settable. On ext4, they're only settable if the
// filesystem has the 'stable_inodes' feature flag. Android only sets
@@ -490,15 +497,17 @@ bool FBEPolicyTest::CreateAndSetHwWrappedKey(std::vector<uint8_t> *enc_key,
// real", e.g. "fileencryption=::inlinecrypt_optimized" in fstab. Since the
// fstab could contain something else, we have to allow the tests for these
// encryption policies to be skipped on ext4.
-bool FBEPolicyTest::IsInoBasedEncryptionGuaranteed() {
- return fs_info_.type != "ext4";
+int FBEPolicyTest::GetSkipFlagsForInoBasedEncryption() {
+ if (fs_info_.type == "ext4") return kSkipIfNoPolicySupport;
+ return 0;
}
// Sets a v2 encryption policy on the test directory. The policy will use the
-// test key and the specified encryption modes and flags. If required=false,
-// then a failure won't be added if the kernel doesn't support the policy.
+// test key and the specified encryption modes and flags. If the kernel doesn't
+// support setting or using the encryption policy, then a failure will be added,
+// unless the reason is covered by a bit set in |skip_flags|.
bool FBEPolicyTest::SetEncryptionPolicy(int contents_mode, int filenames_mode,
- int flags, bool required) {
+ int flags, int skip_flags) {
if (!key_added_) {
ADD_FAILURE() << "SetEncryptionPolicy called but no key added";
return false;
@@ -523,7 +532,7 @@ bool FBEPolicyTest::SetEncryptionPolicy(int contents_mode, int filenames_mode,
}
GTEST_LOG_(INFO) << "Setting encryption policy on " << kTestDir;
if (ioctl(dirfd, FS_IOC_SET_ENCRYPTION_POLICY, &policy) != 0) {
- if (errno == EINVAL && !required) {
+ if (errno == EINVAL && (skip_flags & kSkipIfNoPolicySupport)) {
GTEST_LOG_(INFO) << "Skipping test because encryption policy is "
"unsupported on this filesystem / kernel";
return false;
@@ -534,18 +543,29 @@ bool FBEPolicyTest::SetEncryptionPolicy(int contents_mode, int filenames_mode,
<< std::hex << flags << std::dec << Errno();
return false;
}
- if (!required) {
- // Setting an encryption policy that uses modes that aren't enabled in the
- // kernel's crypto API (e.g. FSCRYPT_MODE_ADIANTUM when the kernel lacks
- // CONFIG_CRYPTO_ADIANTUM) will still succeed, but actually creating a file
- // will fail with ENOPKG. Make sure to check for this case.
+ if (skip_flags & (kSkipIfNoCryptoAPISupport | kSkipIfNoHardwareSupport)) {
android::base::unique_fd fd(
open(kTestFile, O_WRONLY | O_CREAT | O_CLOEXEC, 0600));
- if (fd < 0 && errno == ENOPKG) {
- GTEST_LOG_(INFO)
- << "Skipping test because encryption policy is "
- "unsupported on this kernel, due to missing crypto API support";
- return false;
+ if (fd < 0) {
+ // Setting an encryption policy that uses modes that aren't enabled in the
+ // kernel's crypto API (e.g. FSCRYPT_MODE_ADIANTUM when the kernel lacks
+ // CONFIG_CRYPTO_ADIANTUM) will still succeed, but actually creating a
+ // file will fail with ENOPKG. Make sure to check for this case.
+ if (errno == ENOPKG && (skip_flags & kSkipIfNoCryptoAPISupport)) {
+ GTEST_LOG_(INFO)
+ << "Skipping test because encryption policy is "
+ "unsupported on this kernel, due to missing crypto API support";
+ return false;
+ }
+ // We get EINVAL here when using a hardware-wrapped key and the inline
+ // encryption hardware supports wrapped keys but doesn't support the
+ // number of DUN bytes that the file contents encryption requires.
+ if (errno == EINVAL && (skip_flags & kSkipIfNoHardwareSupport)) {
+ GTEST_LOG_(INFO)
+ << "Skipping test because encryption policy is not compatible with "
+ "this device's inline encryption hardware";
+ return false;
+ }
}
unlink(kTestFile);
}
@@ -743,7 +763,7 @@ TEST_F(FBEPolicyTest, TestAesPerFileKeysPolicy) {
ASSERT_TRUE(SetMasterKey(master_key));
if (!SetEncryptionPolicy(FSCRYPT_MODE_AES_256_XTS, FSCRYPT_MODE_AES_256_CTS,
- 0, true))
+ 0, 0))
return;
TestFileInfo file_info;
@@ -769,7 +789,7 @@ TEST_F(FBEPolicyTest, TestAesInlineCryptOptimizedPolicy) {
if (!SetEncryptionPolicy(FSCRYPT_MODE_AES_256_XTS, FSCRYPT_MODE_AES_256_CTS,
FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64,
- IsInoBasedEncryptionGuaranteed()))
+ GetSkipFlagsForInoBasedEncryption()))
return;
TestFileInfo file_info;
@@ -795,9 +815,11 @@ TEST_F(FBEPolicyTest, TestAesInlineCryptOptimizedHwWrappedKeyPolicy) {
std::vector<uint8_t> enc_key, sw_secret;
if (!CreateAndSetHwWrappedKey(&enc_key, &sw_secret)) return;
- if (!SetEncryptionPolicy(FSCRYPT_MODE_AES_256_XTS, FSCRYPT_MODE_AES_256_CTS,
- FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64,
- IsInoBasedEncryptionGuaranteed()))
+ if (!SetEncryptionPolicy(
+ FSCRYPT_MODE_AES_256_XTS, FSCRYPT_MODE_AES_256_CTS,
+ FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64,
+ // 64-bit DUN support is not guaranteed.
+ kSkipIfNoHardwareSupport | GetSkipFlagsForInoBasedEncryption()))
return;
TestFileInfo file_info;
@@ -907,7 +929,7 @@ TEST_F(FBEPolicyTest, TestAesEmmcOptimizedPolicy) {
if (!SetEncryptionPolicy(FSCRYPT_MODE_AES_256_XTS, FSCRYPT_MODE_AES_256_CTS,
FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32,
- IsInoBasedEncryptionGuaranteed()))
+ GetSkipFlagsForInoBasedEncryption()))
return;
TestFileInfo file_info;
@@ -937,7 +959,7 @@ TEST_F(FBEPolicyTest, TestAesEmmcOptimizedHwWrappedKeyPolicy) {
if (!SetEncryptionPolicy(FSCRYPT_MODE_AES_256_XTS, FSCRYPT_MODE_AES_256_CTS,
FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32,
- IsInoBasedEncryptionGuaranteed()))
+ GetSkipFlagsForInoBasedEncryption()))
return;
TestFileInfo file_info;
@@ -960,8 +982,12 @@ TEST_F(FBEPolicyTest, TestAdiantumPolicy) {
// Adiantum support isn't required (since CONFIG_CRYPTO_ADIANTUM can be unset
// in the kernel config), so we may skip the test here.
+ //
+ // We don't need to use GetSkipFlagsForInoBasedEncryption() here, since the
+ // "DIRECT_KEY" IV generation method doesn't include inode numbers in the IVs.
if (!SetEncryptionPolicy(FSCRYPT_MODE_ADIANTUM, FSCRYPT_MODE_ADIANTUM,
- FSCRYPT_POLICY_FLAG_DIRECT_KEY, false))
+ FSCRYPT_POLICY_FLAG_DIRECT_KEY,
+ kSkipIfNoCryptoAPISupport))
return;
TestFileInfo file_info;