mirror of
https://github.com/vgough/encfs.git
synced 2025-06-20 11:47:58 +02:00
move encrypted key into separate config block
git-svn-id: http://encfs.googlecode.com/svn/trunk@85 db9cf616-1c43-0410-9cb8-a902689de0d6
This commit is contained in:
parent
183dca787f
commit
36946fdea7
@ -344,16 +344,17 @@ bool readV6Config( const char *configFile,
|
|||||||
cfg.set_block_mac_rand_bytes(blockMacRandBytes);
|
cfg.set_block_mac_rand_bytes(blockMacRandBytes);
|
||||||
cfg.set_allow_holes(allowHoles);
|
cfg.set_allow_holes(allowHoles);
|
||||||
|
|
||||||
|
EncryptedKey *encryptedKey = cfg.mutable_key();
|
||||||
int encodedSize;
|
int encodedSize;
|
||||||
(*config)["encodedKeySize"] >> encodedSize;
|
(*config)["encodedKeySize"] >> encodedSize;
|
||||||
unsigned char *key = new unsigned char[encodedSize];
|
unsigned char *key = new unsigned char[encodedSize];
|
||||||
(*config)["encodedKeyData"]->readB64Data(key, encodedSize);
|
(*config)["encodedKeyData"]->readB64Data(key, encodedSize);
|
||||||
cfg.set_key(key, encodedSize);
|
encryptedKey->set_ciphertext(key, encodedSize);
|
||||||
delete[] key;
|
delete[] key;
|
||||||
|
|
||||||
int keySize;
|
int keySize;
|
||||||
(*config)["keySize"] >> keySize;
|
(*config)["keySize"] >> keySize;
|
||||||
cfg.set_key_size(keySize);
|
encryptedKey->set_size(keySize / 8); // save as size in bytes
|
||||||
|
|
||||||
if(cfg.revision() >= 20080816)
|
if(cfg.revision() >= 20080816)
|
||||||
{
|
{
|
||||||
@ -361,19 +362,19 @@ bool readV6Config( const char *configFile,
|
|||||||
(*config)["saltLen"] >> saltLen;
|
(*config)["saltLen"] >> saltLen;
|
||||||
unsigned char *salt = new unsigned char[saltLen];
|
unsigned char *salt = new unsigned char[saltLen];
|
||||||
(*config)["saltData"]->readB64Data(salt, saltLen);
|
(*config)["saltData"]->readB64Data(salt, saltLen);
|
||||||
cfg.set_salt(salt, saltLen);
|
encryptedKey->set_salt(salt, saltLen);
|
||||||
delete[] salt;
|
delete[] salt;
|
||||||
|
|
||||||
int kdfIterations, desiredKDFDuration;
|
int kdfIterations, desiredKDFDuration;
|
||||||
(*config)["kdfIterations"] >> kdfIterations;
|
(*config)["kdfIterations"] >> kdfIterations;
|
||||||
(*config)["desiredKDFDuration"] >> desiredKDFDuration;
|
(*config)["desiredKDFDuration"] >> desiredKDFDuration;
|
||||||
cfg.set_kdf_iterations(kdfIterations);
|
encryptedKey->set_kdf_iterations(kdfIterations);
|
||||||
cfg.set_kdf_duration(desiredKDFDuration);
|
encryptedKey->set_kdf_duration(desiredKDFDuration);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
cfg.clear_salt();
|
encryptedKey->clear_salt();
|
||||||
cfg.set_kdf_iterations(16);
|
encryptedKey->set_kdf_iterations(16);
|
||||||
cfg.set_kdf_duration(NormalKDFDuration);
|
encryptedKey->clear_kdf_duration();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -416,10 +417,11 @@ bool readV5Config( const char *configFile,
|
|||||||
cfgRdr["blockSize"] >> blockSize;
|
cfgRdr["blockSize"] >> blockSize;
|
||||||
config.set_block_size(blockSize);
|
config.set_block_size(blockSize);
|
||||||
|
|
||||||
|
EncryptedKey *encryptedKey = config.mutable_key();
|
||||||
int keySize;
|
int keySize;
|
||||||
cfgRdr["keySize"] >> keySize;
|
cfgRdr["keySize"] >> keySize;
|
||||||
config.set_key_size(keySize);
|
encryptedKey->set_size(keySize / 8);
|
||||||
cfgRdr["keyData"] >> (*config.mutable_key());
|
cfgRdr["keyData"] >> (*encryptedKey->mutable_ciphertext());
|
||||||
|
|
||||||
config.set_unique_iv( cfgRdr["uniqueIV"].readBool( false ) );
|
config.set_unique_iv( cfgRdr["uniqueIV"].readBool( false ) );
|
||||||
config.set_chained_iv( cfgRdr["chainedIV"].readBool( false ) );
|
config.set_chained_iv( cfgRdr["chainedIV"].readBool( false ) );
|
||||||
@ -455,7 +457,8 @@ bool readV4Config( const char *configFile,
|
|||||||
cfgRdr["blockSize"] >> blockSize;
|
cfgRdr["blockSize"] >> blockSize;
|
||||||
config.set_block_size(blockSize);
|
config.set_block_size(blockSize);
|
||||||
|
|
||||||
cfgRdr["keyData"] >> (*config.mutable_key());
|
EncryptedKey *key = config.mutable_key();
|
||||||
|
cfgRdr["keyData"] >> (*key->mutable_ciphertext());
|
||||||
|
|
||||||
// fill in default for V4
|
// fill in default for V4
|
||||||
config.mutable_naming()->MergeFrom( makeInterface("nameio/stream", 1, 0, 0) );
|
config.mutable_naming()->MergeFrom( makeInterface("nameio/stream", 1, 0, 0) );
|
||||||
@ -1058,9 +1061,10 @@ RootPtr createConfig( EncFS_Context *ctx,
|
|||||||
config.set_external_iv( externalIV );
|
config.set_external_iv( externalIV );
|
||||||
config.set_allow_holes( allowHoles );
|
config.set_allow_holes( allowHoles );
|
||||||
|
|
||||||
config.clear_salt();
|
EncryptedKey *key = config.mutable_key();
|
||||||
config.clear_kdf_iterations(); // filled in by keying function
|
key->clear_salt();
|
||||||
config.set_kdf_duration( desiredKDFDuration );
|
key->clear_kdf_iterations(); // filled in by keying function
|
||||||
|
key->set_kdf_duration( desiredKDFDuration );
|
||||||
|
|
||||||
cout << "\n";
|
cout << "\n";
|
||||||
// xgroup(setup)
|
// xgroup(setup)
|
||||||
@ -1107,7 +1111,7 @@ RootPtr createConfig( EncFS_Context *ctx,
|
|||||||
cipher->writeKey( volumeKey, encodedKey, userKey );
|
cipher->writeKey( volumeKey, encodedKey, userKey );
|
||||||
userKey.reset();
|
userKey.reset();
|
||||||
|
|
||||||
config.set_key(encodedKey, encodedKeySize);
|
key->set_ciphertext(encodedKey, encodedKeySize);
|
||||||
delete[] encodedKey;
|
delete[] encodedKey;
|
||||||
|
|
||||||
if(!volumeKey)
|
if(!volumeKey)
|
||||||
@ -1203,8 +1207,9 @@ void showFSInfo( const EncfsConfig &config )
|
|||||||
cout << "\n";
|
cout << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const EncryptedKey &key = config.key();
|
||||||
{
|
{
|
||||||
cout << autosprintf(_("Key Size: %i bits"), config.key_size());
|
cout << autosprintf(_("Key Size: %i bits"), 8 * key.size());
|
||||||
cipher = getCipher(config);
|
cipher = getCipher(config);
|
||||||
if(!cipher)
|
if(!cipher)
|
||||||
{
|
{
|
||||||
@ -1213,12 +1218,12 @@ void showFSInfo( const EncfsConfig &config )
|
|||||||
} else
|
} else
|
||||||
cout << "\n";
|
cout << "\n";
|
||||||
}
|
}
|
||||||
if(config.kdf_iterations() > 0 && config.salt().size() > 0)
|
if(key.kdf_iterations() > 0 && key.salt().size() > 0)
|
||||||
{
|
{
|
||||||
cout << autosprintf(_("Using PBKDF2, with %i iterations"),
|
cout << autosprintf(_("Using PBKDF2, with %i iterations"),
|
||||||
config.kdf_iterations()) << "\n";
|
key.kdf_iterations()) << "\n";
|
||||||
cout << autosprintf(_("Salt Size: %i bits"),
|
cout << autosprintf(_("Salt Size: %i bits"),
|
||||||
8*(int)config.salt().size()) << "\n";
|
8*(int)key.salt().size()) << "\n";
|
||||||
}
|
}
|
||||||
if(config.block_mac_bytes() || config.block_mac_rand_bytes())
|
if(config.block_mac_bytes() || config.block_mac_rand_bytes())
|
||||||
{
|
{
|
||||||
@ -1270,7 +1275,7 @@ void showFSInfo( const EncfsConfig &config )
|
|||||||
|
|
||||||
shared_ptr<Cipher> getCipher(const EncfsConfig &config)
|
shared_ptr<Cipher> getCipher(const EncfsConfig &config)
|
||||||
{
|
{
|
||||||
return getCipher(config.cipher(), config.key_size());
|
return getCipher(config.cipher(), 8 * config.key().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Cipher> getCipher(const Interface &iface, int keySize)
|
shared_ptr<Cipher> getCipher(const Interface &iface, int keySize)
|
||||||
@ -1289,30 +1294,32 @@ CipherKey makeNewKey(EncfsConfig &config, const char *password, int passwdLen)
|
|||||||
cout << _("Error creating salt\n");
|
cout << _("Error creating salt\n");
|
||||||
return userKey;
|
return userKey;
|
||||||
}
|
}
|
||||||
config.set_salt(salt, sizeof(salt));
|
EncryptedKey *key = config.mutable_key();
|
||||||
|
key->set_salt(salt, sizeof(salt));
|
||||||
|
|
||||||
int iterations = config.kdf_iterations();
|
int iterations = key->kdf_iterations();
|
||||||
userKey = cipher->newKey( password, passwdLen,
|
userKey = cipher->newKey( password, passwdLen,
|
||||||
iterations, config.kdf_duration(),
|
iterations, key->kdf_duration(),
|
||||||
salt, sizeof(salt));
|
salt, sizeof(salt));
|
||||||
config.set_kdf_iterations(iterations);
|
key->set_kdf_iterations(iterations);
|
||||||
|
|
||||||
return userKey;
|
return userKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
CipherKey decryptKey(const EncfsConfig &config, const char *password, int passwdLen)
|
CipherKey decryptKey(const EncfsConfig &config, const char *password, int passwdLen)
|
||||||
{
|
{
|
||||||
|
const EncryptedKey &key = config.key();
|
||||||
CipherKey userKey;
|
CipherKey userKey;
|
||||||
shared_ptr<Cipher> cipher = getCipher(config.cipher(), config.key_size());
|
shared_ptr<Cipher> cipher = getCipher(config.cipher(), 8 * key.size());
|
||||||
|
|
||||||
if(!config.salt().empty())
|
if(!key.salt().empty())
|
||||||
{
|
{
|
||||||
int iterations = config.kdf_iterations();
|
int iterations = key.kdf_iterations();
|
||||||
userKey = cipher->newKey( password, passwdLen,
|
userKey = cipher->newKey( password, passwdLen,
|
||||||
iterations, config.kdf_duration(),
|
iterations, key.kdf_duration(),
|
||||||
(const unsigned char *)config.salt().data(), config.salt().size());
|
(const unsigned char *)key.salt().data(), key.salt().size());
|
||||||
|
|
||||||
if (iterations != config.kdf_iterations()) {
|
if (iterations != key.kdf_iterations()) {
|
||||||
rError("Error in KDF, iteration mismatch");
|
rError("Error in KDF, iteration mismatch");
|
||||||
return userKey;
|
return userKey;
|
||||||
}
|
}
|
||||||
@ -1597,7 +1604,7 @@ RootPtr initFS( EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts )
|
|||||||
rDebug("cipher key size = %i", cipher->encodedKeySize());
|
rDebug("cipher key size = %i", cipher->encodedKeySize());
|
||||||
// decode volume key..
|
// decode volume key..
|
||||||
CipherKey volumeKey = cipher->readKey(
|
CipherKey volumeKey = cipher->readKey(
|
||||||
(const unsigned char *)config.key().data(), userKey, opts->checkKey);
|
(const unsigned char *)config.key().ciphertext().data(), userKey, opts->checkKey);
|
||||||
userKey.reset();
|
userKey.reset();
|
||||||
|
|
||||||
if(!volumeKey)
|
if(!volumeKey)
|
||||||
|
@ -5,11 +5,7 @@ message EncfsConfig
|
|||||||
optional int32 revision = 2 [default=0];
|
optional int32 revision = 2 [default=0];
|
||||||
|
|
||||||
required Interface cipher = 3;
|
required Interface cipher = 3;
|
||||||
required bytes key = 4;
|
required EncryptedKey key = 4;
|
||||||
optional bytes salt = 41;
|
|
||||||
required int32 key_size = 42; // in bits
|
|
||||||
optional int32 kdf_iterations = 43 [default=0];
|
|
||||||
optional int32 kdf_duration = 44 [default=500];
|
|
||||||
|
|
||||||
optional Interface naming = 5;
|
optional Interface naming = 5;
|
||||||
optional bool unique_iv = 51 [default=false];
|
optional bool unique_iv = 51 [default=false];
|
||||||
@ -22,6 +18,17 @@ message EncfsConfig
|
|||||||
optional bool allow_holes = 62 [default = false];
|
optional bool allow_holes = 62 [default = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message EncryptedKey
|
||||||
|
{
|
||||||
|
required bytes ciphertext = 1;
|
||||||
|
required int32 size = 2; // Size of data in bytes
|
||||||
|
|
||||||
|
optional bytes salt = 6;
|
||||||
|
|
||||||
|
optional int32 kdf_iterations = 10;
|
||||||
|
optional int32 kdf_duration = 11 [default=500];
|
||||||
|
}
|
||||||
|
|
||||||
message Interface
|
message Interface
|
||||||
{
|
{
|
||||||
required string name = 1;
|
required string name = 1;
|
||||||
|
@ -726,7 +726,7 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
|
|||||||
// decode volume key using user key -- at this point we detect an incorrect
|
// decode volume key using user key -- at this point we detect an incorrect
|
||||||
// password if the key checksum does not match (causing readKey to fail).
|
// password if the key checksum does not match (causing readKey to fail).
|
||||||
CipherKey volumeKey = cipher->readKey(
|
CipherKey volumeKey = cipher->readKey(
|
||||||
(const unsigned char *)config.key().data(), userKey );
|
(const unsigned char *)config.key().ciphertext().data(), userKey );
|
||||||
|
|
||||||
if(!volumeKey)
|
if(!volumeKey)
|
||||||
{
|
{
|
||||||
@ -758,7 +758,8 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
|
|||||||
cipher->writeKey( volumeKey, keyBuf, userKey );
|
cipher->writeKey( volumeKey, keyBuf, userKey );
|
||||||
userKey.reset();
|
userKey.reset();
|
||||||
|
|
||||||
config.set_key( keyBuf, encodedKeySize );
|
EncryptedKey *key = config.mutable_key();
|
||||||
|
key->set_ciphertext( keyBuf, encodedKeySize );
|
||||||
delete[] keyBuf;
|
delete[] keyBuf;
|
||||||
|
|
||||||
if(saveConfig( rootDir, config ))
|
if(saveConfig( rootDir, config ))
|
||||||
|
@ -238,9 +238,10 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
|
|||||||
// store in config struct..
|
// store in config struct..
|
||||||
EncfsConfig cfg;
|
EncfsConfig cfg;
|
||||||
cfg.mutable_cipher()->MergeFrom(cipher->interface());
|
cfg.mutable_cipher()->MergeFrom(cipher->interface());
|
||||||
cfg.set_key_size(8 * cipher->keySize());
|
EncryptedKey *encryptedKey = cfg.mutable_key();
|
||||||
|
encryptedKey->set_size(8 * cipher->keySize());
|
||||||
|
encryptedKey->set_ciphertext( keyBuf, encodedKeySize );
|
||||||
cfg.set_block_size(FSBlockSize);
|
cfg.set_block_size(FSBlockSize);
|
||||||
cfg.set_key( keyBuf, encodedKeySize );
|
|
||||||
|
|
||||||
// save config
|
// save config
|
||||||
string data;
|
string data;
|
||||||
@ -252,12 +253,12 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
|
|||||||
|
|
||||||
// check..
|
// check..
|
||||||
rAssert( implements(cfg.cipher(),cfg2.cipher()) );
|
rAssert( implements(cfg.cipher(),cfg2.cipher()) );
|
||||||
rAssert( cfg.key_size() == cfg2.key_size() );
|
rAssert( cfg.key().size() == cfg2.key().size() );
|
||||||
rAssert( cfg.block_size() == cfg2.block_size() );
|
rAssert( cfg.block_size() == cfg2.block_size() );
|
||||||
|
|
||||||
// try decoding key..
|
// try decoding key..
|
||||||
|
|
||||||
CipherKey key2 = cipher->readKey( (unsigned char *)cfg2.key().data(), encodingKey );
|
CipherKey key2 = cipher->readKey( (unsigned char *)cfg2.key().ciphertext().data(), encodingKey );
|
||||||
if(!key2)
|
if(!key2)
|
||||||
{
|
{
|
||||||
if(verbose)
|
if(verbose)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user