mirror of
https://github.com/vgough/encfs.git
synced 2025-01-09 15:38:15 +01:00
Work around #14 (Editing Configuration File Disables MACs) with "--require-macs"
This patch implements the workaround proposed by https://defuse.ca/audits/encfs.htm to create a --require-macs command line argument. If this argument is passed, encfs will refuse to mount with MACs disabled. When creating a filesystem, encfs will force MACs to be enabled. Addressed CR comments, and added docs.
This commit is contained in:
parent
82ceb88998
commit
9d06412f1c
@ -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) {
|
||||
static void selectBlockMAC(int *macBytes, int *macRandBytes, bool forceMac) {
|
||||
bool addMAC = false;
|
||||
if (!forceMac) {
|
||||
// xgroup(setup)
|
||||
bool addMAC = boolDefaultNo(
|
||||
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;
|
||||
@ -1021,6 +1028,10 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
|
||||
blockSize = DefaultBlockSize;
|
||||
alg = findCipherAlgorithm("AES", keySize);
|
||||
nameIOIface = BlockNameIO::CurrentInterface();
|
||||
|
||||
if (opts->requireMac) {
|
||||
blockMACBytes = 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (answer[0] == 'x' || alg.name.empty()) {
|
||||
@ -1060,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();
|
||||
}
|
||||
}
|
||||
@ -1490,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 ||
|
||||
|
@ -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() {
|
||||
@ -104,6 +106,7 @@ struct EncFS_Opts {
|
||||
configMode = Config_Prompt;
|
||||
noCache = false;
|
||||
readOnly = false;
|
||||
requireMac = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -61,6 +61,7 @@ extern "C" void fuse_unmount_compat22(const char *mountpoint);
|
||||
* 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;
|
||||
@ -195,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;
|
||||
|
||||
@ -229,6 +231,7 @@ static bool processArgs(int argc, char *argv[],
|
||||
{"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) {
|
||||
@ -263,6 +266,9 @@ static bool processArgs(int argc, char *argv[],
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user