summaryrefslogtreecommitdiff
path: root/libfscrypt
diff options
context:
space:
mode:
authorPaul Crowley <paulcrowley@google.com>2019-10-25 10:28:53 -0700
committerPaul Crowley <paulcrowley@google.com>2019-10-28 15:26:56 -0700
commit22eb1d426f460c4c1a452d89cf02704ef85fe009 (patch)
treea60da93f6e6d366153dffbfb2646c0fe1e43c064 /libfscrypt
parentbe2aeea99ec04ea60c61e568ddf477f852ce95ff (diff)
downloadextras-22eb1d426f460c4c1a452d89cf02704ef85fe009.tar.gz
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
Diffstat (limited to 'libfscrypt')
-rw-r--r--libfscrypt/fscrypt.cpp50
-rw-r--r--libfscrypt/include/fscrypt/fscrypt.h2
-rw-r--r--libfscrypt/tests/fscrypt_test.cpp11
3 files changed, 36 insertions, 27 deletions
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<char*>(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<char*>(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);