Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to disable file data encoding #487

Merged
merged 7 commits into from
Mar 20, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions encfs/FSConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -79,6 +81,7 @@ struct EncFSConfig {
EncFSConfig() : keyData(), salt() {
cfgType = Config_None;
subVersion = 0;
plainData = false;
blockMACBytes = 0;
blockMACRandBytes = 0;
uniqueIV = false;
Expand Down
92 changes: 69 additions & 23 deletions encfs/FileUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -875,6 +877,20 @@ 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, you can then disable file data encoding\n"
"which is of course abolutely discouraged.\n"
"Disable file data encoding?"));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

encoding -> encryption

}
return plainData;
}

/**
* Ask the user whether to enable block MAC and random header bytes
*/
Expand Down Expand Up @@ -1020,6 +1036,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()
Expand Down Expand Up @@ -1100,30 +1117,42 @@ 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";
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();
}
}

Expand All @@ -1143,6 +1172,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;
Expand Down Expand Up @@ -1234,7 +1264,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;
Expand Down Expand Up @@ -1664,7 +1700,17 @@ RootPtr initFS(EncFS_Context *ctx, const std::shared_ptr<EncFS_Opts> &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;
Expand Down
3 changes: 3 additions & 0 deletions encfs/FileUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -116,6 +118,7 @@ struct EncFS_Opts {
configMode = Config_Prompt;
noCache = false;
readOnly = false;
unsafe = false;
requireMac = false;
}
};
Expand Down
7 changes: 6 additions & 1 deletion encfs/encfs.pod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ encfs - mounts or creates an encrypted virtual filesystem
=head1 SYNOPSIS

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<--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>]
Expand Down Expand Up @@ -97,6 +97,11 @@ When not creating a filesystem, this flag does nothing.

Same as B<--standard>, but for B<paranoia> 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<EncFS> provides a plaintext view of data on demand: it stores
Expand Down
6 changes: 6 additions & 0 deletions encfs/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old comment "// require MACs"

{"config", 1, nullptr, 'c'}, // command-line-supplied config location
{"unmount", 1, nullptr, 'u'}, // unmount
{nullptr, 0, nullptr, 0}};
Expand Down Expand Up @@ -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 */
Expand Down