summaryrefslogtreecommitdiff
path: root/libfscrypt
diff options
context:
space:
mode:
authorPaul Crowley <paulcrowley@google.com>2019-10-24 23:27:50 -0700
committerPaul Crowley <paulcrowley@google.com>2019-10-28 14:37:45 -0700
commit5e2fbc4cf572f1e0795602d9e96cef9839a5cc18 (patch)
treee506e6030be62bdb625c2df738f7fe31ad41af36 /libfscrypt
parent9444d62255ca18e1ddcde9b2f02d08256bd589e1 (diff)
downloadextras-5e2fbc4cf572f1e0795602d9e96cef9839a5cc18.tar.gz
libfscrypt: Options parser now fills missing defaults
Bug: 143307095 Test: use parser for fstab Change-Id: Ia103a2e7947d03fb50a378472203363477d865e5
Diffstat (limited to 'libfscrypt')
-rw-r--r--libfscrypt/fscrypt.cpp26
-rw-r--r--libfscrypt/include/fscrypt/fscrypt.h2
-rw-r--r--libfscrypt/tests/Android.bp33
-rw-r--r--libfscrypt/tests/fscrypt_test.cpp119
4 files changed, 176 insertions, 4 deletions
diff --git a/libfscrypt/fscrypt.cpp b/libfscrypt/fscrypt.cpp
index 8c578679..c29cf1e8 100644
--- a/libfscrypt/fscrypt.cpp
+++ b/libfscrypt/fscrypt.cpp
@@ -193,13 +193,35 @@ bool OptionsToString(const EncryptionOptions& options, std::string* options_stri
return false;
}
*options_string = contents_mode + ":" + filenames_mode + ":v" + std::to_string(options.version);
+ EncryptionOptions options_check;
+ if (!ParseOptions(*options_string, &options_check)) {
+ LOG(ERROR) << "Internal error serializing options as string: " << *options_string;
+ return false;
+ }
+ if (memcmp(&options, &options_check, sizeof(options_check)) != 0) {
+ LOG(ERROR) << "Internal error serializing options as string, round trip failed: "
+ << *options_string;
+ return false;
+ }
return true;
}
bool ParseOptions(const std::string& options_string, EncryptionOptions* options) {
+ memset(options, '\0', sizeof(*options));
auto parts = android::base::Split(options_string, ":");
-
- if (parts.size() != 3) return false;
+ if (parts.size() < 1 || parts.size() > 3) {
+ return false;
+ }
+ if (parts.size() < 2) {
+ if (parts[0] == "adiantum") {
+ parts.emplace_back("adiantum");
+ } else {
+ parts.emplace_back("aes-256-cts");
+ }
+ }
+ if (parts.size() < 3) {
+ parts.emplace_back("v1");
+ }
return ParseOptionsParts(parts[0], parts[1], parts[2], options);
}
diff --git a/libfscrypt/include/fscrypt/fscrypt.h b/libfscrypt/include/fscrypt/fscrypt.h
index 29617ad5..ccd716f2 100644
--- a/libfscrypt/include/fscrypt/fscrypt.h
+++ b/libfscrypt/include/fscrypt/fscrypt.h
@@ -46,8 +46,6 @@ void BytesToHex(const std::string& bytes, std::string* hex);
bool OptionsToString(const EncryptionOptions& options, std::string* options_string);
-// Note that right now this parses only the output from OptionsToString, not the
-// more general format that appears in fstabs.
bool ParseOptions(const std::string& options_string, EncryptionOptions* options);
bool ParseOptionsParts(const std::string& contents_mode, const std::string& filenames_mode,
diff --git a/libfscrypt/tests/Android.bp b/libfscrypt/tests/Android.bp
new file mode 100644
index 00000000..985b425f
--- /dev/null
+++ b/libfscrypt/tests/Android.bp
@@ -0,0 +1,33 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_test {
+ name: "libfscrypt_unit_test",
+
+ shared_libs: [
+ "libbase",
+ ],
+ static_libs: [
+ "libfscrypt",
+ ],
+ srcs: [
+ "fscrypt_test.cpp",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+}
diff --git a/libfscrypt/tests/fscrypt_test.cpp b/libfscrypt/tests/fscrypt_test.cpp
new file mode 100644
index 00000000..13a37b76
--- /dev/null
+++ b/libfscrypt/tests/fscrypt_test.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <linux/fs.h>
+
+#include <fscrypt/fscrypt.h>
+
+#include <gtest/gtest.h>
+
+using namespace android::fscrypt;
+
+/* modes not supported by upstream kernel, so not in <linux/fs.h> */
+#define FS_ENCRYPTION_MODE_AES_256_HEH 126
+#define FS_ENCRYPTION_MODE_PRIVATE 127
+
+TEST(fscrypt, ParseOptions) {
+ EncryptionOptions options;
+ std::string options_string;
+
+ EXPECT_FALSE(ParseOptions("", &options));
+ EXPECT_FALSE(ParseOptions("blah", &options));
+
+ EXPECT_TRUE(ParseOptions("software", &options));
+ 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_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string);
+
+ EXPECT_TRUE(ParseOptions("aes-256-xts", &options));
+ 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_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string);
+
+ EXPECT_TRUE(ParseOptions("adiantum", &options));
+ EXPECT_EQ(1, options.version);
+ EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.contents_mode);
+ EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.filenames_mode);
+ EXPECT_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("adiantum:adiantum:v1", options_string);
+
+ EXPECT_TRUE(ParseOptions("adiantum:aes-256-heh", &options));
+ 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_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("adiantum:aes-256-heh:v1", options_string);
+
+ EXPECT_TRUE(ParseOptions("ice", &options));
+ 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_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("ice:aes-256-cts:v1", options_string);
+
+ EXPECT_FALSE(ParseOptions("ice:blah", &options));
+
+ EXPECT_TRUE(ParseOptions("ice:aes-256-cts", &options));
+ 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_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("ice:aes-256-cts:v1", options_string);
+
+ EXPECT_TRUE(ParseOptions("ice:aes-256-heh", &options));
+ 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_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("ice:aes-256-heh:v1", options_string);
+
+ EXPECT_TRUE(ParseOptions("ice:adiantum", &options));
+ EXPECT_EQ(1, options.version);
+ EXPECT_EQ(FS_ENCRYPTION_MODE_PRIVATE, options.contents_mode);
+ EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.filenames_mode);
+ EXPECT_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("ice:adiantum:v1", options_string);
+
+ EXPECT_TRUE(ParseOptions("aes-256-xts:aes-256-cts", &options));
+ 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_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string);
+
+ EXPECT_TRUE(ParseOptions("aes-256-xts:aes-256-cts:v1", &options));
+ 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_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string);
+
+ EXPECT_TRUE(ParseOptions("aes-256-xts:aes-256-cts:v2", &options));
+ 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_TRUE(OptionsToString(options, &options_string));
+ EXPECT_EQ("aes-256-xts:aes-256-cts:v2", options_string);
+
+ EXPECT_FALSE(ParseOptions("aes-256-xts:aes-256-cts:v2:", &options));
+ EXPECT_FALSE(ParseOptions("aes-256-xts:aes-256-cts:v2:foo", &options));
+ EXPECT_FALSE(ParseOptions("aes-256-xts:aes-256-cts:blah", &options));
+ EXPECT_FALSE(ParseOptions("aes-256-xts:aes-256-cts:vblah", &options));
+}