From d1cca83ec8f8fbaba35c241d68a5ad25f3a33e9e Mon Sep 17 00:00:00 2001 From: benrubson Date: Sun, 18 Mar 2018 13:01:54 +0100 Subject: [PATCH 1/5] Add ability to disable file data encoding must be enforced by new option --unsafe --- encfs/FSConfig.h | 3 +++ encfs/FileUtils.cpp | 37 +++++++++++++++++++++++++++++++++++-- encfs/FileUtils.h | 3 +++ encfs/encfs.pod | 7 ++++++- encfs/main.cpp | 6 ++++++ 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/encfs/FSConfig.h b/encfs/FSConfig.h index 26fb0d04..15b67b22 100644 --- a/encfs/FSConfig.h +++ b/encfs/FSConfig.h @@ -67,6 +67,8 @@ struct EncFSConfig { int kdfIterations; long desiredKDFDuration; + bool plainData; // do not encrypt file content + int blockMACBytes; // MAC headers on blocks.. int blockMACRandBytes; // number of random bytes in the block header @@ -79,6 +81,7 @@ struct EncFSConfig { EncFSConfig() : keyData(), salt() { cfgType = Config_None; subVersion = 0; + plainData = false; blockMACBytes = 0; blockMACRandBytes = 0; uniqueIV = false; diff --git a/encfs/FileUtils.cpp b/encfs/FileUtils.cpp index e5490bc3..cc3ca018 100644 --- a/encfs/FileUtils.cpp +++ b/encfs/FileUtils.cpp @@ -319,6 +319,7 @@ bool readV6Config(const char *configFile, EncFSConfig *cfg, ConfigInfo *info) { config->read("keySize", &cfg->keySize); config->read("blockSize", &cfg->blockSize); + config->read("plainData", &cfg->plainData); config->read("uniqueIV", &cfg->uniqueIV); config->read("chainedNameIV", &cfg->chainedNameIV); config->read("externalIVChaining", &cfg->externalIVChaining); @@ -547,6 +548,7 @@ bool writeV6Config(const char *configFile, const EncFSConfig *cfg) { addEl(doc, config, "nameAlg", cfg->nameIface); addEl(doc, config, "keySize", cfg->keySize); addEl(doc, config, "blockSize", cfg->blockSize); + addEl(doc, config, "plainData", (int)cfg->plainData); addEl(doc, config, "uniqueIV", (int)cfg->uniqueIV); addEl(doc, config, "chainedNameIV", (int)cfg->chainedNameIV); addEl(doc, config, "externalIVChaining", (int)cfg->externalIVChaining); @@ -875,6 +877,18 @@ static bool boolDefaultYes(const char *prompt) { return boolDefault(prompt, true); } +/** + * Ask the user to select plain data + */ +static bool selectPlainData(bool unsafe) { + bool plainData = false; + if (unsafe) { + plainData = boolDefaultNo( + _("You used --unsafe, Disable file data crypt?")); + } + return plainData; +} + /** * Ask the user whether to enable block MAC and random header bytes */ @@ -1020,6 +1034,7 @@ RootPtr createV6Config(EncFS_Context *ctx, Interface nameIOIface; // selectNameCoding() int blockMACBytes = 0; // selectBlockMAC() int blockMACRandBytes = 0; // selectBlockMAC() + bool plainData = false; // selectPlainData() bool uniqueIV = true; // selectUniqueIV() bool chainedIV = true; // selectChainedIV() bool externalIV = false; // selectExternalChainedIV() @@ -1100,6 +1115,7 @@ RootPtr createV6Config(EncFS_Context *ctx, alg = selectCipherAlgorithm(); keySize = selectKeySize(alg); blockSize = selectBlockSize(alg); + plainData = selectPlainData(opts->unsafe); nameIOIface = selectNameCoding(); if (reverseEncryption) { cout << _("reverse encryption - chained IV and MAC disabled") << "\n"; @@ -1143,6 +1159,7 @@ RootPtr createV6Config(EncFS_Context *ctx, config->cipherIface = cipher->interface(); config->keySize = keySize; config->blockSize = blockSize; + config->plainData = plainData; config->nameIface = nameIOIface; config->creator = "EncFS " VERSION; config->subVersion = V6SubVersion; @@ -1234,7 +1251,13 @@ RootPtr createV6Config(EncFS_Context *ctx, nameCoder->setReverseEncryption(reverseEncryption); FSConfigPtr fsConfig(new FSConfig); - fsConfig->cipher = cipher; + if (plainData) { + static Interface NullInterface("nullCipher", 1, 0, 0); + fsConfig->cipher = Cipher::New(NullInterface, 0); + } + else { + fsConfig->cipher = cipher; + } fsConfig->key = volumeKey; fsConfig->nameCoding = nameCoder; fsConfig->config = config; @@ -1664,7 +1687,17 @@ RootPtr initFS(EncFS_Context *ctx, const std::shared_ptr &opts) { nameCoder->setReverseEncryption(opts->reverseEncryption); FSConfigPtr fsConfig(new FSConfig); - fsConfig->cipher = cipher; + if (config->plainData) { + if (! opts->unsafe) { + cout << _("Configuration use plainData but you did not use --unsafe\n"); + return rootInfo; + } + static Interface NullInterface("nullCipher", 1, 0, 0); + fsConfig->cipher = Cipher::New(NullInterface, 0); + } + else { + fsConfig->cipher = cipher; + } fsConfig->key = volumeKey; fsConfig->nameCoding = nameCoder; fsConfig->config = config; diff --git a/encfs/FileUtils.h b/encfs/FileUtils.h index ea9f50fc..500b6dba 100644 --- a/encfs/FileUtils.h +++ b/encfs/FileUtils.h @@ -96,6 +96,8 @@ struct EncFS_Opts { bool readOnly; // Mount read-only + bool unsafe; // Allow to use plain data / to disable data encoding + bool requireMac; // Throw an error if MAC is disabled ConfigMode configMode; @@ -116,6 +118,7 @@ struct EncFS_Opts { configMode = Config_Prompt; noCache = false; readOnly = false; + unsafe = false; requireMac = false; } }; diff --git a/encfs/encfs.pod b/encfs/encfs.pod index 5137be6d..c243ffd9 100644 --- a/encfs/encfs.pod +++ b/encfs/encfs.pod @@ -17,7 +17,7 @@ encfs - mounts or creates an encrypted virtual filesystem =head1 SYNOPSIS B [B<--version>] [B<-v>|B<--verbose>] [B<-c>|B<--config>] [B<-t>|B<--syslogtag>] -[B<-s>] [B<-f>] [B<--annotate>] [B<--standard>] [B<--paranoia>] +[B<-s>] [B<-f>] [B<--annotate>] [B<--standard>] [B<--paranoia>] [B<--unsafe>] [B<--reverse>] [B<--reversewrite>] [B<--extpass=program>] [B<-S>|B<--stdinpass>] [B<--anykey>] [B<--forcedecode>] [B<-require-macs>] [B<-i MINUTES>|B<--idle=MINUTES>] [B<-m>|B<--ondemand>] [B<--delaymount>] [B<-u>|B<--unmount>] @@ -97,6 +97,11 @@ When not creating a filesystem, this flag does nothing. Same as B<--standard>, but for B mode. +=item B<--unsafe> + +Allows you to disable data encoding, thus to pass plain data as is. Fully +discouraged of course! + =item B<--reverse> Normally B provides a plaintext view of data on demand: it stores diff --git a/encfs/main.cpp b/encfs/main.cpp index 1c61b7c2..a2b72b34 100644 --- a/encfs/main.cpp +++ b/encfs/main.cpp @@ -48,6 +48,7 @@ #define LONG_OPT_ANNOTATE 513 #define LONG_OPT_NOCACHE 514 #define LONG_OPT_REQUIRE_MAC 515 +#define LONG_OPT_UNSAFE 516 using namespace std; using namespace encfs; @@ -221,6 +222,7 @@ static bool processArgs(int argc, char *argv[], out->opts->annotate = false; out->opts->reverseEncryption = false; out->opts->requireMac = false; + out->opts->unsafe = false; out->opts->unmount = false; bool useDefaultFlags = true; @@ -260,6 +262,7 @@ static bool processArgs(int argc, char *argv[], {"standard", 0, nullptr, '1'}, // standard configuration {"paranoia", 0, nullptr, '2'}, // standard configuration {"require-macs", 0, nullptr, LONG_OPT_REQUIRE_MAC}, // require MACs + {"unsafe", 0, nullptr, LONG_OPT_UNSAFE}, // require MACs {"config", 1, nullptr, 'c'}, // command-line-supplied config location {"unmount", 1, nullptr, 'u'}, // unmount {nullptr, 0, nullptr, 0}}; @@ -307,6 +310,9 @@ static bool processArgs(int argc, char *argv[], case LONG_OPT_REQUIRE_MAC: out->opts->requireMac = true; break; + case LONG_OPT_UNSAFE: + out->opts->unsafe = true; + break; case 'c': /* Take config file path from command * line instead of ENV variable */ From 306446fdef1aa283fd96073fd6b420914c2f7fc0 Mon Sep 17 00:00:00 2001 From: benrubson Date: Sun, 18 Mar 2018 13:19:26 +0100 Subject: [PATCH 2/5] Disable not needed options using plain data --- encfs/FileUtils.cpp | 57 ++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/encfs/FileUtils.cpp b/encfs/FileUtils.cpp index cc3ca018..d38ba6e0 100644 --- a/encfs/FileUtils.cpp +++ b/encfs/FileUtils.cpp @@ -884,7 +884,9 @@ static bool selectPlainData(bool unsafe) { bool plainData = false; if (unsafe) { plainData = boolDefaultNo( - _("You used --unsafe, Disable file data crypt?")); + _("You used --unsafe, you can then disable file data encoding\n" + "which is of course abolutely discouraged.\n" + "Disable file data encoding?")); } return plainData; } @@ -1117,29 +1119,40 @@ RootPtr createV6Config(EncFS_Context *ctx, blockSize = selectBlockSize(alg); plainData = selectPlainData(opts->unsafe); nameIOIface = selectNameCoding(); - if (reverseEncryption) { - cout << _("reverse encryption - chained IV and MAC disabled") << "\n"; - uniqueIV = selectUniqueIV(false); - /* If uniqueIV is off, writing can be allowed, because there - * is no header that could be overwritten. - * So if it is on, enforce readOnly. */ - if (uniqueIV) { - opts->readOnly = true; - } - } else { - chainedIV = selectChainedIV(); - uniqueIV = selectUniqueIV(true); - if (chainedIV && uniqueIV) { - externalIV = selectExternalChainedIV(); + if (plainData) { + cout << _("plain data - IV, MAC and file-hole disabled") << "\n"; + allowHoles = false; + chainedIV = false; + externalIV = false; + uniqueIV = false; + blockMACBytes = 0; + blockMACRandBytes = 0; + } + else { + if (reverseEncryption) { + cout << _("reverse encryption - chained IV and MAC disabled") << "\n"; + uniqueIV = selectUniqueIV(false); + /* If uniqueIV is off, writing can be allowed, because there + * is no header that could be overwritten. + * So if it is on, enforce readOnly. */ + if (uniqueIV) { + opts->readOnly = true; + } } else { - // xgroup(setup) - cout << _("External chained IV disabled, as both 'IV chaining'\n" - "and 'unique IV' features are required for this option.") - << "\n"; - externalIV = false; + chainedIV = selectChainedIV(); + uniqueIV = selectUniqueIV(true); + if (chainedIV && uniqueIV) { + externalIV = selectExternalChainedIV(); + } else { + // xgroup(setup) + cout << _("External chained IV disabled, as both 'IV chaining'\n" + "and 'unique IV' features are required for this option.") + << "\n"; + externalIV = false; + } + selectBlockMAC(&blockMACBytes, &blockMACRandBytes, opts->requireMac); + allowHoles = selectZeroBlockPassThrough(); } - selectBlockMAC(&blockMACBytes, &blockMACRandBytes, opts->requireMac); - allowHoles = selectZeroBlockPassThrough(); } } From 665b857850981c2ccd8c328faaf54dae42090209 Mon Sep 17 00:00:00 2001 From: benrubson Date: Mon, 19 Mar 2018 22:02:21 +0100 Subject: [PATCH 3/5] Typos --- encfs/FileUtils.cpp | 4 ++-- encfs/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/encfs/FileUtils.cpp b/encfs/FileUtils.cpp index d38ba6e0..c0b21f5e 100644 --- a/encfs/FileUtils.cpp +++ b/encfs/FileUtils.cpp @@ -884,9 +884,9 @@ static bool selectPlainData(bool unsafe) { bool plainData = false; if (unsafe) { plainData = boolDefaultNo( - _("You used --unsafe, you can then disable file data encoding\n" + _("You used --unsafe, you can then disable file data encryption\n" "which is of course abolutely discouraged.\n" - "Disable file data encoding?")); + "Disable file data encryption?")); } return plainData; } diff --git a/encfs/main.cpp b/encfs/main.cpp index a2b72b34..1b33ae13 100644 --- a/encfs/main.cpp +++ b/encfs/main.cpp @@ -262,7 +262,7 @@ static bool processArgs(int argc, char *argv[], {"standard", 0, nullptr, '1'}, // standard configuration {"paranoia", 0, nullptr, '2'}, // standard configuration {"require-macs", 0, nullptr, LONG_OPT_REQUIRE_MAC}, // require MACs - {"unsafe", 0, nullptr, LONG_OPT_UNSAFE}, // require MACs + {"unsafe", 0, nullptr, LONG_OPT_UNSAFE}, // allows to use null data encryption {"config", 1, nullptr, 'c'}, // command-line-supplied config location {"unmount", 1, nullptr, 'u'}, // unmount {nullptr, 0, nullptr, 0}}; From 62eeb53f3589c16b71bba1f85a28b154cfb7dcf8 Mon Sep 17 00:00:00 2001 From: benrubson Date: Mon, 19 Mar 2018 22:08:37 +0100 Subject: [PATCH 4/5] Change --unsafe to --insecure --- encfs/FileUtils.cpp | 12 ++++++------ encfs/FileUtils.h | 4 ++-- encfs/encfs.pod | 4 ++-- encfs/main.cpp | 10 +++++----- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/encfs/FileUtils.cpp b/encfs/FileUtils.cpp index c0b21f5e..8f067f24 100644 --- a/encfs/FileUtils.cpp +++ b/encfs/FileUtils.cpp @@ -880,11 +880,11 @@ static bool boolDefaultYes(const char *prompt) { /** * Ask the user to select plain data */ -static bool selectPlainData(bool unsafe) { +static bool selectPlainData(bool insecure) { bool plainData = false; - if (unsafe) { + if (insecure) { plainData = boolDefaultNo( - _("You used --unsafe, you can then disable file data encryption\n" + _("You used --insecure, you can then disable file data encryption\n" "which is of course abolutely discouraged.\n" "Disable file data encryption?")); } @@ -1117,7 +1117,7 @@ RootPtr createV6Config(EncFS_Context *ctx, alg = selectCipherAlgorithm(); keySize = selectKeySize(alg); blockSize = selectBlockSize(alg); - plainData = selectPlainData(opts->unsafe); + plainData = selectPlainData(opts->insecure); nameIOIface = selectNameCoding(); if (plainData) { cout << _("plain data - IV, MAC and file-hole disabled") << "\n"; @@ -1701,8 +1701,8 @@ RootPtr initFS(EncFS_Context *ctx, const std::shared_ptr &opts) { FSConfigPtr fsConfig(new FSConfig); if (config->plainData) { - if (! opts->unsafe) { - cout << _("Configuration use plainData but you did not use --unsafe\n"); + if (! opts->insecure) { + cout << _("Configuration use plainData but you did not use --insecure\n"); return rootInfo; } static Interface NullInterface("nullCipher", 1, 0, 0); diff --git a/encfs/FileUtils.h b/encfs/FileUtils.h index 500b6dba..14069153 100644 --- a/encfs/FileUtils.h +++ b/encfs/FileUtils.h @@ -96,7 +96,7 @@ struct EncFS_Opts { bool readOnly; // Mount read-only - bool unsafe; // Allow to use plain data / to disable data encoding + bool insecure; // Allow to use plain data / to disable data encoding bool requireMac; // Throw an error if MAC is disabled @@ -118,7 +118,7 @@ struct EncFS_Opts { configMode = Config_Prompt; noCache = false; readOnly = false; - unsafe = false; + insecure = false; requireMac = false; } }; diff --git a/encfs/encfs.pod b/encfs/encfs.pod index c243ffd9..e5b08171 100644 --- a/encfs/encfs.pod +++ b/encfs/encfs.pod @@ -17,7 +17,7 @@ encfs - mounts or creates an encrypted virtual filesystem =head1 SYNOPSIS B [B<--version>] [B<-v>|B<--verbose>] [B<-c>|B<--config>] [B<-t>|B<--syslogtag>] -[B<-s>] [B<-f>] [B<--annotate>] [B<--standard>] [B<--paranoia>] [B<--unsafe>] +[B<-s>] [B<-f>] [B<--annotate>] [B<--standard>] [B<--paranoia>] [B<--insecure>] [B<--reverse>] [B<--reversewrite>] [B<--extpass=program>] [B<-S>|B<--stdinpass>] [B<--anykey>] [B<--forcedecode>] [B<-require-macs>] [B<-i MINUTES>|B<--idle=MINUTES>] [B<-m>|B<--ondemand>] [B<--delaymount>] [B<-u>|B<--unmount>] @@ -97,7 +97,7 @@ When not creating a filesystem, this flag does nothing. Same as B<--standard>, but for B mode. -=item B<--unsafe> +=item B<--insecure> Allows you to disable data encoding, thus to pass plain data as is. Fully discouraged of course! diff --git a/encfs/main.cpp b/encfs/main.cpp index 1b33ae13..c79cadaf 100644 --- a/encfs/main.cpp +++ b/encfs/main.cpp @@ -48,7 +48,7 @@ #define LONG_OPT_ANNOTATE 513 #define LONG_OPT_NOCACHE 514 #define LONG_OPT_REQUIRE_MAC 515 -#define LONG_OPT_UNSAFE 516 +#define LONG_OPT_INSECURE 516 using namespace std; using namespace encfs; @@ -222,7 +222,7 @@ static bool processArgs(int argc, char *argv[], out->opts->annotate = false; out->opts->reverseEncryption = false; out->opts->requireMac = false; - out->opts->unsafe = false; + out->opts->insecure = false; out->opts->unmount = false; bool useDefaultFlags = true; @@ -262,7 +262,7 @@ static bool processArgs(int argc, char *argv[], {"standard", 0, nullptr, '1'}, // standard configuration {"paranoia", 0, nullptr, '2'}, // standard configuration {"require-macs", 0, nullptr, LONG_OPT_REQUIRE_MAC}, // require MACs - {"unsafe", 0, nullptr, LONG_OPT_UNSAFE}, // allows to use null data encryption + {"insecure", 0, nullptr, LONG_OPT_INSECURE},// allows to use null data encryption {"config", 1, nullptr, 'c'}, // command-line-supplied config location {"unmount", 1, nullptr, 'u'}, // unmount {nullptr, 0, nullptr, 0}}; @@ -310,8 +310,8 @@ static bool processArgs(int argc, char *argv[], case LONG_OPT_REQUIRE_MAC: out->opts->requireMac = true; break; - case LONG_OPT_UNSAFE: - out->opts->unsafe = true; + case LONG_OPT_INSECURE: + out->opts->insecure = true; break; case 'c': /* Take config file path from command From db956d4b40ad9105ba2dc2cbcb79f57e33d008b5 Mon Sep 17 00:00:00 2001 From: benrubson Date: Tue, 20 Mar 2018 08:23:20 +0100 Subject: [PATCH 5/5] Typo --- integration/normal.t.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/normal.t.pl b/integration/normal.t.pl index 7cbe9324..6c5fadfa 100755 --- a/integration/normal.t.pl +++ b/integration/normal.t.pl @@ -441,7 +441,7 @@ sub create_unmount_remount # Unmount portable_unmount($mnt); - # Mount again, testing -c as the same time + # Mount again, testing -c at the same time rename("$crypt/.encfs6.xml", "$crypt/.encfs6_moved.xml"); system("./build/encfs -c $crypt/.encfs6_moved.xml --extpass=\"echo test\" $crypt $mnt 2>&1"); ok( $? == 0, "encfs command returns 0") || return;