Add option to disable file data encoding (#487)

This commit is contained in:
Ben RUBSON 2018-03-20 08:30:14 +01:00 committed by GitHub
parent 154839d67c
commit 2a24884ff0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 25 deletions

View File

@ -67,6 +67,8 @@ struct EncFSConfig {
int kdfIterations; int kdfIterations;
long desiredKDFDuration; long desiredKDFDuration;
bool plainData; // do not encrypt file content
int blockMACBytes; // MAC headers on blocks.. int blockMACBytes; // MAC headers on blocks..
int blockMACRandBytes; // number of random bytes in the block header int blockMACRandBytes; // number of random bytes in the block header
@ -79,6 +81,7 @@ struct EncFSConfig {
EncFSConfig() : keyData(), salt() { EncFSConfig() : keyData(), salt() {
cfgType = Config_None; cfgType = Config_None;
subVersion = 0; subVersion = 0;
plainData = false;
blockMACBytes = 0; blockMACBytes = 0;
blockMACRandBytes = 0; blockMACRandBytes = 0;
uniqueIV = false; uniqueIV = false;

View File

@ -319,6 +319,7 @@ bool readV6Config(const char *configFile, EncFSConfig *cfg, ConfigInfo *info) {
config->read("keySize", &cfg->keySize); config->read("keySize", &cfg->keySize);
config->read("blockSize", &cfg->blockSize); config->read("blockSize", &cfg->blockSize);
config->read("plainData", &cfg->plainData);
config->read("uniqueIV", &cfg->uniqueIV); config->read("uniqueIV", &cfg->uniqueIV);
config->read("chainedNameIV", &cfg->chainedNameIV); config->read("chainedNameIV", &cfg->chainedNameIV);
config->read("externalIVChaining", &cfg->externalIVChaining); 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, "nameAlg", cfg->nameIface);
addEl(doc, config, "keySize", cfg->keySize); addEl(doc, config, "keySize", cfg->keySize);
addEl(doc, config, "blockSize", cfg->blockSize); addEl(doc, config, "blockSize", cfg->blockSize);
addEl(doc, config, "plainData", (int)cfg->plainData);
addEl(doc, config, "uniqueIV", (int)cfg->uniqueIV); addEl(doc, config, "uniqueIV", (int)cfg->uniqueIV);
addEl(doc, config, "chainedNameIV", (int)cfg->chainedNameIV); addEl(doc, config, "chainedNameIV", (int)cfg->chainedNameIV);
addEl(doc, config, "externalIVChaining", (int)cfg->externalIVChaining); addEl(doc, config, "externalIVChaining", (int)cfg->externalIVChaining);
@ -875,6 +877,20 @@ static bool boolDefaultYes(const char *prompt) {
return boolDefault(prompt, true); return boolDefault(prompt, true);
} }
/**
* Ask the user to select plain data
*/
static bool selectPlainData(bool insecure) {
bool plainData = false;
if (insecure) {
plainData = boolDefaultNo(
_("You used --insecure, you can then disable file data encryption\n"
"which is of course abolutely discouraged.\n"
"Disable file data encryption?"));
}
return plainData;
}
/** /**
* Ask the user whether to enable block MAC and random header bytes * Ask the user whether to enable block MAC and random header bytes
*/ */
@ -1020,6 +1036,7 @@ RootPtr createV6Config(EncFS_Context *ctx,
Interface nameIOIface; // selectNameCoding() Interface nameIOIface; // selectNameCoding()
int blockMACBytes = 0; // selectBlockMAC() int blockMACBytes = 0; // selectBlockMAC()
int blockMACRandBytes = 0; // selectBlockMAC() int blockMACRandBytes = 0; // selectBlockMAC()
bool plainData = false; // selectPlainData()
bool uniqueIV = true; // selectUniqueIV() bool uniqueIV = true; // selectUniqueIV()
bool chainedIV = true; // selectChainedIV() bool chainedIV = true; // selectChainedIV()
bool externalIV = false; // selectExternalChainedIV() bool externalIV = false; // selectExternalChainedIV()
@ -1100,30 +1117,42 @@ RootPtr createV6Config(EncFS_Context *ctx,
alg = selectCipherAlgorithm(); alg = selectCipherAlgorithm();
keySize = selectKeySize(alg); keySize = selectKeySize(alg);
blockSize = selectBlockSize(alg); blockSize = selectBlockSize(alg);
plainData = selectPlainData(opts->insecure);
nameIOIface = selectNameCoding(); nameIOIface = selectNameCoding();
if (reverseEncryption) { if (plainData) {
cout << _("reverse encryption - chained IV and MAC disabled") << "\n"; cout << _("plain data - IV, MAC and file-hole disabled") << "\n";
uniqueIV = selectUniqueIV(false); allowHoles = false;
/* If uniqueIV is off, writing can be allowed, because there chainedIV = false;
* is no header that could be overwritten. externalIV = false;
* So if it is on, enforce readOnly. */ uniqueIV = false;
if (uniqueIV) { blockMACBytes = 0;
opts->readOnly = true; blockMACRandBytes = 0;
} }
} else { else {
chainedIV = selectChainedIV(); if (reverseEncryption) {
uniqueIV = selectUniqueIV(true); cout << _("reverse encryption - chained IV and MAC disabled") << "\n";
if (chainedIV && uniqueIV) { uniqueIV = selectUniqueIV(false);
externalIV = selectExternalChainedIV(); /* 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 { } else {
// xgroup(setup) chainedIV = selectChainedIV();
cout << _("External chained IV disabled, as both 'IV chaining'\n" uniqueIV = selectUniqueIV(true);
"and 'unique IV' features are required for this option.") if (chainedIV && uniqueIV) {
<< "\n"; externalIV = selectExternalChainedIV();
externalIV = false; } 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();
} }
} }
@ -1143,6 +1172,7 @@ RootPtr createV6Config(EncFS_Context *ctx,
config->cipherIface = cipher->interface(); config->cipherIface = cipher->interface();
config->keySize = keySize; config->keySize = keySize;
config->blockSize = blockSize; config->blockSize = blockSize;
config->plainData = plainData;
config->nameIface = nameIOIface; config->nameIface = nameIOIface;
config->creator = "EncFS " VERSION; config->creator = "EncFS " VERSION;
config->subVersion = V6SubVersion; config->subVersion = V6SubVersion;
@ -1234,7 +1264,13 @@ RootPtr createV6Config(EncFS_Context *ctx,
nameCoder->setReverseEncryption(reverseEncryption); nameCoder->setReverseEncryption(reverseEncryption);
FSConfigPtr fsConfig(new FSConfig); 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->key = volumeKey;
fsConfig->nameCoding = nameCoder; fsConfig->nameCoding = nameCoder;
fsConfig->config = config; fsConfig->config = config;
@ -1664,7 +1700,17 @@ RootPtr initFS(EncFS_Context *ctx, const std::shared_ptr<EncFS_Opts> &opts) {
nameCoder->setReverseEncryption(opts->reverseEncryption); nameCoder->setReverseEncryption(opts->reverseEncryption);
FSConfigPtr fsConfig(new FSConfig); FSConfigPtr fsConfig(new FSConfig);
fsConfig->cipher = cipher; if (config->plainData) {
if (! opts->insecure) {
cout << _("Configuration use plainData but you did not use --insecure\n");
return rootInfo;
}
static Interface NullInterface("nullCipher", 1, 0, 0);
fsConfig->cipher = Cipher::New(NullInterface, 0);
}
else {
fsConfig->cipher = cipher;
}
fsConfig->key = volumeKey; fsConfig->key = volumeKey;
fsConfig->nameCoding = nameCoder; fsConfig->nameCoding = nameCoder;
fsConfig->config = config; fsConfig->config = config;

View File

@ -96,6 +96,8 @@ struct EncFS_Opts {
bool readOnly; // Mount read-only bool readOnly; // Mount read-only
bool insecure; // Allow to use plain data / to disable data encoding
bool requireMac; // Throw an error if MAC is disabled bool requireMac; // Throw an error if MAC is disabled
ConfigMode configMode; ConfigMode configMode;
@ -116,6 +118,7 @@ struct EncFS_Opts {
configMode = Config_Prompt; configMode = Config_Prompt;
noCache = false; noCache = false;
readOnly = false; readOnly = false;
insecure = false;
requireMac = false; requireMac = false;
} }
}; };

View File

@ -17,7 +17,7 @@ encfs - mounts or creates an encrypted virtual filesystem
=head1 SYNOPSIS =head1 SYNOPSIS
B<encfs> [B<--version>] [B<-v>|B<--verbose>] [B<-c>|B<--config>] [B<-t>|B<--syslogtag>] B<encfs> [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<--insecure>]
[B<--reverse>] [B<--reversewrite>] [B<--extpass=program>] [B<-S>|B<--stdinpass>] [B<--reverse>] [B<--reversewrite>] [B<--extpass=program>] [B<-S>|B<--stdinpass>]
[B<--anykey>] [B<--forcedecode>] [B<-require-macs>] [B<--anykey>] [B<--forcedecode>] [B<-require-macs>]
[B<-i MINUTES>|B<--idle=MINUTES>] [B<-m>|B<--ondemand>] [B<--delaymount>] [B<-u>|B<--unmount>] [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<paranoia> mode. Same as B<--standard>, but for B<paranoia> mode.
=item B<--insecure>
Allows you to disable data encoding, thus to pass plain data as is. Fully
discouraged of course!
=item B<--reverse> =item B<--reverse>
Normally B<EncFS> provides a plaintext view of data on demand: it stores Normally B<EncFS> provides a plaintext view of data on demand: it stores

View File

@ -48,6 +48,7 @@
#define LONG_OPT_ANNOTATE 513 #define LONG_OPT_ANNOTATE 513
#define LONG_OPT_NOCACHE 514 #define LONG_OPT_NOCACHE 514
#define LONG_OPT_REQUIRE_MAC 515 #define LONG_OPT_REQUIRE_MAC 515
#define LONG_OPT_INSECURE 516
using namespace std; using namespace std;
using namespace encfs; using namespace encfs;
@ -221,6 +222,7 @@ static bool processArgs(int argc, char *argv[],
out->opts->annotate = false; out->opts->annotate = false;
out->opts->reverseEncryption = false; out->opts->reverseEncryption = false;
out->opts->requireMac = false; out->opts->requireMac = false;
out->opts->insecure = false;
out->opts->unmount = false; out->opts->unmount = false;
bool useDefaultFlags = true; bool useDefaultFlags = true;
@ -260,6 +262,7 @@ static bool processArgs(int argc, char *argv[],
{"standard", 0, nullptr, '1'}, // standard configuration {"standard", 0, nullptr, '1'}, // standard configuration
{"paranoia", 0, nullptr, '2'}, // standard configuration {"paranoia", 0, nullptr, '2'}, // standard configuration
{"require-macs", 0, nullptr, LONG_OPT_REQUIRE_MAC}, // require MACs {"require-macs", 0, nullptr, LONG_OPT_REQUIRE_MAC}, // require MACs
{"insecure", 0, nullptr, LONG_OPT_INSECURE},// allows to use null data encryption
{"config", 1, nullptr, 'c'}, // command-line-supplied config location {"config", 1, nullptr, 'c'}, // command-line-supplied config location
{"unmount", 1, nullptr, 'u'}, // unmount {"unmount", 1, nullptr, 'u'}, // unmount
{nullptr, 0, nullptr, 0}}; {nullptr, 0, nullptr, 0}};
@ -307,6 +310,9 @@ static bool processArgs(int argc, char *argv[],
case LONG_OPT_REQUIRE_MAC: case LONG_OPT_REQUIRE_MAC:
out->opts->requireMac = true; out->opts->requireMac = true;
break; break;
case LONG_OPT_INSECURE:
out->opts->insecure = true;
break;
case 'c': case 'c':
/* Take config file path from command /* Take config file path from command
* line instead of ENV variable */ * line instead of ENV variable */

View File

@ -441,7 +441,7 @@ sub create_unmount_remount
# Unmount # Unmount
portable_unmount($mnt); 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"); rename("$crypt/.encfs6.xml", "$crypt/.encfs6_moved.xml");
system("./build/encfs -c $crypt/.encfs6_moved.xml --extpass=\"echo test\" $crypt $mnt 2>&1"); system("./build/encfs -c $crypt/.encfs6_moved.xml --extpass=\"echo test\" $crypt $mnt 2>&1");
ok( $? == 0, "encfs command returns 0") || return; ok( $? == 0, "encfs command returns 0") || return;