mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-10-22 14:22:36 +00:00
Linux/macOS: Implement missing Argon2 KDF support on Unix
This commit is contained in:
@@ -21,9 +21,47 @@
|
||||
#endif
|
||||
#include "EncryptionTest.h"
|
||||
#include "Pkcs5Kdf.h"
|
||||
#include "VolumeHeader.h"
|
||||
|
||||
namespace VeraCrypt
|
||||
{
|
||||
#if !defined (WOLFCRYPT_BACKEND) && !defined (VC_DCS_DISABLE_ARGON2)
|
||||
class FailingArgon2Kdf : public Pkcs5Kdf
|
||||
{
|
||||
public:
|
||||
FailingArgon2Kdf () : Pkcs5Kdf() { }
|
||||
virtual ~FailingArgon2Kdf () { }
|
||||
|
||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const
|
||||
{
|
||||
(void) key;
|
||||
(void) password;
|
||||
(void) pim;
|
||||
(void) salt;
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||
{
|
||||
(void) key;
|
||||
(void) password;
|
||||
(void) salt;
|
||||
(void) iterationCount;
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2b); }
|
||||
virtual int GetIterationCount (int pim) const { return 1; }
|
||||
virtual wstring GetName () const { return L"Argon2"; }
|
||||
virtual Pkcs5Kdf* Clone () const { return new FailingArgon2Kdf(); }
|
||||
virtual bool IsArgon2 () const { return true; }
|
||||
|
||||
private:
|
||||
FailingArgon2Kdf (const FailingArgon2Kdf &);
|
||||
FailingArgon2Kdf &operator= (const FailingArgon2Kdf &);
|
||||
};
|
||||
#endif
|
||||
|
||||
void EncryptionTest::TestAll ()
|
||||
{
|
||||
TestAll (false);
|
||||
@@ -1127,37 +1165,131 @@ namespace VeraCrypt
|
||||
|
||||
#ifndef WOLFCRYPT_BACKEND
|
||||
Pkcs5HmacBlake2s pkcs5HmacBlake2s;
|
||||
pkcs5HmacBlake2s.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (pkcs5HmacBlake2s.DeriveKey (derivedKey, password, salt, 5) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
if (memcmp (derivedKey.Ptr(), "\x8d\x51\xfa\x31", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
Pkcs5HmacSha512 pkcs5HmacSha512;
|
||||
pkcs5HmacSha512.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (pkcs5HmacSha512.DeriveKey (derivedKey, password, salt, 5) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
if (memcmp (derivedKey.Ptr(), "\x13\x64\xae\xf8", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
Pkcs5HmacWhirlpool pkcs5HmacWhirlpool;
|
||||
pkcs5HmacWhirlpool.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (pkcs5HmacWhirlpool.DeriveKey (derivedKey, password, salt, 5) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
if (memcmp (derivedKey.Ptr(), "\x50\x7c\x36\x6f", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
Pkcs5HmacSha256 pkcs5HmacSha256;
|
||||
pkcs5HmacSha256.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (pkcs5HmacSha256.DeriveKey (derivedKey, password, salt, 5) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
if (memcmp (derivedKey.Ptr(), "\xf2\xa0\x4f\xb2", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
Pkcs5HmacStreebog pkcs5HmacStreebog;
|
||||
pkcs5HmacStreebog.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (pkcs5HmacStreebog.DeriveKey (derivedKey, password, salt, 5) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
if (memcmp (derivedKey.Ptr(), "\xd0\x53\xa2\x30", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
#ifndef VC_DCS_DISABLE_ARGON2
|
||||
Pkcs5Argon2 pkcs5Argon2;
|
||||
static const uint8 argon2SaltData[] = { 's', 'o', 'm', 'e', 's', 'a', 'l', 't' };
|
||||
static const uint8 argon2Pim1DerivedKey[] =
|
||||
{
|
||||
0x9e, 0x87, 0x89, 0xc8, 0xb4, 0x28, 0x34, 0x22,
|
||||
0x0a, 0xfc, 0x00, 0x08, 0x5a, 0xc7, 0x3a, 0xcc,
|
||||
0x30, 0x86, 0x51, 0x21, 0x69, 0x94, 0xab, 0xbf,
|
||||
0xdd, 0xd6, 0x9b, 0x25, 0x92, 0x03, 0x2e, 0xfd
|
||||
};
|
||||
ConstBufferPtr argon2Salt (argon2SaltData, sizeof (argon2SaltData));
|
||||
Buffer argon2DerivedKey (sizeof (argon2Pim1DerivedKey));
|
||||
|
||||
// PIM 1 maps to Argon2id t=3, m=64 MiB, p=1.
|
||||
if (pkcs5Argon2.DeriveKey (argon2DerivedKey, password, 1, argon2Salt) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
if (memcmp (argon2DerivedKey.Ptr(), argon2Pim1DerivedKey, sizeof (argon2Pim1DerivedKey)) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
try
|
||||
{
|
||||
if (pkcs5Argon2.DeriveKey (derivedKey, password, salt, 5) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
throw TestFailed (SRC_POS);
|
||||
}
|
||||
catch (ParameterIncorrect&)
|
||||
{
|
||||
}
|
||||
|
||||
shared_ptr <Pkcs5Kdf> sha512Kdf (new Pkcs5HmacSha512);
|
||||
shared_ptr <Pkcs5Kdf> failingArgon2Kdf (new FailingArgon2Kdf);
|
||||
shared_ptr <EncryptionAlgorithm> ea (new AES);
|
||||
SecureBuffer headerBuffer (TC_VOLUME_HEADER_SIZE);
|
||||
SecureBuffer dataKey (ea->GetKeySize() * 2);
|
||||
SecureBuffer headerSalt (VolumeHeader::GetSaltSize());
|
||||
SecureBuffer headerKey (VolumeHeader::GetLargestSerializedKeySize());
|
||||
|
||||
for (size_t i = 0; i < dataKey.Size(); ++i)
|
||||
dataKey.Ptr()[i] = (uint8) (i + 1);
|
||||
|
||||
for (size_t i = 0; i < headerSalt.Size(); ++i)
|
||||
headerSalt.Ptr()[i] = (uint8) (i + 2);
|
||||
|
||||
if (sha512Kdf->DeriveKey (headerKey, password, 1, headerSalt) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
VolumeHeaderCreationOptions options;
|
||||
options.DataKey = dataKey;
|
||||
options.EA = ea;
|
||||
options.Kdf = sha512Kdf;
|
||||
options.HeaderKey = headerKey;
|
||||
options.Salt = headerSalt;
|
||||
options.SectorSize = TC_SECTOR_SIZE_FILE_HOSTED_VOLUME;
|
||||
options.VolumeDataStart = TC_VOLUME_HEADER_GROUP_SIZE;
|
||||
options.VolumeDataSize = TC_MIN_VOLUME_SIZE;
|
||||
options.Type = VolumeType::Normal;
|
||||
|
||||
VolumeHeader header (TC_VOLUME_HEADER_SIZE);
|
||||
header.Create (headerBuffer, options);
|
||||
|
||||
Pkcs5KdfList kdfs;
|
||||
kdfs.push_back (failingArgon2Kdf);
|
||||
kdfs.push_back (sha512Kdf);
|
||||
|
||||
EncryptionAlgorithmList encryptionAlgorithms;
|
||||
encryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AES));
|
||||
|
||||
EncryptionModeList encryptionModes;
|
||||
encryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS));
|
||||
|
||||
VolumeHeader decryptedHeader (TC_VOLUME_HEADER_SIZE);
|
||||
if (!decryptedHeader.Decrypt (headerBuffer, password, 1, shared_ptr <Pkcs5Kdf> (), kdfs, encryptionAlgorithms, encryptionModes)
|
||||
|| decryptedHeader.GetPkcs5Kdf()->GetName() != sha512Kdf->GetName())
|
||||
{
|
||||
throw TestFailed (SRC_POS);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
decryptedHeader.Decrypt (headerBuffer, password, 1, failingArgon2Kdf, kdfs, encryptionAlgorithms, encryptionModes);
|
||||
throw TestFailed (SRC_POS);
|
||||
}
|
||||
catch (ExternalException&)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
Pkcs5HmacSha256 pkcs5HmacSha256;
|
||||
pkcs5HmacSha256.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (pkcs5HmacSha256.DeriveKey (derivedKey, password, salt, 5) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
if (memcmp (derivedKey.Ptr(), "\x64\xf3\xa5\xa3", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
Pkcs5HmacSha512 pkcs5HmacSha512;
|
||||
pkcs5HmacSha512.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (pkcs5HmacSha512.DeriveKey (derivedKey, password, salt, 5) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
if (memcmp (derivedKey.Ptr(), "\x55\xa1\x76\xbb", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user