Skip to content

Commit

Permalink
Merge pull request #69 from rfjakob/next
Browse files Browse the repository at this point in the history
Changes for 1.8.1
  • Loading branch information
vgough committed Mar 24, 2015
2 parents b2f50ba + 17e12d3 commit 843a4ca
Show file tree
Hide file tree
Showing 13 changed files with 252 additions and 95 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Makefile.in
/po/remove-potcdate.sed
/po/Makefile.in.in
/po/Rules-quot
/po/*.gmo
/po/stamp-po

/m4/*.m4
!/m4/ax_boost_base.m4
Expand Down
20 changes: 20 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
Sun Mar 22 2015 Jakob Unterwurzacher <[email protected]>
* release version 1.8.1
* reverse: re-enable kernel cache (bug #60)
* reverse mode: disable unique IV by default
* add "make benchmark-reverse"
* remove "-o default_permissions" to improve performance

Fri Mar 20 2015 Eric Swanson <[email protected]>
* add option "--require-macs" (bug #14)

Fri Mar 13 2015 Valient Gough <[email protected]>
* add po files to git (bug #63)

Mon Mar 9 2015 Jakob Unterwurzacher <[email protected]>
* release version 1.8
* improve automatic test converage: also test reverse mode (make test)
* add automatic benchmark (make benchmark)
* compare MAC in constant time ( fixes bug #12 )
* lots of fixes to make building on OSX easier

Sun Nov 23 2014 Jakob Unterwurzacher <[email protected]>
* add per-file IVs to reverse mode
* add --nocache option
Expand Down
5 changes: 5 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,8 @@ test-verbose:
.PHONY: benchmark
benchmark:
sudo tests/benchmark.pl /var/tmp

.PHONY: benchmark-reverse
benchmark-reverse:
tests/benchmark-reverse.pl /var/tmp
tests/benchmark-reverse.pl /var/tmp --nocache
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.

AC_INIT([encfs], [1.8])
AC_INIT([encfs], [1.8.1])
AC_CONFIG_SRCDIR([encfs/encfs.h])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
Expand Down
57 changes: 32 additions & 25 deletions encfs/FileUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -855,14 +855,21 @@ static bool boolDefaultYes(const char *prompt) {
/**
* Ask the user whether to enable block MAC and random header bytes
*/
static void selectBlockMAC(int *macBytes, int *macRandBytes) {
// xgroup(setup)
bool addMAC = boolDefaultNo(
_("Enable block authentication code headers\n"
"on every block in a file? This adds about 12 bytes per block\n"
"to the storage requirements for a file, and significantly affects\n"
"performance but it also means [almost] any modifications or errors\n"
"within a block will be caught and will cause a read error."));
static void selectBlockMAC(int *macBytes, int *macRandBytes, bool forceMac) {
bool addMAC = false;
if (!forceMac) {
// xgroup(setup)
addMAC = boolDefaultNo(
_("Enable block authentication code headers\n"
"on every block in a file? This adds about 12 bytes per block\n"
"to the storage requirements for a file, and significantly affects\n"
"performance but it also means [almost] any modifications or errors\n"
"within a block will be caught and will cause a read error."));
} else {
cout << _("\n\nYou specified --require-macs. "
"Enabling block authentication code headers...\n\n");
addMAC = true;
}

if (addMAC)
*macBytes = 8;
Expand Down Expand Up @@ -893,13 +900,13 @@ static void selectBlockMAC(int *macBytes, int *macRandBytes) {
/**
* Ask the user if per-file unique IVs should be used
*/
static bool selectUniqueIV() {
static bool selectUniqueIV(bool default_answer) {
// xgroup(setup)
return boolDefaultYes(
return boolDefault(
_("Enable per-file initialization vectors?\n"
"This adds about 8 bytes per file to the storage requirements.\n"
"It should not affect performance except possibly with applications\n"
"which rely on block-aligned file io for performance."));
"which rely on block-aligned file io for performance."), default_answer);
}

/**
Expand Down Expand Up @@ -977,15 +984,16 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
Interface nameIOIface; // selectNameCoding()
int blockMACBytes = 0; // selectBlockMAC()
int blockMACRandBytes = 0; // selectBlockMAC()
bool uniqueIV = false; // selectUniqueIV()
bool chainedIV = false; // selectChainedIV()
bool uniqueIV = true; // selectUniqueIV()
bool chainedIV = true; // selectChainedIV()
bool externalIV = false; // selectExternalChainedIV()
bool allowHoles = true; // selectZeroBlockPassThrough()
long desiredKDFDuration = NormalKDFDuration;

if (reverseEncryption) {
chainedIV = false;
externalIV = false;
uniqueIV = false;
blockMACBytes = 0;
blockMACRandBytes = 0;
}
Expand All @@ -1009,8 +1017,6 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
nameIOIface = BlockNameIO::CurrentInterface();
blockMACBytes = 8;
blockMACRandBytes = 0; // using uniqueIV, so this isn't necessary
uniqueIV = true;
chainedIV = true;
externalIV = true;
desiredKDFDuration = ParanoiaKDFDuration;
} else if (configMode == Config_Standard || answer[0] != 'x') {
Expand All @@ -1021,15 +1027,10 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
keySize = 192;
blockSize = DefaultBlockSize;
alg = findCipherAlgorithm("AES", keySize);
blockMACBytes = 0;
externalIV = false;
nameIOIface = BlockNameIO::CurrentInterface();
uniqueIV = true;

if (reverseEncryption) {
cout << _("reverse encryption - chained IV disabled") << "\n";
} else {
chainedIV = true;
if (opts->requireMac) {
blockMACBytes = 8;
}
}

Expand All @@ -1052,15 +1053,15 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
nameIOIface = selectNameCoding();
if (reverseEncryption) {
cout << _("reverse encryption - chained IV and MAC disabled") << "\n";
uniqueIV = selectUniqueIV();
uniqueIV = selectUniqueIV(false);
/* Reverse mounts are read-only by default (set in main.cpp).
* If uniqueIV is off, writing can be allowed, because there
* is no header that could be overwritten */
if (uniqueIV == false)
opts->readOnly = false;
} else {
chainedIV = selectChainedIV();
uniqueIV = selectUniqueIV();
uniqueIV = selectUniqueIV(true);
if (chainedIV && uniqueIV)
externalIV = selectExternalChainedIV();
else {
Expand All @@ -1070,7 +1071,7 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
<< "\n";
externalIV = false;
}
selectBlockMAC(&blockMACBytes, &blockMACRandBytes);
selectBlockMAC(&blockMACBytes, &blockMACRandBytes, opts->requireMac);
allowHoles = selectZeroBlockPassThrough();
}
}
Expand Down Expand Up @@ -1500,6 +1501,12 @@ RootPtr initFS(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
shared_ptr<EncFSConfig> config(new EncFSConfig);

if (readConfig(opts->rootDir, config) != Config_None) {
if (config->blockMACBytes == 0 && opts->requireMac) {
cout
<< _("The configuration disabled MAC, but you passed --require-macs\n");
return rootInfo;
}

if (opts->reverseEncryption) {
if (config->blockMACBytes != 0 || config->blockMACRandBytes != 0 ||
config->externalIVChaining ||
Expand Down
3 changes: 3 additions & 0 deletions encfs/FileUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ struct EncFS_Opts {

bool readOnly; // Mount read-only

bool requireMac; // Throw an error if MAC is disabled

ConfigMode configMode;

EncFS_Opts() {
Expand All @@ -104,6 +106,7 @@ struct EncFS_Opts {
configMode = Config_Prompt;
noCache = false;
readOnly = false;
requireMac = false;
}
};

Expand Down
19 changes: 18 additions & 1 deletion encfs/encfs.pod
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,15 @@ password. If this succeeds, then the filesystem becomes available again.
Do not mount the filesystem when encfs starts; instead, delay mounting until
first use. This option only makes sense with B<--ondemand>.

=item B<--require-macs>

If creating a new filesystem, this forces block authentication code headers to
be enabled. When mounting an existing filesystem, this causes encfs to exit
if block authentication code headers are not enabled.

This can be used to improve security in case the ciphertext is vulnerable to
tampering, by preventing an attacker from disabling MACs in the config file.

=item B<--reverse>

Normally B<EncFS> provides a plaintext view of data on demand. Normally it
Expand All @@ -134,7 +143,7 @@ For example, the following would create an encrypted view in /tmp/crypt-view.
encfs --reverse /home/me /tmp/crypt-view

You could then copy the /tmp/crypt-view directory in order to have a copy of
the encrypted data. You must also keep a copy of the file /home/me/.encfs5
the encrypted data. You must also keep a copy of the file /home/me/.encfs6.xml
which contains the filesystem information. Together, the two can be used to
reproduce the unencrypted data:

Expand All @@ -145,6 +154,14 @@ Now /tmp/plain-view contains the same data as /home/me
Note that B<--reverse> mode only works with limited configuration options, so
many settings may be disabled when used.

=item B<--nocache>

Disable the kernel's cache of file attributes.
Setting this option makes EncFS pass "attr_timeout=0" and "entry_timeout=0" to
FUSE. This makes sure that modifications to the backing files that occour
outside EncFS show up immediately in the EncFS mount. The main use case
for "--nocache" is reverse mode.

=item B<--standard>

If creating a new filesystem, this automatically selects standard configuration
Expand Down
55 changes: 41 additions & 14 deletions encfs/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@
extern "C" void fuse_unmount_compat22(const char *mountpoint);
#define fuse_unmount fuse_unmount_compat22

/* Arbitrary identifiers for long options that do
* not have a short version */
#define LONG_OPT_ANNOTATE 513
#define LONG_OPT_NOCACHE 514
#define LONG_OPT_REQUIRE_MAC 515

using namespace std;
using namespace rlog;
using namespace rel;
Expand Down Expand Up @@ -190,6 +196,7 @@ static bool processArgs(int argc, char *argv[],
out->opts->useStdin = false;
out->opts->annotate = false;
out->opts->reverseEncryption = false;
out->opts->requireMac = false;

bool useDefaultFlags = true;

Expand All @@ -215,15 +222,16 @@ static bool processArgs(int argc, char *argv[],
{"delaymount", 0, 0, 'M'}, // delay initial mount until use
{"public", 0, 0, 'P'}, // public mode
{"extpass", 1, 0, 'p'}, // external password program
// {"single-thread", 0, 0, 's'}, // single-threaded mode
{"stdinpass", 0, 0, 'S'}, // read password from stdin
{"annotate", 0, 0, 513}, // Print annotation lines to stderr
{"nocache", 0, 0, 514}, // disable caching
// {"single-thread", 0, 0, 's'}, // single-threaded mode
{"stdinpass", 0, 0, 'S'}, // read password from stdin
{"annotate", 0, 0, LONG_OPT_ANNOTATE}, // Print annotation lines to stderr
{"nocache", 0, 0, LONG_OPT_NOCACHE}, // disable caching
{"verbose", 0, 0, 'v'}, // verbose mode
{"version", 0, 0, 'V'}, // version
{"reverse", 0, 0, 'r'}, // reverse encryption
{"standard", 0, 0, '1'}, // standard configuration
{"paranoia", 0, 0, '2'}, // standard configuration
{"require-macs", 0, 0, LONG_OPT_REQUIRE_MAC}, // require MACs
{0, 0, 0, 0}};

while (1) {
Expand Down Expand Up @@ -255,9 +263,12 @@ static bool processArgs(int argc, char *argv[],
case 'S':
out->opts->useStdin = true;
break;
case 513:
case LONG_OPT_ANNOTATE:
out->opts->annotate = true;
break;
case LONG_OPT_REQUIRE_MAC:
out->opts->requireMac = true;
break;
case 'f':
out->isDaemon = false;
// this option was added in fuse 2.x
Expand Down Expand Up @@ -295,8 +306,11 @@ static bool processArgs(int argc, char *argv[],
* filesystem where something can change the underlying
* filesystem without going through fuse can run into
* inconsistencies."
* Enabling reverse automatically enables noCache */
case 514:
* However, disabling the caches causes a factor 3
* slowdown. If you are concerned about inconsistencies,
* please use --nocache. */
break;
case LONG_OPT_NOCACHE:
/* Disable EncFS block cache
* Causes reverse grow tests to fail because short reads
* are returned */
Expand Down Expand Up @@ -359,13 +373,6 @@ static bool processArgs(int argc, char *argv[],

if (!out->isThreaded) PUSHARG("-s");

if (useDefaultFlags) {
PUSHARG("-o");
PUSHARG("use_ino");
PUSHARG("-o");
PUSHARG("default_permissions");
}

// we should have at least 2 arguments left over - the source directory and
// the mount point.
if (optind + 2 <= argc) {
Expand All @@ -388,6 +395,26 @@ static bool processArgs(int argc, char *argv[],
}
}

// Add default flags unless --no-default-flags was passed
if (useDefaultFlags) {

// Expose the underlying stable inode number
PUSHARG("-o");
PUSHARG("use_ino");

// "default_permissions" comes with a performance cost. Only enable
// it if makes sense.
for(int i=0; i < out->fuseArgc; i++) {
if ( out->fuseArgv[i] == NULL ) {
continue;
} else if (strcmp(out->fuseArgv[i], "allow_other") == 0) {
PUSHARG("-o");
PUSHARG("default_permissions");
break;
}
}
}

// sanity check
if (out->isDaemon && (!isAbsolutePath(out->mountPoint.c_str()) ||
!isAbsolutePath(out->opts->rootDir.c_str()))) {
Expand Down
Loading

0 comments on commit 843a4ca

Please sign in to comment.