diff options
author | Paul Crowley <paulcrowley@google.com> | 2019-10-24 23:27:50 -0700 |
---|---|---|
committer | Paul Crowley <paulcrowley@google.com> | 2019-10-28 14:37:45 -0700 |
commit | 5e2fbc4cf572f1e0795602d9e96cef9839a5cc18 (patch) | |
tree | e506e6030be62bdb625c2df738f7fe31ad41af36 /libfscrypt | |
parent | 9444d62255ca18e1ddcde9b2f02d08256bd589e1 (diff) | |
download | extras-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.cpp | 26 | ||||
-rw-r--r-- | libfscrypt/include/fscrypt/fscrypt.h | 2 | ||||
-rw-r--r-- | libfscrypt/tests/Android.bp | 33 | ||||
-rw-r--r-- | libfscrypt/tests/fscrypt_test.cpp | 119 |
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)); +} |