From: Paul Crowley Date: Fri, 25 Oct 2019 17:28:53 +0000 (-0700) Subject: libfscrypt: Infer flags at parse time and include in options struct X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=22eb1d426f460c4c1a452d89cf02704ef85fe009;p=android-x86%2Fsystem-extras.git libfscrypt: Infer flags at parse time and include in options struct Bug: 143307095 Test: cuttlefish, policy=v1 -> flags=0, policy=v2 -> flags=2 Change-Id: I28f35a1e0ee474d07e2e2b591c84e9057ecb6acf --- diff --git a/libfscrypt/fscrypt.cpp b/libfscrypt/fscrypt.cpp index b73f1bc8..33c8249a 100644 --- a/libfscrypt/fscrypt.cpp +++ b/libfscrypt/fscrypt.cpp @@ -150,31 +150,6 @@ void BytesToHex(const std::string& bytes, std::string* hex) { } } -static uint8_t fscrypt_get_policy_flags(const EncryptionOptions& options) { - uint8_t flags = 0; - - // In the original setting of v1 policies and AES-256-CTS we used 4-byte - // padding of filenames, so we have to retain that for compatibility. - // - // For everything else, use 16-byte padding. This is more secure (it helps - // hide the length of filenames), and it makes the inputs evenly divisible - // into cipher blocks which is more efficient for encryption and decryption. - if (options.version == 1 && options.filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS) { - flags |= FS_POLICY_FLAGS_PAD_4; - } else { - flags |= FS_POLICY_FLAGS_PAD_16; - } - - // Use DIRECT_KEY for Adiantum, since it's much more efficient but just as - // secure since Android doesn't reuse the same master key for multiple - // encryption modes. - if (options.filenames_mode == FS_ENCRYPTION_MODE_ADIANTUM) { - flags |= FS_POLICY_FLAG_DIRECT_KEY; - } - - return flags; -} - static bool fscrypt_is_encrypted(int fd) { fscrypt_policy_v1 policy; @@ -238,6 +213,26 @@ bool ParseOptions(const std::string& options_string, EncryptionOptions* options) } else { options->version = 1; } + options->flags = 0; + + // In the original setting of v1 policies and AES-256-CTS we used 4-byte + // padding of filenames, so we have to retain that for compatibility. + // + // For everything else, use 16-byte padding. This is more secure (it helps + // hide the length of filenames), and it makes the inputs evenly divisible + // into cipher blocks which is more efficient for encryption and decryption. + if (options->version == 1 && options->filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS) { + options->flags |= FS_POLICY_FLAGS_PAD_4; + } else { + options->flags |= FS_POLICY_FLAGS_PAD_16; + } + + // Use DIRECT_KEY for Adiantum, since it's much more efficient but just as + // secure since Android doesn't reuse the same master key for multiple + // encryption modes. + if (options->filenames_mode == FS_ENCRYPTION_MODE_ADIANTUM) { + options->flags |= FS_POLICY_FLAG_DIRECT_KEY; + } return true; } @@ -248,6 +243,7 @@ static std::string PolicyDebugString(const EncryptionPolicy& policy) { ss << ref_hex; ss << " v" << policy.options.version; ss << " modes " << policy.options.contents_mode << "/" << policy.options.filenames_mode; + ss << std::hex << " flags 0x" << policy.options.flags; return ss.str(); } @@ -270,7 +266,7 @@ bool EnsurePolicy(const EncryptionPolicy& policy, const std::string& directory) kern_policy.v1.version = FSCRYPT_POLICY_V1; kern_policy.v1.contents_encryption_mode = policy.options.contents_mode; kern_policy.v1.filenames_encryption_mode = policy.options.filenames_mode; - kern_policy.v1.flags = fscrypt_get_policy_flags(policy.options); + kern_policy.v1.flags = policy.options.flags; policy.key_raw_ref.copy(reinterpret_cast(kern_policy.v1.master_key_descriptor), FSCRYPT_KEY_DESCRIPTOR_SIZE); break; @@ -283,7 +279,7 @@ bool EnsurePolicy(const EncryptionPolicy& policy, const std::string& directory) kern_policy.v2.version = FSCRYPT_POLICY_V2; kern_policy.v2.contents_encryption_mode = policy.options.contents_mode; kern_policy.v2.filenames_encryption_mode = policy.options.filenames_mode; - kern_policy.v2.flags = fscrypt_get_policy_flags(policy.options); + kern_policy.v2.flags = policy.options.flags; policy.key_raw_ref.copy(reinterpret_cast(kern_policy.v2.master_key_identifier), FSCRYPT_KEY_IDENTIFIER_SIZE); break; diff --git a/libfscrypt/include/fscrypt/fscrypt.h b/libfscrypt/include/fscrypt/fscrypt.h index 47fedb5c..ca051f4a 100644 --- a/libfscrypt/include/fscrypt/fscrypt.h +++ b/libfscrypt/include/fscrypt/fscrypt.h @@ -33,7 +33,9 @@ struct EncryptionOptions { int version; int contents_mode; int filenames_mode; + int flags; + // Ensure that "version" is not valid on creation and so must be explicitly set EncryptionOptions() : version(0) {} }; diff --git a/libfscrypt/tests/fscrypt_test.cpp b/libfscrypt/tests/fscrypt_test.cpp index 13a37b76..48d092df 100644 --- a/libfscrypt/tests/fscrypt_test.cpp +++ b/libfscrypt/tests/fscrypt_test.cpp @@ -37,6 +37,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(1, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string); @@ -44,6 +45,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(1, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string); @@ -51,6 +53,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(1, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16 | FS_POLICY_FLAG_DIRECT_KEY, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("adiantum:adiantum:v1", options_string); @@ -58,6 +61,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(1, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_HEH, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("adiantum:aes-256-heh:v1", options_string); @@ -65,6 +69,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(1, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_PRIVATE, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("ice:aes-256-cts:v1", options_string); @@ -74,6 +79,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(1, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_PRIVATE, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("ice:aes-256-cts:v1", options_string); @@ -81,6 +87,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(1, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_PRIVATE, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_HEH, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("ice:aes-256-heh:v1", options_string); @@ -88,6 +95,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(1, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_PRIVATE, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16 | FS_POLICY_FLAG_DIRECT_KEY, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("ice:adiantum:v1", options_string); @@ -95,6 +103,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(1, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string); @@ -102,6 +111,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(1, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string); @@ -109,6 +119,7 @@ TEST(fscrypt, ParseOptions) { EXPECT_EQ(2, options.version); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16, options.flags); EXPECT_TRUE(OptionsToString(options, &options_string)); EXPECT_EQ("aes-256-xts:aes-256-cts:v2", options_string);