mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-12 03:18:26 -06:00
Add TrueCrypt 7.1a MacOSX/Linux specific source files.
This commit is contained in:
314
src/Volume/Cipher.cpp
Normal file
314
src/Volume/Cipher.cpp
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Cipher.h"
|
||||
#include "Crypto/Aes.h"
|
||||
#include "Crypto/Blowfish.h"
|
||||
#include "Crypto/Des.h"
|
||||
#include "Crypto/Cast.h"
|
||||
#include "Crypto/Serpent.h"
|
||||
#include "Crypto/Twofish.h"
|
||||
|
||||
#ifdef TC_AES_HW_CPU
|
||||
# include "Crypto/Aes_hw_cpu.h"
|
||||
#endif
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
Cipher::Cipher () : Initialized (false)
|
||||
{
|
||||
}
|
||||
|
||||
Cipher::~Cipher ()
|
||||
{
|
||||
}
|
||||
|
||||
void Cipher::DecryptBlock (byte *data) const
|
||||
{
|
||||
if (!Initialized)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
Decrypt (data);
|
||||
}
|
||||
|
||||
void Cipher::DecryptBlocks (byte *data, size_t blockCount) const
|
||||
{
|
||||
if (!Initialized)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
while (blockCount-- > 0)
|
||||
{
|
||||
Decrypt (data);
|
||||
data += GetBlockSize();
|
||||
}
|
||||
}
|
||||
|
||||
void Cipher::EncryptBlock (byte *data) const
|
||||
{
|
||||
if (!Initialized)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
Encrypt (data);
|
||||
}
|
||||
|
||||
void Cipher::EncryptBlocks (byte *data, size_t blockCount) const
|
||||
{
|
||||
if (!Initialized)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
while (blockCount-- > 0)
|
||||
{
|
||||
Encrypt (data);
|
||||
data += GetBlockSize();
|
||||
}
|
||||
}
|
||||
|
||||
CipherList Cipher::GetAvailableCiphers ()
|
||||
{
|
||||
CipherList l;
|
||||
|
||||
l.push_back (shared_ptr <Cipher> (new CipherAES ()));
|
||||
l.push_back (shared_ptr <Cipher> (new CipherSerpent ()));
|
||||
l.push_back (shared_ptr <Cipher> (new CipherTwofish ()));
|
||||
l.push_back (shared_ptr <Cipher> (new CipherBlowfish ()));
|
||||
l.push_back (shared_ptr <Cipher> (new CipherCast5 ()));
|
||||
l.push_back (shared_ptr <Cipher> (new CipherTripleDES ()));
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void Cipher::SetKey (const ConstBufferPtr &key)
|
||||
{
|
||||
if (key.Size() != GetKeySize ())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
if (!Initialized)
|
||||
ScheduledKey.Allocate (GetScheduledKeySize ());
|
||||
|
||||
SetCipherKey (key);
|
||||
Key.CopyFrom (key);
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
|
||||
#undef TC_EXCEPTION_NODECL
|
||||
#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
|
||||
|
||||
TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (CipherException);
|
||||
|
||||
|
||||
// AES
|
||||
void CipherAES::Decrypt (byte *data) const
|
||||
{
|
||||
#ifdef TC_AES_HW_CPU
|
||||
if (IsHwSupportAvailable())
|
||||
aes_hw_cpu_decrypt (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx), data);
|
||||
else
|
||||
#endif
|
||||
aes_decrypt (data, data, (aes_decrypt_ctx *) (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx)));
|
||||
}
|
||||
|
||||
void CipherAES::DecryptBlocks (byte *data, size_t blockCount) const
|
||||
{
|
||||
if (!Initialized)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
#ifdef TC_AES_HW_CPU
|
||||
if ((blockCount & (32 - 1)) == 0
|
||||
&& IsHwSupportAvailable())
|
||||
{
|
||||
while (blockCount > 0)
|
||||
{
|
||||
aes_hw_cpu_decrypt_32_blocks (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx), data);
|
||||
|
||||
data += 32 * GetBlockSize();
|
||||
blockCount -= 32;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
Cipher::DecryptBlocks (data, blockCount);
|
||||
}
|
||||
|
||||
void CipherAES::Encrypt (byte *data) const
|
||||
{
|
||||
#ifdef TC_AES_HW_CPU
|
||||
if (IsHwSupportAvailable())
|
||||
aes_hw_cpu_encrypt (ScheduledKey.Ptr(), data);
|
||||
else
|
||||
#endif
|
||||
aes_encrypt (data, data, (aes_encrypt_ctx *) ScheduledKey.Ptr());
|
||||
}
|
||||
|
||||
void CipherAES::EncryptBlocks (byte *data, size_t blockCount) const
|
||||
{
|
||||
if (!Initialized)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
#ifdef TC_AES_HW_CPU
|
||||
if ((blockCount & (32 - 1)) == 0
|
||||
&& IsHwSupportAvailable())
|
||||
{
|
||||
while (blockCount > 0)
|
||||
{
|
||||
aes_hw_cpu_encrypt_32_blocks (ScheduledKey.Ptr(), data);
|
||||
|
||||
data += 32 * GetBlockSize();
|
||||
blockCount -= 32;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
Cipher::EncryptBlocks (data, blockCount);
|
||||
}
|
||||
|
||||
size_t CipherAES::GetScheduledKeySize () const
|
||||
{
|
||||
return sizeof(aes_encrypt_ctx) + sizeof(aes_decrypt_ctx);
|
||||
}
|
||||
|
||||
bool CipherAES::IsHwSupportAvailable () const
|
||||
{
|
||||
#ifdef TC_AES_HW_CPU
|
||||
static bool state = false;
|
||||
static bool stateValid = false;
|
||||
|
||||
if (!stateValid)
|
||||
{
|
||||
state = is_aes_hw_cpu_supported() ? true : false;
|
||||
stateValid = true;
|
||||
}
|
||||
return state && HwSupportEnabled;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CipherAES::SetCipherKey (const byte *key)
|
||||
{
|
||||
if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ScheduledKey.Ptr()) != EXIT_SUCCESS)
|
||||
throw CipherInitError (SRC_POS);
|
||||
|
||||
if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS)
|
||||
throw CipherInitError (SRC_POS);
|
||||
}
|
||||
|
||||
|
||||
// Blowfish
|
||||
void CipherBlowfish::Decrypt (byte *data) const
|
||||
{
|
||||
BlowfishEncryptLE (data, data, (BF_KEY *) ScheduledKey.Ptr(), 0);
|
||||
}
|
||||
|
||||
void CipherBlowfish::Encrypt (byte *data) const
|
||||
{
|
||||
BlowfishEncryptLE (data, data, (BF_KEY *) ScheduledKey.Ptr(), 1);
|
||||
}
|
||||
|
||||
size_t CipherBlowfish::GetScheduledKeySize () const
|
||||
{
|
||||
return sizeof (BF_KEY);
|
||||
}
|
||||
|
||||
void CipherBlowfish::SetCipherKey (const byte *key)
|
||||
{
|
||||
BlowfishSetKey ((BF_KEY *) ScheduledKey.Ptr(), static_cast<int> (GetKeySize ()), (unsigned char *) key);
|
||||
}
|
||||
|
||||
|
||||
// CAST5
|
||||
void CipherCast5::Decrypt (byte *data) const
|
||||
{
|
||||
Cast5Decrypt (data, data, (CAST_KEY *) ScheduledKey.Ptr());
|
||||
}
|
||||
|
||||
void CipherCast5::Encrypt (byte *data) const
|
||||
{
|
||||
Cast5Encrypt (data, data, (CAST_KEY *) ScheduledKey.Ptr());
|
||||
}
|
||||
|
||||
size_t CipherCast5::GetScheduledKeySize () const
|
||||
{
|
||||
return sizeof (CAST_KEY);
|
||||
}
|
||||
|
||||
void CipherCast5::SetCipherKey (const byte *key)
|
||||
{
|
||||
Cast5SetKey ((CAST_KEY *) ScheduledKey.Ptr(), static_cast<int> (GetKeySize ()), (unsigned char *) key);
|
||||
}
|
||||
|
||||
|
||||
// Serpent
|
||||
void CipherSerpent::Decrypt (byte *data) const
|
||||
{
|
||||
serpent_decrypt (data, data, ScheduledKey);
|
||||
}
|
||||
|
||||
void CipherSerpent::Encrypt (byte *data) const
|
||||
{
|
||||
serpent_encrypt (data, data, ScheduledKey);
|
||||
}
|
||||
|
||||
size_t CipherSerpent::GetScheduledKeySize () const
|
||||
{
|
||||
return 140*4;
|
||||
}
|
||||
|
||||
void CipherSerpent::SetCipherKey (const byte *key)
|
||||
{
|
||||
serpent_set_key (key, static_cast<int> (GetKeySize ()), ScheduledKey);
|
||||
}
|
||||
|
||||
|
||||
// Triple-DES
|
||||
void CipherTripleDES::Decrypt (byte *data) const
|
||||
{
|
||||
TripleDesEncrypt (data, data, (TDES_KEY *) ScheduledKey.Ptr(), 0);
|
||||
}
|
||||
|
||||
void CipherTripleDES::Encrypt (byte *data) const
|
||||
{
|
||||
TripleDesEncrypt (data, data, (TDES_KEY *) ScheduledKey.Ptr(), 1);
|
||||
}
|
||||
|
||||
size_t CipherTripleDES::GetScheduledKeySize () const
|
||||
{
|
||||
return sizeof (TDES_KEY);
|
||||
}
|
||||
|
||||
void CipherTripleDES::SetCipherKey (const byte *key)
|
||||
{
|
||||
TripleDesSetKey (key, GetKeySize(), (TDES_KEY *) ScheduledKey.Ptr());
|
||||
}
|
||||
|
||||
|
||||
// Twofish
|
||||
void CipherTwofish::Decrypt (byte *data) const
|
||||
{
|
||||
twofish_decrypt ((TwofishInstance *) ScheduledKey.Ptr(), (unsigned int *)data, (unsigned int *)data);
|
||||
}
|
||||
|
||||
void CipherTwofish::Encrypt (byte *data) const
|
||||
{
|
||||
twofish_encrypt ((TwofishInstance *) ScheduledKey.Ptr(), (unsigned int *)data, (unsigned int *)data);
|
||||
}
|
||||
|
||||
size_t CipherTwofish::GetScheduledKeySize () const
|
||||
{
|
||||
return TWOFISH_KS;
|
||||
}
|
||||
|
||||
void CipherTwofish::SetCipherKey (const byte *key)
|
||||
{
|
||||
twofish_set_key ((TwofishInstance *) ScheduledKey.Ptr(), (unsigned int *) key, static_cast<int> (GetKeySize ()) * 8);
|
||||
}
|
||||
|
||||
|
||||
bool Cipher::HwSupportEnabled = true;
|
||||
}
|
||||
129
src/Volume/Cipher.h
Normal file
129
src/Volume/Cipher.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_Ciphers
|
||||
#define TC_HEADER_Encryption_Ciphers
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class Cipher;
|
||||
typedef vector < shared_ptr <Cipher> > CipherList;
|
||||
|
||||
class Cipher
|
||||
{
|
||||
public:
|
||||
virtual ~Cipher ();
|
||||
|
||||
virtual void DecryptBlock (byte *data) const;
|
||||
virtual void DecryptBlocks (byte *data, size_t blockCount) const;
|
||||
static void EnableHwSupport (bool enable) { HwSupportEnabled = enable; }
|
||||
virtual void EncryptBlock (byte *data) const;
|
||||
virtual void EncryptBlocks (byte *data, size_t blockCount) const;
|
||||
static CipherList GetAvailableCiphers ();
|
||||
virtual size_t GetBlockSize () const = 0;
|
||||
virtual const SecureBuffer &GetKey () const { return Key; }
|
||||
virtual size_t GetKeySize () const = 0;
|
||||
virtual wstring GetName () const = 0;
|
||||
virtual shared_ptr <Cipher> GetNew () const = 0;
|
||||
virtual bool IsHwSupportAvailable () const { return false; }
|
||||
static bool IsHwSupportEnabled () { return HwSupportEnabled; }
|
||||
virtual void SetKey (const ConstBufferPtr &key);
|
||||
|
||||
static const int MaxBlockSize = 16;
|
||||
|
||||
protected:
|
||||
Cipher ();
|
||||
|
||||
virtual void Decrypt (byte *data) const = 0;
|
||||
virtual void Encrypt (byte *data) const = 0;
|
||||
virtual size_t GetScheduledKeySize () const = 0;
|
||||
virtual void SetCipherKey (const byte *key) = 0;
|
||||
|
||||
static bool HwSupportEnabled;
|
||||
bool Initialized;
|
||||
SecureBuffer Key;
|
||||
SecureBuffer ScheduledKey;
|
||||
|
||||
private:
|
||||
Cipher (const Cipher &);
|
||||
Cipher &operator= (const Cipher &);
|
||||
};
|
||||
|
||||
struct CipherException : public Exception
|
||||
{
|
||||
protected:
|
||||
CipherException () { }
|
||||
CipherException (const string &message) : Exception (message) { }
|
||||
CipherException (const string &message, const wstring &subject) : Exception (message, subject) { }
|
||||
};
|
||||
|
||||
|
||||
#define TC_CIPHER(NAME, BLOCK_SIZE, KEY_SIZE) \
|
||||
class TC_JOIN (Cipher,NAME) : public Cipher \
|
||||
{ \
|
||||
public: \
|
||||
TC_JOIN (Cipher,NAME) () { } \
|
||||
virtual ~TC_JOIN (Cipher,NAME) () { } \
|
||||
\
|
||||
virtual size_t GetBlockSize () const { return BLOCK_SIZE; }; \
|
||||
virtual size_t GetKeySize () const { return KEY_SIZE; }; \
|
||||
virtual wstring GetName () const { return L###NAME; }; \
|
||||
virtual shared_ptr <Cipher> GetNew () const { return shared_ptr <Cipher> (new TC_JOIN (Cipher,NAME)()); } \
|
||||
TC_CIPHER_ADD_METHODS \
|
||||
\
|
||||
protected: \
|
||||
virtual void Decrypt (byte *data) const; \
|
||||
virtual void Encrypt (byte *data) const; \
|
||||
virtual size_t GetScheduledKeySize () const; \
|
||||
virtual void SetCipherKey (const byte *key); \
|
||||
\
|
||||
private: \
|
||||
TC_JOIN (Cipher,NAME) (const TC_JOIN (Cipher,NAME) &); \
|
||||
TC_JOIN (Cipher,NAME) &operator= (const TC_JOIN (Cipher,NAME) &); \
|
||||
}
|
||||
|
||||
#define TC_CIPHER_ADD_METHODS \
|
||||
virtual void DecryptBlocks (byte *data, size_t blockCount) const; \
|
||||
virtual void EncryptBlocks (byte *data, size_t blockCount) const; \
|
||||
virtual bool IsHwSupportAvailable () const;
|
||||
|
||||
TC_CIPHER (AES, 16, 32);
|
||||
|
||||
#undef TC_CIPHER_ADD_METHODS
|
||||
#define TC_CIPHER_ADD_METHODS
|
||||
|
||||
TC_CIPHER (Blowfish, 8, 56);
|
||||
TC_CIPHER (Cast5, 8, 16);
|
||||
TC_CIPHER (Serpent, 16, 32);
|
||||
TC_CIPHER (TripleDES, 8, 24);
|
||||
TC_CIPHER (Twofish, 16, 32);
|
||||
|
||||
#undef TC_CIPHER
|
||||
|
||||
|
||||
#define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,CipherException)
|
||||
|
||||
#undef TC_EXCEPTION_SET
|
||||
#define TC_EXCEPTION_SET \
|
||||
TC_EXCEPTION (CipherInitError); \
|
||||
TC_EXCEPTION (WeakKeyDetected);
|
||||
|
||||
TC_EXCEPTION_SET;
|
||||
|
||||
#undef TC_EXCEPTION
|
||||
|
||||
#if (defined (TC_ARCH_X86) || defined (TC_ARCH_X64)) && !defined (__ppc__)
|
||||
# define TC_AES_HW_CPU
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_Ciphers
|
||||
44
src/Volume/Crc32.h
Normal file
44
src/Volume/Crc32.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_Crc32
|
||||
#define TC_HEADER_Encryption_Crc32
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Common/Crc.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class Crc32
|
||||
{
|
||||
public:
|
||||
Crc32 () : CrcValue (0xffffFFFF) { };
|
||||
virtual ~Crc32 () { };
|
||||
|
||||
uint32 Get () const { return CrcValue ^ 0xffffFFFF; }
|
||||
|
||||
uint32 Process (byte data)
|
||||
{
|
||||
return CrcValue = crc_32_tab[(byte) (CrcValue ^ data)] ^ (CrcValue >> 8);
|
||||
}
|
||||
|
||||
static uint32 ProcessBuffer (const ConstBufferPtr &buffer)
|
||||
{
|
||||
return ::GetCrc32 (const_cast<byte *> (buffer.Get()), static_cast<int> (buffer.Size()));
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32 CrcValue;
|
||||
|
||||
private:
|
||||
Crc32 (const Crc32 &);
|
||||
Crc32 &operator= (const Crc32 &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_Crc32
|
||||
345
src/Volume/EncryptionAlgorithm.cpp
Normal file
345
src/Volume/EncryptionAlgorithm.cpp
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "EncryptionAlgorithm.h"
|
||||
#include "EncryptionModeCBC.h"
|
||||
#include "EncryptionModeLRW.h"
|
||||
#include "EncryptionModeXTS.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
EncryptionAlgorithm::EncryptionAlgorithm () : Deprecated (false)
|
||||
{
|
||||
}
|
||||
|
||||
EncryptionAlgorithm::~EncryptionAlgorithm ()
|
||||
{
|
||||
}
|
||||
|
||||
void EncryptionAlgorithm::Decrypt (byte *data, uint64 length) const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
Mode->Decrypt (data, length);
|
||||
}
|
||||
|
||||
void EncryptionAlgorithm::Decrypt (const BufferPtr &data) const
|
||||
{
|
||||
Decrypt (data, data.Size());
|
||||
}
|
||||
|
||||
void EncryptionAlgorithm::DecryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
if_debug (ValidateState());
|
||||
Mode->DecryptSectors (data, sectorIndex, sectorCount, sectorSize);
|
||||
}
|
||||
|
||||
void EncryptionAlgorithm::Encrypt (byte *data, uint64 length) const
|
||||
{
|
||||
if_debug (ValidateState());
|
||||
Mode->Encrypt (data, length);
|
||||
}
|
||||
|
||||
void EncryptionAlgorithm::Encrypt (const BufferPtr &data) const
|
||||
{
|
||||
Encrypt (data, data.Size());
|
||||
}
|
||||
|
||||
void EncryptionAlgorithm::EncryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
Mode->EncryptSectors (data, sectorIndex, sectorCount, sectorSize);
|
||||
}
|
||||
|
||||
EncryptionAlgorithmList EncryptionAlgorithm::GetAvailableAlgorithms ()
|
||||
{
|
||||
EncryptionAlgorithmList l;
|
||||
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new AES ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new Serpent ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new Twofish ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofish ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofishSerpent ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentAES ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentTwofishAES ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new TwofishSerpent ()));
|
||||
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new AESBlowfish ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new AESBlowfishSerpent ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new Blowfish ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new Cast5 ()));
|
||||
l.push_back (shared_ptr <EncryptionAlgorithm> (new TripleDES ()));
|
||||
return l;
|
||||
}
|
||||
|
||||
size_t EncryptionAlgorithm::GetLargestKeySize (const EncryptionAlgorithmList &algorithms)
|
||||
{
|
||||
size_t largestKeySize = 0;
|
||||
|
||||
foreach_ref (const EncryptionAlgorithm &ea, algorithms)
|
||||
{
|
||||
if (ea.GetKeySize() > largestKeySize)
|
||||
largestKeySize = ea.GetKeySize();
|
||||
}
|
||||
|
||||
return largestKeySize;
|
||||
}
|
||||
|
||||
size_t EncryptionAlgorithm::GetKeySize () const
|
||||
{
|
||||
if (Ciphers.size() < 1)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
size_t keySize = 0;
|
||||
|
||||
foreach_ref (const Cipher &c, Ciphers)
|
||||
keySize += c.GetKeySize();
|
||||
|
||||
return keySize;
|
||||
}
|
||||
|
||||
size_t EncryptionAlgorithm::GetMaxBlockSize () const
|
||||
{
|
||||
size_t blockSize = 0;
|
||||
|
||||
foreach_ref (const Cipher &c, Ciphers)
|
||||
if (c.GetBlockSize() > blockSize)
|
||||
blockSize = c.GetBlockSize();
|
||||
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
size_t EncryptionAlgorithm::GetMinBlockSize () const
|
||||
{
|
||||
size_t blockSize = 0;
|
||||
|
||||
foreach_ref (const Cipher &c, Ciphers)
|
||||
if (blockSize == 0 || c.GetBlockSize() < blockSize)
|
||||
blockSize = c.GetBlockSize();
|
||||
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
shared_ptr <EncryptionMode> EncryptionAlgorithm::GetMode () const
|
||||
{
|
||||
if (Mode.get() == nullptr)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
return Mode;
|
||||
}
|
||||
|
||||
wstring EncryptionAlgorithm::GetName () const
|
||||
{
|
||||
if (Ciphers.size() < 1)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
wstring name;
|
||||
|
||||
foreach_reverse_ref (const Cipher &c, Ciphers)
|
||||
{
|
||||
if (name.empty())
|
||||
name = c.GetName();
|
||||
else
|
||||
name += wstring (L"-") + c.GetName();
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
bool EncryptionAlgorithm::IsModeSupported (const EncryptionMode &mode) const
|
||||
{
|
||||
bool supported = false;
|
||||
|
||||
foreach_ref (const EncryptionMode &em, SupportedModes)
|
||||
{
|
||||
if (typeid (mode) == typeid (em))
|
||||
{
|
||||
supported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
|
||||
bool EncryptionAlgorithm::IsModeSupported (const shared_ptr <EncryptionMode> mode) const
|
||||
{
|
||||
return IsModeSupported (*mode);
|
||||
}
|
||||
|
||||
void EncryptionAlgorithm::SetMode (shared_ptr <EncryptionMode> mode)
|
||||
{
|
||||
if (!IsModeSupported (*mode))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
mode->SetCiphers (Ciphers);
|
||||
Mode = mode;
|
||||
}
|
||||
|
||||
void EncryptionAlgorithm::SetKey (const ConstBufferPtr &key)
|
||||
{
|
||||
if (Ciphers.size() < 1)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
if (GetKeySize() != key.Size())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
size_t keyOffset = 0;
|
||||
foreach_ref (Cipher &c, Ciphers)
|
||||
{
|
||||
c.SetKey (key.GetRange (keyOffset, c.GetKeySize()));
|
||||
keyOffset += c.GetKeySize();
|
||||
}
|
||||
}
|
||||
|
||||
void EncryptionAlgorithm::ValidateState () const
|
||||
{
|
||||
if (Ciphers.size() < 1 || Mode.get() == nullptr)
|
||||
throw NotInitialized (SRC_POS);
|
||||
}
|
||||
|
||||
// AES
|
||||
AES::AES ()
|
||||
{
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherAES()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// AES-Blowfish
|
||||
AESBlowfish::AESBlowfish ()
|
||||
{
|
||||
Deprecated = true;
|
||||
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherBlowfish ()));
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherAES ()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// AES-Blowfish-Serpent
|
||||
AESBlowfishSerpent::AESBlowfishSerpent ()
|
||||
{
|
||||
Deprecated = true;
|
||||
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent ()));
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherBlowfish ()));
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherAES ()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// AES-Twofish
|
||||
AESTwofish::AESTwofish ()
|
||||
{
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherTwofish ()));
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherAES ()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// AES-Twofish-Serpent
|
||||
AESTwofishSerpent::AESTwofishSerpent ()
|
||||
{
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent ()));
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherTwofish ()));
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherAES ()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// Blowfish
|
||||
Blowfish::Blowfish ()
|
||||
{
|
||||
Deprecated = true;
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherBlowfish()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// CAST5
|
||||
Cast5::Cast5 ()
|
||||
{
|
||||
Deprecated = true;
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherCast5()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// Serpent
|
||||
Serpent::Serpent ()
|
||||
{
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// Serpent-AES
|
||||
SerpentAES::SerpentAES ()
|
||||
{
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherAES ()));
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent ()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// Triple-DES
|
||||
TripleDES::TripleDES ()
|
||||
{
|
||||
Deprecated = true;
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherTripleDES()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// Twofish
|
||||
Twofish::Twofish ()
|
||||
{
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherTwofish()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// Twofish-Serpent
|
||||
TwofishSerpent::TwofishSerpent ()
|
||||
{
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent ()));
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherTwofish ()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
// Serpent-Twofish-AES
|
||||
SerpentTwofishAES::SerpentTwofishAES ()
|
||||
{
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherAES ()));
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherTwofish ()));
|
||||
Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent ()));
|
||||
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
}
|
||||
93
src/Volume/EncryptionAlgorithm.h
Normal file
93
src/Volume/EncryptionAlgorithm.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_EncryptionAlgorithm
|
||||
#define TC_HEADER_Encryption_EncryptionAlgorithm
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Cipher.h"
|
||||
#include "EncryptionMode.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class EncryptionAlgorithm;
|
||||
typedef list < shared_ptr <EncryptionAlgorithm> > EncryptionAlgorithmList;
|
||||
|
||||
class EncryptionAlgorithm
|
||||
{
|
||||
public:
|
||||
virtual ~EncryptionAlgorithm ();
|
||||
|
||||
virtual void Decrypt (byte *data, uint64 length) const;
|
||||
virtual void Decrypt (const BufferPtr &data) const;
|
||||
virtual void DecryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const;
|
||||
virtual void Encrypt (byte *data, uint64 length) const;
|
||||
virtual void Encrypt (const BufferPtr &data) const;
|
||||
virtual void EncryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const;
|
||||
static EncryptionAlgorithmList GetAvailableAlgorithms ();
|
||||
virtual const CipherList &GetCiphers () const { return Ciphers; }
|
||||
virtual shared_ptr <EncryptionAlgorithm> GetNew () const = 0;
|
||||
virtual size_t GetMaxBlockSize () const;
|
||||
virtual size_t GetMinBlockSize () const;
|
||||
static size_t GetLargestKeySize (const EncryptionAlgorithmList &algorithms);
|
||||
virtual size_t GetKeySize () const;
|
||||
virtual shared_ptr <EncryptionMode> GetMode () const;
|
||||
virtual wstring GetName () const;
|
||||
bool IsDeprecated () const { return Deprecated; }
|
||||
virtual bool IsModeSupported (const EncryptionMode &mode) const;
|
||||
virtual bool IsModeSupported (const shared_ptr <EncryptionMode> mode) const;
|
||||
virtual void SetKey (const ConstBufferPtr &key);
|
||||
virtual void SetMode (shared_ptr <EncryptionMode> mode);
|
||||
|
||||
protected:
|
||||
EncryptionAlgorithm ();
|
||||
|
||||
void ValidateState () const;
|
||||
|
||||
CipherList Ciphers;
|
||||
bool Deprecated;
|
||||
shared_ptr <EncryptionMode> Mode;
|
||||
EncryptionModeList SupportedModes;
|
||||
|
||||
private:
|
||||
EncryptionAlgorithm (const EncryptionAlgorithm &);
|
||||
EncryptionAlgorithm &operator= (const EncryptionAlgorithm &);
|
||||
};
|
||||
|
||||
#define TC_ENCRYPTION_ALGORITHM(NAME) \
|
||||
class NAME : public EncryptionAlgorithm \
|
||||
{ \
|
||||
public: \
|
||||
NAME (); \
|
||||
virtual ~NAME () { } \
|
||||
\
|
||||
virtual shared_ptr <EncryptionAlgorithm> GetNew () const { return shared_ptr <EncryptionAlgorithm> (new NAME()); } \
|
||||
\
|
||||
private: \
|
||||
NAME (const NAME &); \
|
||||
NAME &operator= (const NAME &); \
|
||||
}
|
||||
|
||||
TC_ENCRYPTION_ALGORITHM (AES);
|
||||
TC_ENCRYPTION_ALGORITHM (AESBlowfish);
|
||||
TC_ENCRYPTION_ALGORITHM (AESBlowfishSerpent);
|
||||
TC_ENCRYPTION_ALGORITHM (AESTwofish);
|
||||
TC_ENCRYPTION_ALGORITHM (AESTwofishSerpent);
|
||||
TC_ENCRYPTION_ALGORITHM (Blowfish);
|
||||
TC_ENCRYPTION_ALGORITHM (Cast5);
|
||||
TC_ENCRYPTION_ALGORITHM (Serpent);
|
||||
TC_ENCRYPTION_ALGORITHM (SerpentAES);
|
||||
TC_ENCRYPTION_ALGORITHM (TripleDES);
|
||||
TC_ENCRYPTION_ALGORITHM (Twofish);
|
||||
TC_ENCRYPTION_ALGORITHM (TwofishSerpent);
|
||||
TC_ENCRYPTION_ALGORITHM (SerpentTwofishAES);
|
||||
|
||||
#undef TC_ENCRYPTION_ALGORITHM
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_EncryptionAlgorithm
|
||||
63
src/Volume/EncryptionMode.cpp
Normal file
63
src/Volume/EncryptionMode.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "EncryptionMode.h"
|
||||
#include "EncryptionModeCBC.h"
|
||||
#include "EncryptionModeLRW.h"
|
||||
#include "EncryptionModeXTS.h"
|
||||
#include "EncryptionThreadPool.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
EncryptionMode::EncryptionMode () : KeySet (false), SectorOffset (0)
|
||||
{
|
||||
}
|
||||
|
||||
EncryptionMode::~EncryptionMode ()
|
||||
{
|
||||
}
|
||||
|
||||
void EncryptionMode::DecryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
EncryptionThreadPool::DoWork (EncryptionThreadPool::WorkType::DecryptDataUnits, this, data, sectorIndex, sectorCount, sectorSize);
|
||||
}
|
||||
|
||||
void EncryptionMode::EncryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
EncryptionThreadPool::DoWork (EncryptionThreadPool::WorkType::EncryptDataUnits, this, data, sectorIndex, sectorCount, sectorSize);
|
||||
}
|
||||
|
||||
EncryptionModeList EncryptionMode::GetAvailableModes ()
|
||||
{
|
||||
EncryptionModeList l;
|
||||
|
||||
l.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
l.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
l.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void EncryptionMode::ValidateState () const
|
||||
{
|
||||
if (!KeySet || Ciphers.size() < 1)
|
||||
throw NotInitialized (SRC_POS);
|
||||
}
|
||||
|
||||
void EncryptionMode::ValidateParameters (byte *data, uint64 length) const
|
||||
{
|
||||
if ((Ciphers.size() > 0 && (length % Ciphers.front()->GetBlockSize()) != 0))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
void EncryptionMode::ValidateParameters (byte *data, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
if (sectorCount == 0 || sectorSize == 0 || (sectorSize % EncryptionDataUnitSize) != 0)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
}
|
||||
62
src/Volume/EncryptionMode.h
Normal file
62
src/Volume/EncryptionMode.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_EncryptionMode
|
||||
#define TC_HEADER_Encryption_EncryptionMode
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Common/Crypto.h"
|
||||
#include "Cipher.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class EncryptionMode;
|
||||
typedef list < shared_ptr <EncryptionMode> > EncryptionModeList;
|
||||
|
||||
class EncryptionMode
|
||||
{
|
||||
public:
|
||||
virtual ~EncryptionMode ();
|
||||
|
||||
virtual void Decrypt (byte *data, uint64 length) const = 0;
|
||||
virtual void DecryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const;
|
||||
virtual void DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const = 0;
|
||||
virtual void Encrypt (byte *data, uint64 length) const = 0;
|
||||
virtual void EncryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const;
|
||||
virtual void EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const = 0;
|
||||
static EncryptionModeList GetAvailableModes ();
|
||||
virtual const SecureBuffer &GetKey () const { throw NotApplicable (SRC_POS); }
|
||||
virtual size_t GetKeySize () const = 0;
|
||||
virtual wstring GetName () const = 0;
|
||||
virtual shared_ptr <EncryptionMode> GetNew () const = 0;
|
||||
virtual uint64 GetSectorOffset () const { return SectorOffset; }
|
||||
virtual bool IsKeySet () const { return KeySet; }
|
||||
virtual void SetKey (const ConstBufferPtr &key) = 0;
|
||||
virtual void SetCiphers (const CipherList &ciphers) { Ciphers = ciphers; }
|
||||
virtual void SetSectorOffset (int64 offset) { SectorOffset = offset; }
|
||||
|
||||
protected:
|
||||
EncryptionMode ();
|
||||
|
||||
virtual void ValidateState () const;
|
||||
void ValidateParameters (byte *data, uint64 length) const;
|
||||
virtual void ValidateParameters (byte *data, uint64 sectorCount, size_t sectorSize) const;
|
||||
|
||||
static const size_t EncryptionDataUnitSize = ENCRYPTION_DATA_UNIT_SIZE;
|
||||
|
||||
CipherList Ciphers;
|
||||
bool KeySet;
|
||||
uint64 SectorOffset;
|
||||
|
||||
private:
|
||||
EncryptionMode (const EncryptionMode &);
|
||||
EncryptionMode &operator= (const EncryptionMode &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_EncryptionMode
|
||||
335
src/Volume/EncryptionModeCBC.cpp
Normal file
335
src/Volume/EncryptionModeCBC.cpp
Normal file
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Platform/Memory.h"
|
||||
#include "Common/Crc.h"
|
||||
#include "Common/Endian.h"
|
||||
#include "EncryptionModeCBC.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
void EncryptionModeCBC::Decrypt (byte *data, uint64 length) const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
if_debug (ValidateParameters (data, length));
|
||||
|
||||
if (IsOuterCBC (Ciphers))
|
||||
{
|
||||
DecryptBuffer (data, length, Ciphers, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin();
|
||||
iCipherList != Ciphers.rend();
|
||||
++iCipherList)
|
||||
{
|
||||
CipherList cl;
|
||||
cl.push_back (*iCipherList);
|
||||
|
||||
DecryptBuffer (data, length, cl, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EncryptionModeCBC::DecryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const
|
||||
{
|
||||
size_t blockSize = ciphers.front()->GetBlockSize();
|
||||
if (blockSize != 8 && blockSize != 16)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
uint32 *data32 = (uint32 *) data;
|
||||
uint32 bufIV[4];
|
||||
uint32 ct[4];
|
||||
uint64 i;
|
||||
|
||||
bufIV[0] = iv[0];
|
||||
bufIV[1] = iv[1];
|
||||
if (blockSize == 16)
|
||||
{
|
||||
bufIV[2] = iv[2];
|
||||
bufIV[3] = iv[3];
|
||||
}
|
||||
|
||||
for (i = 0; i < length / blockSize; i++)
|
||||
{
|
||||
// Dewhitening
|
||||
data32[0] ^= whitening[0];
|
||||
data32[1] ^= whitening[1];
|
||||
if (blockSize == 16)
|
||||
{
|
||||
data32[2] ^= whitening[0];
|
||||
data32[3] ^= whitening[1];
|
||||
}
|
||||
|
||||
// CBC
|
||||
ct[0] = data32[0];
|
||||
ct[1] = data32[1];
|
||||
if (blockSize == 16)
|
||||
{
|
||||
ct[2] = data32[2];
|
||||
ct[3] = data32[3];
|
||||
}
|
||||
|
||||
for (CipherList::const_reverse_iterator iCipherList = ciphers.rbegin();
|
||||
iCipherList != ciphers.rend();
|
||||
++iCipherList)
|
||||
{
|
||||
const Cipher &c = **iCipherList;
|
||||
|
||||
if (c.GetBlockSize () != blockSize)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
c.DecryptBlock ((byte *) data32);
|
||||
}
|
||||
|
||||
// CBC
|
||||
data32[0] ^= bufIV[0];
|
||||
data32[1] ^= bufIV[1];
|
||||
bufIV[0] = ct[0];
|
||||
bufIV[1] = ct[1];
|
||||
if (blockSize == 16)
|
||||
{
|
||||
data32[2] ^= bufIV[2];
|
||||
data32[3] ^= bufIV[3];
|
||||
bufIV[2] = ct[2];
|
||||
bufIV[3] = ct[3];
|
||||
}
|
||||
|
||||
data32 += blockSize / sizeof(*data32);
|
||||
}
|
||||
|
||||
Memory::Erase (bufIV, sizeof (bufIV));
|
||||
Memory::Erase (ct, sizeof (ct));
|
||||
}
|
||||
|
||||
void EncryptionModeCBC::DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
if_debug (ValidateParameters (data, sectorCount, sectorSize));
|
||||
|
||||
uint32 sectorIV[4];
|
||||
uint32 sectorWhitening[2];
|
||||
|
||||
while (sectorCount--)
|
||||
{
|
||||
if (IsOuterCBC (Ciphers))
|
||||
{
|
||||
InitSectorIVAndWhitening (sectorIndex, Ciphers.front()->GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
|
||||
DecryptBuffer (data, sectorSize, Ciphers, sectorIV, sectorWhitening);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin();
|
||||
iCipherList != Ciphers.rend();
|
||||
++iCipherList)
|
||||
{
|
||||
const Cipher &c = **iCipherList;
|
||||
CipherList cl;
|
||||
cl.push_back (*iCipherList);
|
||||
|
||||
InitSectorIVAndWhitening (sectorIndex, c.GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
|
||||
DecryptBuffer (data, sectorSize, cl, sectorIV, sectorWhitening);
|
||||
}
|
||||
}
|
||||
|
||||
data += sectorSize;
|
||||
sectorIndex++;
|
||||
}
|
||||
|
||||
Memory::Erase (sectorIV, sizeof (sectorIV));
|
||||
Memory::Erase (sectorWhitening, sizeof (sectorWhitening));
|
||||
}
|
||||
|
||||
void EncryptionModeCBC::Encrypt (byte *data, uint64 length) const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
if_debug (ValidateParameters (data, length));
|
||||
|
||||
if (IsOuterCBC (Ciphers))
|
||||
{
|
||||
EncryptBuffer (data, length, Ciphers, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (CipherList::const_iterator iCipherList = Ciphers.begin();
|
||||
iCipherList != Ciphers.end();
|
||||
++iCipherList)
|
||||
{
|
||||
CipherList cl;
|
||||
cl.push_back (*iCipherList);
|
||||
|
||||
EncryptBuffer (data, length, cl, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EncryptionModeCBC::EncryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const
|
||||
{
|
||||
size_t blockSize = ciphers.front()->GetBlockSize();
|
||||
if (blockSize != 8 && blockSize != 16)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
uint32 *data32 = (uint32 *) data;
|
||||
uint32 bufIV[4];
|
||||
uint64 i;
|
||||
|
||||
bufIV[0] = iv[0];
|
||||
bufIV[1] = iv[1];
|
||||
if (blockSize == 16)
|
||||
{
|
||||
bufIV[2] = iv[2];
|
||||
bufIV[3] = iv[3];
|
||||
}
|
||||
|
||||
for (i = 0; i < length / blockSize; i++)
|
||||
{
|
||||
data32[0] ^= bufIV[0];
|
||||
data32[1] ^= bufIV[1];
|
||||
if (blockSize == 16)
|
||||
{
|
||||
data32[2] ^= bufIV[2];
|
||||
data32[3] ^= bufIV[3];
|
||||
}
|
||||
|
||||
for (CipherList::const_iterator iCipherList = ciphers.begin();
|
||||
iCipherList != ciphers.end();
|
||||
++iCipherList)
|
||||
{
|
||||
const Cipher &c = **iCipherList;
|
||||
|
||||
if (c.GetBlockSize () != blockSize)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
c.EncryptBlock ((byte *) data32);
|
||||
}
|
||||
|
||||
bufIV[0] = data32[0];
|
||||
bufIV[1] = data32[1];
|
||||
if (blockSize == 16)
|
||||
{
|
||||
bufIV[2] = data32[2];
|
||||
bufIV[3] = data32[3];
|
||||
}
|
||||
|
||||
data32[0] ^= whitening[0];
|
||||
data32[1] ^= whitening[1];
|
||||
if (blockSize == 16)
|
||||
{
|
||||
data32[2] ^= whitening[0];
|
||||
data32[3] ^= whitening[1];
|
||||
}
|
||||
|
||||
data32 += blockSize / sizeof(*data32);
|
||||
}
|
||||
|
||||
Memory::Erase (bufIV, sizeof (bufIV));
|
||||
}
|
||||
|
||||
void EncryptionModeCBC::EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
if_debug (ValidateParameters (data, sectorCount, sectorSize));
|
||||
|
||||
uint32 sectorIV[4];
|
||||
uint32 sectorWhitening[2];
|
||||
|
||||
while (sectorCount--)
|
||||
{
|
||||
if (IsOuterCBC (Ciphers))
|
||||
{
|
||||
InitSectorIVAndWhitening (sectorIndex, Ciphers.front()->GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
|
||||
EncryptBuffer (data, sectorSize, Ciphers, sectorIV, sectorWhitening);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (CipherList::const_iterator iCipherList = Ciphers.begin();
|
||||
iCipherList != Ciphers.end();
|
||||
++iCipherList)
|
||||
{
|
||||
const Cipher &c = **iCipherList;
|
||||
CipherList cl;
|
||||
cl.push_back (*iCipherList);
|
||||
|
||||
InitSectorIVAndWhitening (sectorIndex, c.GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening);
|
||||
EncryptBuffer (data, sectorSize, cl, sectorIV, sectorWhitening);
|
||||
}
|
||||
}
|
||||
|
||||
data += sectorSize;
|
||||
sectorIndex++;
|
||||
}
|
||||
|
||||
Memory::Erase (sectorIV, sizeof (sectorIV));
|
||||
Memory::Erase (sectorWhitening, sizeof (sectorWhitening));
|
||||
}
|
||||
|
||||
void EncryptionModeCBC::InitSectorIVAndWhitening (uint64 sectorIndex, size_t blockSize, const uint64 *ivSeed, uint32 *iv, uint32 *whitening) const
|
||||
{
|
||||
if (blockSize != 8 && blockSize != 16)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
uint64 iv64[4];
|
||||
uint32 *iv32 = (uint32 *) iv64;
|
||||
|
||||
iv64[0] = ivSeed[0] ^ Endian::Little (sectorIndex);
|
||||
iv64[1] = ivSeed[1] ^ Endian::Little (sectorIndex);
|
||||
iv64[2] = ivSeed[2] ^ Endian::Little (sectorIndex);
|
||||
if (blockSize == 16)
|
||||
{
|
||||
iv64[3] = ivSeed[3] ^ Endian::Little (sectorIndex);
|
||||
}
|
||||
|
||||
iv[0] = iv32[0];
|
||||
iv[1] = iv32[1];
|
||||
|
||||
if (blockSize == 8)
|
||||
{
|
||||
whitening[0] = Endian::Little ( crc32int ( &iv32[2] ) ^ crc32int ( &iv32[5] ) );
|
||||
whitening[1] = Endian::Little ( crc32int ( &iv32[3] ) ^ crc32int ( &iv32[4] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
iv[2] = iv32[2];
|
||||
iv[3] = iv32[3];
|
||||
|
||||
whitening[0] = Endian::Little ( crc32int ( &iv32[4] ) ^ crc32int ( &iv32[7] ) );
|
||||
whitening[1] = Endian::Little ( crc32int ( &iv32[5] ) ^ crc32int ( &iv32[6] ) );
|
||||
}
|
||||
}
|
||||
|
||||
bool EncryptionModeCBC::IsOuterCBC (const CipherList &ciphers) const
|
||||
{
|
||||
if (ciphers.size() < 2)
|
||||
return false;
|
||||
|
||||
size_t blockSize = ciphers.front()->GetBlockSize();
|
||||
|
||||
for (CipherList::const_iterator iCipherList = ciphers.begin();
|
||||
iCipherList != ciphers.end();
|
||||
++iCipherList)
|
||||
{
|
||||
const Cipher &c = **iCipherList;
|
||||
if (c.GetBlockSize() != blockSize)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EncryptionModeCBC::SetKey (const ConstBufferPtr &key)
|
||||
{
|
||||
if (key.Size() != GetKeySize ())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
if (!KeySet)
|
||||
IV.Allocate (GetKeySize ());
|
||||
|
||||
IV.CopyFrom (key);
|
||||
KeySet = true;
|
||||
}
|
||||
}
|
||||
47
src/Volume/EncryptionModeCBC.h
Normal file
47
src/Volume/EncryptionModeCBC.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_EncryptionModeCBC
|
||||
#define TC_HEADER_Encryption_EncryptionModeCBC
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "EncryptionMode.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class EncryptionModeCBC : public EncryptionMode
|
||||
{
|
||||
public:
|
||||
EncryptionModeCBC () { }
|
||||
virtual ~EncryptionModeCBC () { }
|
||||
|
||||
virtual void Decrypt (byte *data, uint64 length) const;
|
||||
virtual void DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const;
|
||||
virtual void Encrypt (byte *data, uint64 length) const;
|
||||
virtual void EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const;
|
||||
virtual size_t GetKeySize () const { return 32; };
|
||||
virtual wstring GetName () const { return L"CBC"; };
|
||||
virtual shared_ptr <EncryptionMode> GetNew () const { return shared_ptr <EncryptionMode> (new EncryptionModeCBC); }
|
||||
virtual void SetKey (const ConstBufferPtr &key);
|
||||
|
||||
protected:
|
||||
void DecryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const;
|
||||
void EncryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const;
|
||||
void InitSectorIVAndWhitening (uint64 sectorIndex, size_t blockSize, const uint64 *ivSeed, uint32 *iv, uint32 *whitening) const;
|
||||
bool IsOuterCBC (const CipherList &ciphers) const;
|
||||
|
||||
SecureBuffer IV;
|
||||
static const int WhiteningIVOffset = 8;
|
||||
|
||||
private:
|
||||
EncryptionModeCBC (const EncryptionModeCBC &);
|
||||
EncryptionModeCBC &operator= (const EncryptionModeCBC &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_EncryptionModeCBC
|
||||
195
src/Volume/EncryptionModeLRW.cpp
Normal file
195
src/Volume/EncryptionModeLRW.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "EncryptionModeLRW.h"
|
||||
#include "Common/GfMul.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
void EncryptionModeLRW::Decrypt (byte *data, uint64 length) const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
DecryptBuffer (data, length, 1);
|
||||
}
|
||||
|
||||
void EncryptionModeLRW::DecryptBuffer (byte *data, uint64 length, uint64 blockIndex) const
|
||||
{
|
||||
size_t blockSize = Ciphers.front()->GetBlockSize();
|
||||
if (blockSize != 8 && blockSize != 16)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
byte i[8];
|
||||
*(uint64 *)i = Endian::Big (blockIndex);
|
||||
|
||||
byte t[Cipher::MaxBlockSize];
|
||||
|
||||
for (unsigned int b = 0; b < length / blockSize; b++)
|
||||
{
|
||||
if (blockSize == 8)
|
||||
{
|
||||
Gf64MulTab (i, t, (GfCtx *) (GfContext.Ptr()));
|
||||
Xor64 ((uint64 *)data, (uint64 *)t);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gf128MulBy64Tab (i, t, (GfCtx *) (GfContext.Ptr()));
|
||||
Xor128 ((uint64 *)data, (uint64 *)t);
|
||||
}
|
||||
|
||||
for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin();
|
||||
iCipherList != Ciphers.rend();
|
||||
++iCipherList)
|
||||
{
|
||||
const Cipher &c = **iCipherList;
|
||||
|
||||
if (c.GetBlockSize () != blockSize)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
c.DecryptBlock (data);
|
||||
}
|
||||
|
||||
if (blockSize == 8)
|
||||
Xor64 ((uint64 *)data, (uint64 *)t);
|
||||
else
|
||||
Xor128 ((uint64 *)data, (uint64 *)t);
|
||||
|
||||
data += blockSize;
|
||||
IncrementBlockIndex (i);
|
||||
}
|
||||
|
||||
Memory::Erase (t, sizeof (t));
|
||||
}
|
||||
|
||||
void EncryptionModeLRW::DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
if_debug (ValidateParameters (data, sectorCount, sectorSize));
|
||||
|
||||
DecryptBuffer (data,
|
||||
sectorCount * sectorSize,
|
||||
SectorToBlockIndex (sectorIndex));
|
||||
}
|
||||
|
||||
void EncryptionModeLRW::Encrypt (byte *data, uint64 length) const
|
||||
{
|
||||
ValidateState ();
|
||||
EncryptBuffer (data, length, 1);
|
||||
}
|
||||
|
||||
void EncryptionModeLRW::EncryptBuffer (byte *data, uint64 length, uint64 blockIndex) const
|
||||
{
|
||||
size_t blockSize = Ciphers.front()->GetBlockSize();
|
||||
if (blockSize != 8 && blockSize != 16)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
byte i[8];
|
||||
*(uint64 *)i = Endian::Big (blockIndex);
|
||||
|
||||
byte t[Cipher::MaxBlockSize];
|
||||
|
||||
for (unsigned int b = 0; b < length / blockSize; b++)
|
||||
{
|
||||
if (blockSize == 8)
|
||||
{
|
||||
Gf64MulTab (i, t, (GfCtx *) (GfContext.Ptr()));
|
||||
Xor64 ((uint64 *)data, (uint64 *)t);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gf128MulBy64Tab (i, t, (GfCtx *) (GfContext.Ptr()));
|
||||
Xor128 ((uint64 *)data, (uint64 *)t);
|
||||
}
|
||||
|
||||
for (CipherList::const_iterator iCipherList = Ciphers.begin();
|
||||
iCipherList != Ciphers.end();
|
||||
++iCipherList)
|
||||
{
|
||||
const Cipher &c = **iCipherList;
|
||||
|
||||
if (c.GetBlockSize () != blockSize)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
c.EncryptBlock (data);
|
||||
}
|
||||
|
||||
if (blockSize == 8)
|
||||
Xor64 ((uint64 *)data, (uint64 *)t);
|
||||
else
|
||||
Xor128 ((uint64 *)data, (uint64 *)t);
|
||||
|
||||
data += blockSize;
|
||||
IncrementBlockIndex (i);
|
||||
}
|
||||
|
||||
Memory::Erase (t, sizeof (t));
|
||||
}
|
||||
|
||||
void EncryptionModeLRW::EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
if_debug (ValidateParameters (data, sectorCount, sectorSize));
|
||||
|
||||
EncryptBuffer (data,
|
||||
sectorCount * sectorSize,
|
||||
SectorToBlockIndex (sectorIndex));
|
||||
}
|
||||
|
||||
void EncryptionModeLRW::IncrementBlockIndex (byte *index) const
|
||||
{
|
||||
if (index[7] != 0xff)
|
||||
index[7]++;
|
||||
else
|
||||
*(uint64 *)index = Endian::Big ( Endian::Big (*(uint64 *)index) + 1 );
|
||||
}
|
||||
|
||||
uint64 EncryptionModeLRW::SectorToBlockIndex (uint64 sectorIndex) const
|
||||
{
|
||||
sectorIndex -= SectorOffset;
|
||||
|
||||
switch (Ciphers.front()->GetBlockSize())
|
||||
{
|
||||
case 8:
|
||||
return (sectorIndex << 6) | 1;
|
||||
|
||||
case 16:
|
||||
return (sectorIndex << 5) | 1;
|
||||
|
||||
default:
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
}
|
||||
|
||||
void EncryptionModeLRW::SetKey (const ConstBufferPtr &key)
|
||||
{
|
||||
if (key.Size() != 16)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
if (!KeySet)
|
||||
GfContext.Allocate (sizeof (GfCtx));
|
||||
|
||||
if (!Gf64TabInit ((unsigned char *) key.Get(), (GfCtx *) (GfContext.Ptr())))
|
||||
throw bad_alloc();
|
||||
|
||||
if (!Gf128Tab64Init ((unsigned char *) key.Get(), (GfCtx *) (GfContext.Ptr())))
|
||||
throw bad_alloc();
|
||||
|
||||
Key.CopyFrom (key);
|
||||
KeySet = true;
|
||||
}
|
||||
|
||||
void EncryptionModeLRW::Xor64 (uint64 *a, const uint64 *b) const
|
||||
{
|
||||
*a ^= *b;
|
||||
}
|
||||
|
||||
void EncryptionModeLRW::Xor128 (uint64 *a, const uint64 *b) const
|
||||
{
|
||||
*a++ ^= *b++;
|
||||
*a ^= *b;
|
||||
}
|
||||
}
|
||||
50
src/Volume/EncryptionModeLRW.h
Normal file
50
src/Volume/EncryptionModeLRW.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_EncryptionModeLRW
|
||||
#define TC_HEADER_Encryption_EncryptionModeLRW
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "EncryptionMode.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class EncryptionModeLRW : public EncryptionMode
|
||||
{
|
||||
public:
|
||||
EncryptionModeLRW () { }
|
||||
virtual ~EncryptionModeLRW () { }
|
||||
|
||||
virtual void Decrypt (byte *data, uint64 length) const;
|
||||
virtual void DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const;
|
||||
virtual void Encrypt (byte *data, uint64 length) const;
|
||||
virtual void EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const;
|
||||
virtual const SecureBuffer &GetKey () const { return Key; }
|
||||
virtual size_t GetKeySize () const { return 16; };
|
||||
virtual wstring GetName () const { return L"LRW"; };
|
||||
virtual shared_ptr <EncryptionMode> GetNew () const { return shared_ptr <EncryptionMode> (new EncryptionModeLRW); }
|
||||
virtual void SetKey (const ConstBufferPtr &key);
|
||||
|
||||
protected:
|
||||
void DecryptBuffer (byte *plainText, uint64 length, uint64 blockIndex) const;
|
||||
void EncryptBuffer (byte *plainText, uint64 length, uint64 blockIndex) const;
|
||||
void IncrementBlockIndex (byte *index) const;
|
||||
uint64 SectorToBlockIndex (uint64 sectorIndex) const;
|
||||
void Xor64 (uint64 *a, const uint64 *b) const;
|
||||
void Xor128 (uint64 *a, const uint64 *b) const;
|
||||
|
||||
SecureBuffer GfContext;
|
||||
SecureBuffer Key;
|
||||
|
||||
private:
|
||||
EncryptionModeLRW (const EncryptionModeLRW &);
|
||||
EncryptionModeLRW &operator= (const EncryptionModeLRW &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_EncryptionModeLRW
|
||||
374
src/Volume/EncryptionModeXTS.cpp
Normal file
374
src/Volume/EncryptionModeXTS.cpp
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "EncryptionModeXTS.h"
|
||||
#include "Common/Crypto.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
void EncryptionModeXTS::Encrypt (byte *data, uint64 length) const
|
||||
{
|
||||
EncryptBuffer (data, length, 0);
|
||||
}
|
||||
|
||||
void EncryptionModeXTS::EncryptBuffer (byte *data, uint64 length, uint64 startDataUnitNo) const
|
||||
{
|
||||
if_debug (ValidateState());
|
||||
|
||||
CipherList::const_iterator iSecondaryCipher = SecondaryCiphers.begin();
|
||||
|
||||
for (CipherList::const_iterator iCipher = Ciphers.begin(); iCipher != Ciphers.end(); ++iCipher)
|
||||
{
|
||||
EncryptBufferXTS (**iCipher, **iSecondaryCipher, data, length, startDataUnitNo, 0);
|
||||
++iSecondaryCipher;
|
||||
}
|
||||
|
||||
assert (iSecondaryCipher == SecondaryCiphers.end());
|
||||
}
|
||||
|
||||
void EncryptionModeXTS::EncryptBufferXTS (const Cipher &cipher, const Cipher &secondaryCipher, byte *buffer, uint64 length, uint64 startDataUnitNo, unsigned int startCipherBlockNo) const
|
||||
{
|
||||
byte finalCarry;
|
||||
byte whiteningValues [ENCRYPTION_DATA_UNIT_SIZE];
|
||||
byte whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
byte byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
uint64 *whiteningValuesPtr64 = (uint64 *) whiteningValues;
|
||||
uint64 *whiteningValuePtr64 = (uint64 *) whiteningValue;
|
||||
uint64 *bufPtr = (uint64 *) buffer;
|
||||
uint64 *dataUnitBufPtr;
|
||||
unsigned int startBlock = startCipherBlockNo, endBlock, block;
|
||||
uint64 *const finalInt64WhiteningValuesPtr = whiteningValuesPtr64 + sizeof (whiteningValues) / sizeof (*whiteningValuesPtr64) - 1;
|
||||
uint64 blockCount, dataUnitNo;
|
||||
|
||||
startDataUnitNo += SectorOffset;
|
||||
|
||||
/* The encrypted data unit number (i.e. the resultant ciphertext block) is to be multiplied in the
|
||||
finite field GF(2^128) by j-th power of n, where j is the sequential plaintext/ciphertext block
|
||||
number and n is 2, a primitive element of GF(2^128). This can be (and is) simplified and implemented
|
||||
as a left shift of the preceding whitening value by one bit (with carry propagating). In addition, if
|
||||
the shift of the highest byte results in a carry, 135 is XORed into the lowest byte. The value 135 is
|
||||
derived from the modulus of the Galois Field (x^128+x^7+x^2+x+1). */
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
|
||||
dataUnitNo = startDataUnitNo;
|
||||
*((uint64 *) byteBufUnitNo) = Endian::Little (dataUnitNo);
|
||||
*((uint64 *) byteBufUnitNo + 1) = 0;
|
||||
|
||||
if (length % BYTES_PER_XTS_BLOCK)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Process all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
whiteningValuePtr64 = (uint64 *) whiteningValue;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
*whiteningValuePtr64 = *((uint64 *) byteBufUnitNo);
|
||||
*(whiteningValuePtr64 + 1) = 0;
|
||||
secondaryCipher.EncryptBlock (whiteningValue);
|
||||
|
||||
// Generate subsequent whitening values for blocks in this data unit. Note that all generated 128-bit
|
||||
// whitening values are stored in memory as a sequence of 64-bit integers in reverse order.
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64++;
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64;
|
||||
}
|
||||
else
|
||||
whiteningValuePtr64++;
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
// Little-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x8000000000000000ULL) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64-- <<= 1;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x8000000000000000ULL)
|
||||
*(whiteningValuePtr64 + 1) |= 1;
|
||||
|
||||
*whiteningValuePtr64 <<= 1;
|
||||
#else
|
||||
|
||||
// Big-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x80) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64 = Endian::Little (Endian::Little (*whiteningValuePtr64) << 1);
|
||||
|
||||
whiteningValuePtr64--;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x80)
|
||||
*(whiteningValuePtr64 + 1) |= 0x0100000000000000ULL;
|
||||
|
||||
*whiteningValuePtr64 = Endian::Little (Endian::Little (*whiteningValuePtr64) << 1);
|
||||
#endif
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
dataUnitBufPtr = bufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
// Encrypt all blocks in this data unit
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
// Pre-whitening
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
// Actual encryption
|
||||
cipher.EncryptBlocks ((byte *) dataUnitBufPtr, endBlock - startBlock);
|
||||
|
||||
bufPtr = dataUnitBufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
// Post-whitening
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
dataUnitNo++;
|
||||
*((uint64 *) byteBufUnitNo) = Endian::Little (dataUnitNo);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
FAST_ERASE64 (whiteningValues, sizeof (whiteningValues));
|
||||
}
|
||||
|
||||
void EncryptionModeXTS::EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
EncryptBuffer (data, sectorCount * sectorSize, sectorIndex * sectorSize / ENCRYPTION_DATA_UNIT_SIZE);
|
||||
}
|
||||
|
||||
size_t EncryptionModeXTS::GetKeySize () const
|
||||
{
|
||||
if (Ciphers.empty())
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
size_t keySize = 0;
|
||||
foreach_ref (const Cipher &cipher, SecondaryCiphers)
|
||||
{
|
||||
keySize += cipher.GetKeySize();
|
||||
}
|
||||
|
||||
return keySize;
|
||||
}
|
||||
|
||||
void EncryptionModeXTS::Decrypt (byte *data, uint64 length) const
|
||||
{
|
||||
DecryptBuffer (data, length, 0);
|
||||
}
|
||||
|
||||
void EncryptionModeXTS::DecryptBuffer (byte *data, uint64 length, uint64 startDataUnitNo) const
|
||||
{
|
||||
if_debug (ValidateState());
|
||||
|
||||
CipherList::const_iterator iSecondaryCipher = SecondaryCiphers.end();
|
||||
|
||||
for (CipherList::const_reverse_iterator iCipher = Ciphers.rbegin(); iCipher != Ciphers.rend(); ++iCipher)
|
||||
{
|
||||
--iSecondaryCipher;
|
||||
DecryptBufferXTS (**iCipher, **iSecondaryCipher, data, length, startDataUnitNo, 0);
|
||||
}
|
||||
|
||||
assert (iSecondaryCipher == SecondaryCiphers.begin());
|
||||
}
|
||||
|
||||
void EncryptionModeXTS::DecryptBufferXTS (const Cipher &cipher, const Cipher &secondaryCipher, byte *buffer, uint64 length, uint64 startDataUnitNo, unsigned int startCipherBlockNo) const
|
||||
{
|
||||
byte finalCarry;
|
||||
byte whiteningValues [ENCRYPTION_DATA_UNIT_SIZE];
|
||||
byte whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
byte byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
uint64 *whiteningValuesPtr64 = (uint64 *) whiteningValues;
|
||||
uint64 *whiteningValuePtr64 = (uint64 *) whiteningValue;
|
||||
uint64 *bufPtr = (uint64 *) buffer;
|
||||
uint64 *dataUnitBufPtr;
|
||||
unsigned int startBlock = startCipherBlockNo, endBlock, block;
|
||||
uint64 *const finalInt64WhiteningValuesPtr = whiteningValuesPtr64 + sizeof (whiteningValues) / sizeof (*whiteningValuesPtr64) - 1;
|
||||
uint64 blockCount, dataUnitNo;
|
||||
|
||||
startDataUnitNo += SectorOffset;
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
|
||||
dataUnitNo = startDataUnitNo;
|
||||
*((uint64 *) byteBufUnitNo) = Endian::Little (dataUnitNo);
|
||||
*((uint64 *) byteBufUnitNo + 1) = 0;
|
||||
|
||||
if (length % BYTES_PER_XTS_BLOCK)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Process all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
whiteningValuePtr64 = (uint64 *) whiteningValue;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
*whiteningValuePtr64 = *((uint64 *) byteBufUnitNo);
|
||||
*(whiteningValuePtr64 + 1) = 0;
|
||||
secondaryCipher.EncryptBlock (whiteningValue);
|
||||
|
||||
// Generate subsequent whitening values for blocks in this data unit. Note that all generated 128-bit
|
||||
// whitening values are stored in memory as a sequence of 64-bit integers in reverse order.
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64++;
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64;
|
||||
}
|
||||
else
|
||||
whiteningValuePtr64++;
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
// Little-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x8000000000000000ULL) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64-- <<= 1;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x8000000000000000ULL)
|
||||
*(whiteningValuePtr64 + 1) |= 1;
|
||||
|
||||
*whiteningValuePtr64 <<= 1;
|
||||
|
||||
#else
|
||||
// Big-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x80) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64 = Endian::Little (Endian::Little (*whiteningValuePtr64) << 1);
|
||||
|
||||
whiteningValuePtr64--;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x80)
|
||||
*(whiteningValuePtr64 + 1) |= 0x0100000000000000ULL;
|
||||
|
||||
*whiteningValuePtr64 = Endian::Little (Endian::Little (*whiteningValuePtr64) << 1);
|
||||
#endif
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
dataUnitBufPtr = bufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
// Decrypt blocks in this data unit
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
cipher.DecryptBlocks ((byte *) dataUnitBufPtr, endBlock - startBlock);
|
||||
|
||||
bufPtr = dataUnitBufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
dataUnitNo++;
|
||||
|
||||
*((uint64 *) byteBufUnitNo) = Endian::Little (dataUnitNo);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
FAST_ERASE64 (whiteningValues, sizeof (whiteningValues));
|
||||
}
|
||||
|
||||
void EncryptionModeXTS::DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const
|
||||
{
|
||||
DecryptBuffer (data, sectorCount * sectorSize, sectorIndex * sectorSize / ENCRYPTION_DATA_UNIT_SIZE);
|
||||
}
|
||||
|
||||
void EncryptionModeXTS::SetCiphers (const CipherList &ciphers)
|
||||
{
|
||||
EncryptionMode::SetCiphers (ciphers);
|
||||
|
||||
SecondaryCiphers.clear();
|
||||
|
||||
foreach_ref (const Cipher &cipher, ciphers)
|
||||
{
|
||||
SecondaryCiphers.push_back (cipher.GetNew());
|
||||
}
|
||||
|
||||
if (SecondaryKey.Size() > 0)
|
||||
SetSecondaryCipherKeys();
|
||||
}
|
||||
|
||||
void EncryptionModeXTS::SetKey (const ConstBufferPtr &key)
|
||||
{
|
||||
SecondaryKey.Allocate (key.Size());
|
||||
SecondaryKey.CopyFrom (key);
|
||||
|
||||
if (!SecondaryCiphers.empty())
|
||||
SetSecondaryCipherKeys();
|
||||
}
|
||||
|
||||
void EncryptionModeXTS::SetSecondaryCipherKeys ()
|
||||
{
|
||||
size_t keyOffset = 0;
|
||||
foreach_ref (Cipher &cipher, SecondaryCiphers)
|
||||
{
|
||||
cipher.SetKey (SecondaryKey.GetRange (keyOffset, cipher.GetKeySize()));
|
||||
keyOffset += cipher.GetKeySize();
|
||||
}
|
||||
|
||||
KeySet = true;
|
||||
}
|
||||
}
|
||||
50
src/Volume/EncryptionModeXTS.h
Normal file
50
src/Volume/EncryptionModeXTS.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Volume_EncryptionModeXTS
|
||||
#define TC_HEADER_Volume_EncryptionModeXTS
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "EncryptionMode.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class EncryptionModeXTS : public EncryptionMode
|
||||
{
|
||||
public:
|
||||
EncryptionModeXTS () { }
|
||||
virtual ~EncryptionModeXTS () { }
|
||||
|
||||
virtual void Decrypt (byte *data, uint64 length) const;
|
||||
virtual void DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const;
|
||||
virtual void Encrypt (byte *data, uint64 length) const;
|
||||
virtual void EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const;
|
||||
virtual const SecureBuffer &GetKey () const { return SecondaryKey; }
|
||||
virtual size_t GetKeySize () const;
|
||||
virtual wstring GetName () const { return L"XTS"; };
|
||||
virtual shared_ptr <EncryptionMode> GetNew () const { return shared_ptr <EncryptionMode> (new EncryptionModeXTS); }
|
||||
virtual void SetCiphers (const CipherList &ciphers);
|
||||
virtual void SetKey (const ConstBufferPtr &key);
|
||||
|
||||
protected:
|
||||
void DecryptBuffer (byte *data, uint64 length, uint64 startDataUnitNo) const;
|
||||
void DecryptBufferXTS (const Cipher &cipher, const Cipher &secondaryCipher, byte *buffer, uint64 length, uint64 startDataUnitNo, unsigned int startCipherBlockNo) const;
|
||||
void EncryptBuffer (byte *data, uint64 length, uint64 startDataUnitNo) const;
|
||||
void EncryptBufferXTS (const Cipher &cipher, const Cipher &secondaryCipher, byte *buffer, uint64 length, uint64 startDataUnitNo, unsigned int startCipherBlockNo) const;
|
||||
void SetSecondaryCipherKeys ();
|
||||
|
||||
SecureBuffer SecondaryKey;
|
||||
CipherList SecondaryCiphers;
|
||||
|
||||
private:
|
||||
EncryptionModeXTS (const EncryptionModeXTS &);
|
||||
EncryptionModeXTS &operator= (const EncryptionModeXTS &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Volume_EncryptionModeXTS
|
||||
890
src/Volume/EncryptionTest.cpp
Normal file
890
src/Volume/EncryptionTest.cpp
Normal file
@@ -0,0 +1,890 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Cipher.h"
|
||||
#include "Common/Crc.h"
|
||||
#include "Crc32.h"
|
||||
#include "EncryptionAlgorithm.h"
|
||||
#include "EncryptionMode.h"
|
||||
#include "EncryptionModeCBC.h"
|
||||
#include "EncryptionModeLRW.h"
|
||||
#include "EncryptionModeXTS.h"
|
||||
#include "EncryptionTest.h"
|
||||
#include "Pkcs5Kdf.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
void EncryptionTest::TestAll ()
|
||||
{
|
||||
TestAll (false);
|
||||
TestAll (true);
|
||||
}
|
||||
|
||||
void EncryptionTest::TestAll (bool enableCpuEncryptionSupport)
|
||||
{
|
||||
bool hwSupportEnabled = Cipher::IsHwSupportEnabled();
|
||||
finally_do_arg (bool, hwSupportEnabled, { Cipher::EnableHwSupport (finally_arg); });
|
||||
|
||||
Cipher::EnableHwSupport (enableCpuEncryptionSupport);
|
||||
|
||||
TestCiphers();
|
||||
TestXtsAES();
|
||||
TestXts();
|
||||
TestLegacyModes();
|
||||
TestPkcs5();
|
||||
}
|
||||
|
||||
void EncryptionTest::TestLegacyModes ()
|
||||
{
|
||||
byte buf[ENCRYPTION_DATA_UNIT_SIZE * 2];
|
||||
byte iv[32];
|
||||
unsigned int i;
|
||||
uint32 crc;
|
||||
uint64 secNo = 0x0234567890ABCDEFull;
|
||||
|
||||
for (i = 0; i < sizeof (buf); i++)
|
||||
buf[i] = (byte) i;
|
||||
|
||||
for (i = 0; i < sizeof (iv); i++)
|
||||
iv[i] = (byte) i;
|
||||
|
||||
EncryptionModeList encModes = EncryptionMode::GetAvailableModes ();
|
||||
|
||||
foreach_ref (EncryptionAlgorithm &ea, EncryptionAlgorithm::GetAvailableAlgorithms())
|
||||
{
|
||||
foreach (shared_ptr <EncryptionMode> mode, encModes)
|
||||
{
|
||||
if (typeid (*mode) == typeid (EncryptionModeXTS))
|
||||
continue;
|
||||
|
||||
if (!mode->IsKeySet())
|
||||
{
|
||||
mode->SetKey (ConstBufferPtr (iv, mode->GetKeySize()));
|
||||
mode->SetSectorOffset (1);
|
||||
}
|
||||
|
||||
if (ea.IsModeSupported (mode))
|
||||
{
|
||||
ea.SetMode (mode);
|
||||
ea.SetKey (ConstBufferPtr (buf, ea.GetKeySize()));
|
||||
|
||||
ea.EncryptSectors (buf, secNo, sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
ea.DecryptSectors (buf, secNo, sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
ea.EncryptSectors (buf, secNo, sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
|
||||
crc = ::GetCrc32 (buf, sizeof (buf));
|
||||
|
||||
if (typeid (*mode) == typeid (EncryptionModeLRW))
|
||||
{
|
||||
if (typeid (ea) == typeid (AES) && crc != 0x5237acf9) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (AESTwofish) && crc != 0x4ed0fd80) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (AESTwofishSerpent) && crc != 0xea04b3cf) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (Blowfish) && crc != 0xf94d5300) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (Cast5) && crc != 0x33971e82) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (Serpent) && crc != 0x7fb86805) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (TripleDES) && crc != 0x2b20bb84) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (Twofish) && crc != 0xa9de0f0b) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (TwofishSerpent) && crc != 0xca65c5cd) throw TestFailed (SRC_POS);
|
||||
}
|
||||
|
||||
if (typeid (*mode) == typeid (EncryptionModeCBC))
|
||||
{
|
||||
if (typeid (ea) == typeid (AES) && crc != 0x2274f53d) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (AESBlowfish) && crc != 0xa7a80c84) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (AESBlowfishSerpent) && crc != 0xa0584562) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (AESTwofish) && crc != 0x3c226444) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (AESTwofishSerpent) && crc != 0x5e5e77fd) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (Blowfish) && crc != 0x033899a1) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (Cast5) && crc != 0x331cecc7) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (Serpent) && crc != 0x42dff3d4) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (TripleDES) && crc != 0xfe497d0c) throw TestFailed (SRC_POS);
|
||||
if (typeid (ea) == typeid (TwofishSerpent) && crc != 0xa7b659f3) throw TestFailed (SRC_POS);
|
||||
}
|
||||
|
||||
ea.DecryptSectors (buf, secNo, sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct CipherTestVector
|
||||
{
|
||||
byte Key[32];
|
||||
byte Plaintext[16];
|
||||
byte Ciphertext[16];
|
||||
};
|
||||
|
||||
static const CipherTestVector AESTestVectors[] =
|
||||
{
|
||||
{
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
},
|
||||
{
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
|
||||
},
|
||||
{
|
||||
0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const CipherTestVector SerpentTestVectors[] =
|
||||
{
|
||||
{
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||
},
|
||||
{
|
||||
0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8, 0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const CipherTestVector TwofishTestVectors[] =
|
||||
{
|
||||
{
|
||||
{
|
||||
0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
|
||||
0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F
|
||||
},
|
||||
{
|
||||
0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6
|
||||
},
|
||||
{
|
||||
0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void TestCipher (Cipher &cipher, const CipherTestVector *testVector, size_t testVectorCount)
|
||||
{
|
||||
Buffer buffer (cipher.GetBlockSize());
|
||||
for (size_t i = 0; i < testVectorCount; ++i)
|
||||
{
|
||||
cipher.SetKey (ConstBufferPtr (testVector[i].Key, sizeof (testVector[i].Key)));
|
||||
buffer.CopyFrom (ConstBufferPtr (testVector[i].Plaintext, sizeof (testVector[i].Plaintext)));
|
||||
cipher.EncryptBlock (buffer);
|
||||
|
||||
if (memcmp (buffer, testVector[i].Ciphertext, buffer.Size()) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
}
|
||||
}
|
||||
|
||||
void EncryptionTest::TestCiphers ()
|
||||
{
|
||||
CipherAES aes;
|
||||
TestCipher (aes, AESTestVectors, array_capacity (AESTestVectors));
|
||||
|
||||
Buffer testData (1024);
|
||||
for (size_t i = 0; i < testData.Size(); ++i)
|
||||
{
|
||||
testData[i] = (byte) i;
|
||||
}
|
||||
|
||||
uint32 origCrc = Crc32::ProcessBuffer (testData);
|
||||
|
||||
aes.SetKey (ConstBufferPtr (testData, aes.GetKeySize()));
|
||||
aes.EncryptBlocks (testData, testData.Size() / aes.GetBlockSize());
|
||||
|
||||
if (Crc32::ProcessBuffer (testData) != 0xb5cd5631)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
aes.DecryptBlocks (testData, testData.Size() / aes.GetBlockSize());
|
||||
|
||||
if (origCrc != Crc32::ProcessBuffer (testData))
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
CipherSerpent serpent;
|
||||
TestCipher (serpent, SerpentTestVectors, array_capacity (SerpentTestVectors));
|
||||
|
||||
CipherTwofish twofish;
|
||||
TestCipher (twofish, TwofishTestVectors, array_capacity (TwofishTestVectors));
|
||||
}
|
||||
|
||||
const EncryptionTest::XtsTestVector EncryptionTest::XtsTestVectors[] =
|
||||
{
|
||||
/* XTS-AES-256 */
|
||||
{
|
||||
// IEEE 1619 - Vector 10
|
||||
|
||||
{ 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27 },
|
||||
{ 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff },
|
||||
0,
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
},
|
||||
{
|
||||
0x1c, 0x3b, 0x3a, 0x10, 0x2f, 0x77, 0x03, 0x86, 0xe4, 0x83, 0x6c, 0x99, 0xe3, 0x70, 0xcf, 0x9b, 0xea, 0x00, 0x80, 0x3f, 0x5e, 0x48, 0x23, 0x57, 0xa4, 0xae, 0x12, 0xd4, 0x14, 0xa3, 0xe6, 0x3b,
|
||||
0x5d, 0x31, 0xe2, 0x76, 0xf8, 0xfe, 0x4a, 0x8d, 0x66, 0xb3, 0x17, 0xf9, 0xac, 0x68, 0x3f, 0x44, 0x68, 0x0a, 0x86, 0xac, 0x35, 0xad, 0xfc, 0x33, 0x45, 0xbe, 0xfe, 0xcb, 0x4b, 0xb1, 0x88, 0xfd,
|
||||
0x57, 0x76, 0x92, 0x6c, 0x49, 0xa3, 0x09, 0x5e, 0xb1, 0x08, 0xfd, 0x10, 0x98, 0xba, 0xec, 0x70, 0xaa, 0xa6, 0x69, 0x99, 0xa7, 0x2a, 0x82, 0xf2, 0x7d, 0x84, 0x8b, 0x21, 0xd4, 0xa7, 0x41, 0xb0,
|
||||
0xc5, 0xcd, 0x4d, 0x5f, 0xff, 0x9d, 0xac, 0x89, 0xae, 0xba, 0x12, 0x29, 0x61, 0xd0, 0x3a, 0x75, 0x71, 0x23, 0xe9, 0x87, 0x0f, 0x8a, 0xcf, 0x10, 0x00, 0x02, 0x08, 0x87, 0x89, 0x14, 0x29, 0xca,
|
||||
0x2a, 0x3e, 0x7a, 0x7d, 0x7d, 0xf7, 0xb1, 0x03, 0x55, 0x16, 0x5c, 0x8b, 0x9a, 0x6d, 0x0a, 0x7d, 0xe8, 0xb0, 0x62, 0xc4, 0x50, 0x0d, 0xc4, 0xcd, 0x12, 0x0c, 0x0f, 0x74, 0x18, 0xda, 0xe3, 0xd0,
|
||||
0xb5, 0x78, 0x1c, 0x34, 0x80, 0x3f, 0xa7, 0x54, 0x21, 0xc7, 0x90, 0xdf, 0xe1, 0xde, 0x18, 0x34, 0xf2, 0x80, 0xd7, 0x66, 0x7b, 0x32, 0x7f, 0x6c, 0x8c, 0xd7, 0x55, 0x7e, 0x12, 0xac, 0x3a, 0x0f,
|
||||
0x93, 0xec, 0x05, 0xc5, 0x2e, 0x04, 0x93, 0xef, 0x31, 0xa1, 0x2d, 0x3d, 0x92, 0x60, 0xf7, 0x9a, 0x28, 0x9d, 0x6a, 0x37, 0x9b, 0xc7, 0x0c, 0x50, 0x84, 0x14, 0x73, 0xd1, 0xa8, 0xcc, 0x81, 0xec,
|
||||
0x58, 0x3e, 0x96, 0x45, 0xe0, 0x7b, 0x8d, 0x96, 0x70, 0x65, 0x5b, 0xa5, 0xbb, 0xcf, 0xec, 0xc6, 0xdc, 0x39, 0x66, 0x38, 0x0a, 0xd8, 0xfe, 0xcb, 0x17, 0xb6, 0xba, 0x02, 0x46, 0x9a, 0x02, 0x0a,
|
||||
0x84, 0xe1, 0x8e, 0x8f, 0x84, 0x25, 0x20, 0x70, 0xc1, 0x3e, 0x9f, 0x1f, 0x28, 0x9b, 0xe5, 0x4f, 0xbc, 0x48, 0x14, 0x57, 0x77, 0x8f, 0x61, 0x60, 0x15, 0xe1, 0x32, 0x7a, 0x02, 0xb1, 0x40, 0xf1,
|
||||
0x50, 0x5e, 0xb3, 0x09, 0x32, 0x6d, 0x68, 0x37, 0x8f, 0x83, 0x74, 0x59, 0x5c, 0x84, 0x9d, 0x84, 0xf4, 0xc3, 0x33, 0xec, 0x44, 0x23, 0x88, 0x51, 0x43, 0xcb, 0x47, 0xbd, 0x71, 0xc5, 0xed, 0xae,
|
||||
0x9b, 0xe6, 0x9a, 0x2f, 0xfe, 0xce, 0xb1, 0xbe, 0xc9, 0xde, 0x24, 0x4f, 0xbe, 0x15, 0x99, 0x2b, 0x11, 0xb7, 0x7c, 0x04, 0x0f, 0x12, 0xbd, 0x8f, 0x6a, 0x97, 0x5a, 0x44, 0xa0, 0xf9, 0x0c, 0x29,
|
||||
0xa9, 0xab, 0xc3, 0xd4, 0xd8, 0x93, 0x92, 0x72, 0x84, 0xc5, 0x87, 0x54, 0xcc, 0xe2, 0x94, 0x52, 0x9f, 0x86, 0x14, 0xdc, 0xd2, 0xab, 0xa9, 0x91, 0x92, 0x5f, 0xed, 0xc4, 0xae, 0x74, 0xff, 0xac,
|
||||
0x6e, 0x33, 0x3b, 0x93, 0xeb, 0x4a, 0xff, 0x04, 0x79, 0xda, 0x9a, 0x41, 0x0e, 0x44, 0x50, 0xe0, 0xdd, 0x7a, 0xe4, 0xc6, 0xe2, 0x91, 0x09, 0x00, 0x57, 0x5d, 0xa4, 0x01, 0xfc, 0x07, 0x05, 0x9f,
|
||||
0x64, 0x5e, 0x8b, 0x7e, 0x9b, 0xfd, 0xef, 0x33, 0x94, 0x30, 0x54, 0xff, 0x84, 0x01, 0x14, 0x93, 0xc2, 0x7b, 0x34, 0x29, 0xea, 0xed, 0xb4, 0xed, 0x53, 0x76, 0x44, 0x1a, 0x77, 0xed, 0x43, 0x85,
|
||||
0x1a, 0xd7, 0x7f, 0x16, 0xf5, 0x41, 0xdf, 0xd2, 0x69, 0xd5, 0x0d, 0x6a, 0x5f, 0x14, 0xfb, 0x0a, 0xab, 0x1c, 0xbb, 0x4c, 0x15, 0x50, 0xbe, 0x97, 0xf7, 0xab, 0x40, 0x66, 0x19, 0x3c, 0x4c, 0xaa,
|
||||
0x77, 0x3d, 0xad, 0x38, 0x01, 0x4b, 0xd2, 0x09, 0x2f, 0xa7, 0x55, 0xc8, 0x24, 0xbb, 0x5e, 0x54, 0xc4, 0xf3, 0x6f, 0xfd, 0xa9, 0xfc, 0xea, 0x70, 0xb9, 0xc6, 0xe6, 0x93, 0xe1, 0x48, 0xc1, 0x51
|
||||
}
|
||||
},
|
||||
{
|
||||
// IEEE 1619 - Vector 11
|
||||
|
||||
{ 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27 },
|
||||
{ 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff },
|
||||
0,
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
},
|
||||
{
|
||||
0x77, 0xa3, 0x12, 0x51, 0x61, 0x8a, 0x15, 0xe6, 0xb9, 0x2d, 0x1d, 0x66, 0xdf, 0xfe, 0x7b, 0x50, 0xb5, 0x0b, 0xad, 0x55, 0x23, 0x05, 0xba, 0x02, 0x17, 0xa6, 0x10, 0x68, 0x8e, 0xff, 0x7e, 0x11,
|
||||
0xe1, 0xd0, 0x22, 0x54, 0x38, 0xe0, 0x93, 0x24, 0x2d, 0x6d, 0xb2, 0x74, 0xfd, 0xe8, 0x01, 0xd4, 0xca, 0xe0, 0x6f, 0x20, 0x92, 0xc7, 0x28, 0xb2, 0x47, 0x85, 0x59, 0xdf, 0x58, 0xe8, 0x37, 0xc2,
|
||||
0x46, 0x9e, 0xe4, 0xa4, 0xfa, 0x79, 0x4e, 0x4b, 0xbc, 0x7f, 0x39, 0xbc, 0x02, 0x6e, 0x3c, 0xb7, 0x2c, 0x33, 0xb0, 0x88, 0x8f, 0x25, 0xb4, 0xac, 0xf5, 0x6a, 0x2a, 0x98, 0x04, 0xf1, 0xce, 0x6d,
|
||||
0x3d, 0x6e, 0x1d, 0xc6, 0xca, 0x18, 0x1d, 0x4b, 0x54, 0x61, 0x79, 0xd5, 0x55, 0x44, 0xaa, 0x77, 0x60, 0xc4, 0x0d, 0x06, 0x74, 0x15, 0x39, 0xc7, 0xe3, 0xcd, 0x9d, 0x2f, 0x66, 0x50, 0xb2, 0x01,
|
||||
0x3f, 0xd0, 0xee, 0xb8, 0xc2, 0xb8, 0xe3, 0xd8, 0xd2, 0x40, 0xcc, 0xae, 0x2d, 0x4c, 0x98, 0x32, 0x0a, 0x74, 0x42, 0xe1, 0xc8, 0xd7, 0x5a, 0x42, 0xd6, 0xe6, 0xcf, 0xa4, 0xc2, 0xec, 0xa1, 0x79,
|
||||
0x8d, 0x15, 0x8c, 0x7a, 0xec, 0xdf, 0x82, 0x49, 0x0f, 0x24, 0xbb, 0x9b, 0x38, 0xe1, 0x08, 0xbc, 0xda, 0x12, 0xc3, 0xfa, 0xf9, 0xa2, 0x11, 0x41, 0xc3, 0x61, 0x3b, 0x58, 0x36, 0x7f, 0x92, 0x2a,
|
||||
0xaa, 0x26, 0xcd, 0x22, 0xf2, 0x3d, 0x70, 0x8d, 0xae, 0x69, 0x9a, 0xd7, 0xcb, 0x40, 0xa8, 0xad, 0x0b, 0x6e, 0x27, 0x84, 0x97, 0x3d, 0xcb, 0x60, 0x56, 0x84, 0xc0, 0x8b, 0x8d, 0x69, 0x98, 0xc6,
|
||||
0x9a, 0xac, 0x04, 0x99, 0x21, 0x87, 0x1e, 0xbb, 0x65, 0x30, 0x1a, 0x46, 0x19, 0xca, 0x80, 0xec, 0xb4, 0x85, 0xa3, 0x1d, 0x74, 0x42, 0x23, 0xce, 0x8d, 0xdc, 0x23, 0x94, 0x82, 0x8d, 0x6a, 0x80,
|
||||
0x47, 0x0c, 0x09, 0x2f, 0x5b, 0xa4, 0x13, 0xc3, 0x37, 0x8f, 0xa6, 0x05, 0x42, 0x55, 0xc6, 0xf9, 0xdf, 0x44, 0x95, 0x86, 0x2b, 0xbb, 0x32, 0x87, 0x68, 0x1f, 0x93, 0x1b, 0x68, 0x7c, 0x88, 0x8a,
|
||||
0xbf, 0x84, 0x4d, 0xfc, 0x8f, 0xc2, 0x83, 0x31, 0xe5, 0x79, 0x92, 0x8c, 0xd1, 0x2b, 0xd2, 0x39, 0x0a, 0xe1, 0x23, 0xcf, 0x03, 0x81, 0x8d, 0x14, 0xde, 0xdd, 0xe5, 0xc0, 0xc2, 0x4c, 0x8a, 0xb0,
|
||||
0x18, 0xbf, 0xca, 0x75, 0xca, 0x09, 0x6f, 0x2d, 0x53, 0x1f, 0x3d, 0x16, 0x19, 0xe7, 0x85, 0xf1, 0xad, 0xa4, 0x37, 0xca, 0xb9, 0x2e, 0x98, 0x05, 0x58, 0xb3, 0xdc, 0xe1, 0x47, 0x4a, 0xfb, 0x75,
|
||||
0xbf, 0xed, 0xbf, 0x8f, 0xf5, 0x4c, 0xb2, 0x61, 0x8e, 0x02, 0x44, 0xc9, 0xac, 0x0d, 0x3c, 0x66, 0xfb, 0x51, 0x59, 0x8c, 0xd2, 0xdb, 0x11, 0xf9, 0xbe, 0x39, 0x79, 0x1a, 0xbe, 0x44, 0x7c, 0x63,
|
||||
0x09, 0x4f, 0x7c, 0x45, 0x3b, 0x7f, 0xf8, 0x7c, 0xb5, 0xbb, 0x36, 0xb7, 0xc7, 0x9e, 0xfb, 0x08, 0x72, 0xd1, 0x70, 0x58, 0xb8, 0x3b, 0x15, 0xab, 0x08, 0x66, 0xad, 0x8a, 0x58, 0x65, 0x6c, 0x5a,
|
||||
0x7e, 0x20, 0xdb, 0xdf, 0x30, 0x8b, 0x24, 0x61, 0xd9, 0x7c, 0x0e, 0xc0, 0x02, 0x4a, 0x27, 0x15, 0x05, 0x52, 0x49, 0xcf, 0x3b, 0x47, 0x8d, 0xdd, 0x47, 0x40, 0xde, 0x65, 0x4f, 0x75, 0xca, 0x68,
|
||||
0x6e, 0x0d, 0x73, 0x45, 0xc6, 0x9e, 0xd5, 0x0c, 0xdc, 0x2a, 0x8b, 0x33, 0x2b, 0x1f, 0x88, 0x24, 0x10, 0x8a, 0xc9, 0x37, 0xeb, 0x05, 0x05, 0x85, 0x60, 0x8e, 0xe7, 0x34, 0x09, 0x7f, 0xc0, 0x90,
|
||||
0x54, 0xfb, 0xff, 0x89, 0xee, 0xae, 0xea, 0x79, 0x1f, 0x4a, 0x7a, 0xb1, 0xf9, 0x86, 0x82, 0x94, 0xa4, 0xf9, 0xe2, 0x7b, 0x42, 0xaf, 0x81, 0x00, 0xcb, 0x9d, 0x59, 0xce, 0xf9, 0x64, 0x58, 0x03
|
||||
}
|
||||
},
|
||||
{
|
||||
// IEEE 1619 - Vector 12
|
||||
|
||||
{ 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27 },
|
||||
{ 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff },
|
||||
0,
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
},
|
||||
{
|
||||
0xe3, 0x87, 0xaa, 0xa5, 0x8b, 0xa4, 0x83, 0xaf, 0xa7, 0xe8, 0xeb, 0x46, 0x97, 0x78, 0x31, 0x7e, 0xcf, 0x4c, 0xf5, 0x73, 0xaa, 0x9d, 0x4e, 0xac, 0x23, 0xf2, 0xcd, 0xf9, 0x14, 0xe4, 0xe2, 0x00,
|
||||
0xa8, 0xb4, 0x90, 0xe4, 0x2e, 0xe6, 0x46, 0x80, 0x2d, 0xc6, 0xee, 0x2b, 0x47, 0x1b, 0x27, 0x81, 0x95, 0xd6, 0x09, 0x18, 0xec, 0xec, 0xb4, 0x4b, 0xf7, 0x99, 0x66, 0xf8, 0x3f, 0xab, 0xa0, 0x49,
|
||||
0x92, 0x98, 0xeb, 0xc6, 0x99, 0xc0, 0xc8, 0x63, 0x47, 0x15, 0xa3, 0x20, 0xbb, 0x4f, 0x07, 0x5d, 0x62, 0x2e, 0x74, 0xc8, 0xc9, 0x32, 0x00, 0x4f, 0x25, 0xb4, 0x1e, 0x36, 0x10, 0x25, 0xb5, 0xa8,
|
||||
0x78, 0x15, 0x39, 0x1f, 0x61, 0x08, 0xfc, 0x4a, 0xfa, 0x6a, 0x05, 0xd9, 0x30, 0x3c, 0x6b, 0xa6, 0x8a, 0x12, 0x8a, 0x55, 0x70, 0x5d, 0x41, 0x59, 0x85, 0x83, 0x2f, 0xde, 0xaa, 0xe6, 0xc8, 0xe1,
|
||||
0x91, 0x10, 0xe8, 0x4d, 0x1b, 0x1f, 0x19, 0x9a, 0x26, 0x92, 0x11, 0x9e, 0xdc, 0x96, 0x13, 0x26, 0x58, 0xf0, 0x9d, 0xa7, 0xc6, 0x23, 0xef, 0xce, 0xc7, 0x12, 0x53, 0x7a, 0x3d, 0x94, 0xc0, 0xbf,
|
||||
0x5d, 0x7e, 0x35, 0x2e, 0xc9, 0x4a, 0xe5, 0x79, 0x7f, 0xdb, 0x37, 0x7d, 0xc1, 0x55, 0x11, 0x50, 0x72, 0x1a, 0xdf, 0x15, 0xbd, 0x26, 0xa8, 0xef, 0xc2, 0xfc, 0xaa, 0xd5, 0x68, 0x81, 0xfa, 0x9e,
|
||||
0x62, 0x46, 0x2c, 0x28, 0xf3, 0x0a, 0xe1, 0xce, 0xac, 0xa9, 0x3c, 0x34, 0x5c, 0xf2, 0x43, 0xb7, 0x3f, 0x54, 0x2e, 0x20, 0x74, 0xa7, 0x05, 0xbd, 0x26, 0x43, 0xbb, 0x9f, 0x7c, 0xc7, 0x9b, 0xb6,
|
||||
0xe7, 0x09, 0x1e, 0xa6, 0xe2, 0x32, 0xdf, 0x0f, 0x9a, 0xd0, 0xd6, 0xcf, 0x50, 0x23, 0x27, 0x87, 0x6d, 0x82, 0x20, 0x7a, 0xbf, 0x21, 0x15, 0xcd, 0xac, 0xf6, 0xd5, 0xa4, 0x8f, 0x6c, 0x18, 0x79,
|
||||
0xa6, 0x5b, 0x11, 0x5f, 0x0f, 0x8b, 0x3c, 0xb3, 0xc5, 0x9d, 0x15, 0xdd, 0x8c, 0x76, 0x9b, 0xc0, 0x14, 0x79, 0x5a, 0x18, 0x37, 0xf3, 0x90, 0x1b, 0x58, 0x45, 0xeb, 0x49, 0x1a, 0xdf, 0xef, 0xe0,
|
||||
0x97, 0xb1, 0xfa, 0x30, 0xa1, 0x2f, 0xc1, 0xf6, 0x5b, 0xa2, 0x29, 0x05, 0x03, 0x15, 0x39, 0x97, 0x1a, 0x10, 0xf2, 0xf3, 0x6c, 0x32, 0x1b, 0xb5, 0x13, 0x31, 0xcd, 0xef, 0xb3, 0x9e, 0x39, 0x64,
|
||||
0xc7, 0xef, 0x07, 0x99, 0x94, 0xf5, 0xb6, 0x9b, 0x2e, 0xdd, 0x83, 0xa7, 0x1e, 0xf5, 0x49, 0x97, 0x1e, 0xe9, 0x3f, 0x44, 0xea, 0xc3, 0x93, 0x8f, 0xcd, 0xd6, 0x1d, 0x01, 0xfa, 0x71, 0x79, 0x9d,
|
||||
0xa3, 0xa8, 0x09, 0x1c, 0x4c, 0x48, 0xaa, 0x9e, 0xd2, 0x63, 0xff, 0x07, 0x49, 0xdf, 0x95, 0xd4, 0x4f, 0xef, 0x6a, 0x0b, 0xb5, 0x78, 0xec, 0x69, 0x45, 0x6a, 0xa5, 0x40, 0x8a, 0xe3, 0x2c, 0x7a,
|
||||
0xf0, 0x8a, 0xd7, 0xba, 0x89, 0x21, 0x28, 0x7e, 0x3b, 0xbe, 0xe3, 0x1b, 0x76, 0x7b, 0xe0, 0x6a, 0x0e, 0x70, 0x5c, 0x86, 0x4a, 0x76, 0x91, 0x37, 0xdf, 0x28, 0x29, 0x22, 0x83, 0xea, 0x81, 0xa2,
|
||||
0x48, 0x02, 0x41, 0xb4, 0x4d, 0x99, 0x21, 0xcd, 0xbe, 0xc1, 0xbc, 0x28, 0xdc, 0x1f, 0xda, 0x11, 0x4b, 0xd8, 0xe5, 0x21, 0x7a, 0xc9, 0xd8, 0xeb, 0xaf, 0xa7, 0x20, 0xe9, 0xda, 0x4f, 0x9a, 0xce,
|
||||
0x23, 0x1c, 0xc9, 0x49, 0xe5, 0xb9, 0x6f, 0xe7, 0x6f, 0xfc, 0x21, 0x06, 0x3f, 0xdd, 0xc8, 0x3a, 0x6b, 0x86, 0x79, 0xc0, 0x0d, 0x35, 0xe0, 0x95, 0x76, 0xa8, 0x75, 0x30, 0x5b, 0xed, 0x5f, 0x36,
|
||||
0xed, 0x24, 0x2c, 0x89, 0x00, 0xdd, 0x1f, 0xa9, 0x65, 0xbc, 0x95, 0x0d, 0xfc, 0xe0, 0x9b, 0x13, 0x22, 0x63, 0xa1, 0xee, 0xf5, 0x2d, 0xd6, 0x88, 0x8c, 0x30, 0x9f, 0x5a, 0x7d, 0x71, 0x28, 0x26
|
||||
}
|
||||
},
|
||||
{
|
||||
// IEEE 1619 - Vector 13
|
||||
|
||||
{ 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27 },
|
||||
{ 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff },
|
||||
0,
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
},
|
||||
{
|
||||
0xbf, 0x53, 0xd2, 0xda, 0xde, 0x78, 0xe8, 0x22, 0xa4, 0xd9, 0x49, 0xa9, 0xbc, 0x67, 0x66, 0xb0, 0x1b, 0x06, 0xa8, 0xef, 0x70, 0xd2, 0x67, 0x48, 0xc6, 0xa7, 0xfc, 0x36, 0xd8, 0x0a, 0xe4, 0xc5,
|
||||
0x52, 0x0f, 0x7c, 0x4a, 0xb0, 0xac, 0x85, 0x44, 0x42, 0x4f, 0xa4, 0x05, 0x16, 0x2f, 0xef, 0x5a, 0x6b, 0x7f, 0x22, 0x94, 0x98, 0x06, 0x36, 0x18, 0xd3, 0x9f, 0x00, 0x03, 0xcb, 0x5f, 0xb8, 0xd1,
|
||||
0xc8, 0x6b, 0x64, 0x34, 0x97, 0xda, 0x1f, 0xf9, 0x45, 0xc8, 0xd3, 0xbe, 0xde, 0xca, 0x4f, 0x47, 0x97, 0x02, 0xa7, 0xa7, 0x35, 0xf0, 0x43, 0xdd, 0xb1, 0xd6, 0xaa, 0xad, 0xe3, 0xc4, 0xa0, 0xac,
|
||||
0x7c, 0xa7, 0xf3, 0xfa, 0x52, 0x79, 0xbe, 0xf5, 0x6f, 0x82, 0xcd, 0x7a, 0x2f, 0x38, 0x67, 0x2e, 0x82, 0x48, 0x14, 0xe1, 0x07, 0x00, 0x30, 0x0a, 0x05, 0x5e, 0x16, 0x30, 0xb8, 0xf1, 0xcb, 0x0e,
|
||||
0x91, 0x9f, 0x5e, 0x94, 0x20, 0x10, 0xa4, 0x16, 0xe2, 0xbf, 0x48, 0xcb, 0x46, 0x99, 0x3d, 0x3c, 0xb6, 0xa5, 0x1c, 0x19, 0xba, 0xcf, 0x86, 0x47, 0x85, 0xa0, 0x0b, 0xc2, 0xec, 0xff, 0x15, 0xd3,
|
||||
0x50, 0x87, 0x5b, 0x24, 0x6e, 0xd5, 0x3e, 0x68, 0xbe, 0x6f, 0x55, 0xbd, 0x7e, 0x05, 0xcf, 0xc2, 0xb2, 0xed, 0x64, 0x32, 0x19, 0x8a, 0x64, 0x44, 0xb6, 0xd8, 0xc2, 0x47, 0xfa, 0xb9, 0x41, 0xf5,
|
||||
0x69, 0x76, 0x8b, 0x5c, 0x42, 0x93, 0x66, 0xf1, 0xd3, 0xf0, 0x0f, 0x03, 0x45, 0xb9, 0x61, 0x23, 0xd5, 0x62, 0x04, 0xc0, 0x1c, 0x63, 0xb2, 0x2c, 0xe7, 0x8b, 0xaf, 0x11, 0x6e, 0x52, 0x5e, 0xd9,
|
||||
0x0f, 0xde, 0xa3, 0x9f, 0xa4, 0x69, 0x49, 0x4d, 0x38, 0x66, 0xc3, 0x1e, 0x05, 0xf2, 0x95, 0xff, 0x21, 0xfe, 0xa8, 0xd4, 0xe6, 0xe1, 0x3d, 0x67, 0xe4, 0x7c, 0xe7, 0x22, 0xe9, 0x69, 0x8a, 0x1c,
|
||||
0x10, 0x48, 0xd6, 0x8e, 0xbc, 0xde, 0x76, 0xb8, 0x6f, 0xcf, 0x97, 0x6e, 0xab, 0x8a, 0xa9, 0x79, 0x02, 0x68, 0xb7, 0x06, 0x8e, 0x01, 0x7a, 0x8b, 0x9b, 0x74, 0x94, 0x09, 0x51, 0x4f, 0x10, 0x53,
|
||||
0x02, 0x7f, 0xd1, 0x6c, 0x37, 0x86, 0xea, 0x1b, 0xac, 0x5f, 0x15, 0xcb, 0x79, 0x71, 0x1e, 0xe2, 0xab, 0xe8, 0x2f, 0x5c, 0xf8, 0xb1, 0x3a, 0xe7, 0x30, 0x30, 0xef, 0x5b, 0x9e, 0x44, 0x57, 0xe7,
|
||||
0x5d, 0x13, 0x04, 0xf9, 0x88, 0xd6, 0x2d, 0xd6, 0xfc, 0x4b, 0x94, 0xed, 0x38, 0xba, 0x83, 0x1d, 0xa4, 0xb7, 0x63, 0x49, 0x71, 0xb6, 0xcd, 0x8e, 0xc3, 0x25, 0xd9, 0xc6, 0x1c, 0x00, 0xf1, 0xdf,
|
||||
0x73, 0x62, 0x7e, 0xd3, 0x74, 0x5a, 0x5e, 0x84, 0x89, 0xf3, 0xa9, 0x5c, 0x69, 0x63, 0x9c, 0x32, 0xcd, 0x6e, 0x1d, 0x53, 0x7a, 0x85, 0xf7, 0x5c, 0xc8, 0x44, 0x72, 0x6e, 0x8a, 0x72, 0xfc, 0x00,
|
||||
0x77, 0xad, 0x22, 0x00, 0x0f, 0x1d, 0x50, 0x78, 0xf6, 0xb8, 0x66, 0x31, 0x8c, 0x66, 0x8f, 0x1a, 0xd0, 0x3d, 0x5a, 0x5f, 0xce, 0xd5, 0x21, 0x9f, 0x2e, 0xab, 0xbd, 0x0a, 0xa5, 0xc0, 0xf4, 0x60,
|
||||
0xd1, 0x83, 0xf0, 0x44, 0x04, 0xa0, 0xd6, 0xf4, 0x69, 0x55, 0x8e, 0x81, 0xfa, 0xb2, 0x4a, 0x16, 0x79, 0x05, 0xab, 0x4c, 0x78, 0x78, 0x50, 0x2a, 0xd3, 0xe3, 0x8f, 0xdb, 0xe6, 0x2a, 0x41, 0x55,
|
||||
0x6c, 0xec, 0x37, 0x32, 0x57, 0x59, 0x53, 0x3c, 0xe8, 0xf2, 0x5f, 0x36, 0x7c, 0x87, 0xbb, 0x55, 0x78, 0xd6, 0x67, 0xae, 0x93, 0xf9, 0xe2, 0xfd, 0x99, 0xbc, 0xbc, 0x5f, 0x2f, 0xbb, 0xa8, 0x8c,
|
||||
0xf6, 0x51, 0x61, 0x39, 0x42, 0x0f, 0xcf, 0xf3, 0xb7, 0x36, 0x1d, 0x86, 0x32, 0x2c, 0x4b, 0xd8, 0x4c, 0x82, 0xf3, 0x35, 0xab, 0xb1, 0x52, 0xc4, 0xa9, 0x34, 0x11, 0x37, 0x3a, 0xaa, 0x82, 0x20
|
||||
}
|
||||
},
|
||||
{
|
||||
// IEEE 1619 - Vector 14
|
||||
|
||||
{ 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27 },
|
||||
{ 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92 },
|
||||
{ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff },
|
||||
0,
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
},
|
||||
{
|
||||
0x64, 0x49, 0x7e, 0x5a, 0x83, 0x1e, 0x4a, 0x93, 0x2c, 0x09, 0xbe, 0x3e, 0x53, 0x93, 0x37, 0x6d, 0xaa, 0x59, 0x95, 0x48, 0xb8, 0x16, 0x03, 0x1d, 0x22, 0x4b, 0xbf, 0x50, 0xa8, 0x18, 0xed, 0x23,
|
||||
0x50, 0xea, 0xe7, 0xe9, 0x60, 0x87, 0xc8, 0xa0, 0xdb, 0x51, 0xad, 0x29, 0x0b, 0xd0, 0x0c, 0x1a, 0xc1, 0x62, 0x08, 0x57, 0x63, 0x5b, 0xf2, 0x46, 0xc1, 0x76, 0xab, 0x46, 0x3b, 0xe3, 0x0b, 0x80,
|
||||
0x8d, 0xa5, 0x48, 0x08, 0x1a, 0xc8, 0x47, 0xb1, 0x58, 0xe1, 0x26, 0x4b, 0xe2, 0x5b, 0xb0, 0x91, 0x0b, 0xbc, 0x92, 0x64, 0x71, 0x08, 0x08, 0x94, 0x15, 0xd4, 0x5f, 0xab, 0x1b, 0x3d, 0x26, 0x04,
|
||||
0xe8, 0xa8, 0xef, 0xf1, 0xae, 0x40, 0x20, 0xcf, 0xa3, 0x99, 0x36, 0xb6, 0x68, 0x27, 0xb2, 0x3f, 0x37, 0x1b, 0x92, 0x20, 0x0b, 0xe9, 0x02, 0x51, 0xe6, 0xd7, 0x3c, 0x5f, 0x86, 0xde, 0x5f, 0xd4,
|
||||
0xa9, 0x50, 0x78, 0x19, 0x33, 0xd7, 0x9a, 0x28, 0x27, 0x2b, 0x78, 0x2a, 0x2e, 0xc3, 0x13, 0xef, 0xdf, 0xcc, 0x06, 0x28, 0xf4, 0x3d, 0x74, 0x4c, 0x2d, 0xc2, 0xff, 0x3d, 0xcb, 0x66, 0x99, 0x9b,
|
||||
0x50, 0xc7, 0xca, 0x89, 0x5b, 0x0c, 0x64, 0x79, 0x1e, 0xea, 0xa5, 0xf2, 0x94, 0x99, 0xfb, 0x1c, 0x02, 0x6f, 0x84, 0xce, 0x5b, 0x5c, 0x72, 0xba, 0x10, 0x83, 0xcd, 0xdb, 0x5c, 0xe4, 0x54, 0x34,
|
||||
0x63, 0x16, 0x65, 0xc3, 0x33, 0xb6, 0x0b, 0x11, 0x59, 0x3f, 0xb2, 0x53, 0xc5, 0x17, 0x9a, 0x2c, 0x8d, 0xb8, 0x13, 0x78, 0x2a, 0x00, 0x48, 0x56, 0xa1, 0x65, 0x30, 0x11, 0xe9, 0x3f, 0xb6, 0xd8,
|
||||
0x76, 0xc1, 0x83, 0x66, 0xdd, 0x86, 0x83, 0xf5, 0x34, 0x12, 0xc0, 0xc1, 0x80, 0xf9, 0xc8, 0x48, 0x59, 0x2d, 0x59, 0x3f, 0x86, 0x09, 0xca, 0x73, 0x63, 0x17, 0xd3, 0x56, 0xe1, 0x3e, 0x2b, 0xff,
|
||||
0x3a, 0x9f, 0x59, 0xcd, 0x9a, 0xeb, 0x19, 0xcd, 0x48, 0x25, 0x93, 0xd8, 0xc4, 0x61, 0x28, 0xbb, 0x32, 0x42, 0x3b, 0x37, 0xa9, 0xad, 0xfb, 0x48, 0x2b, 0x99, 0x45, 0x3f, 0xbe, 0x25, 0xa4, 0x1b,
|
||||
0xf6, 0xfe, 0xb4, 0xaa, 0x0b, 0xef, 0x5e, 0xd2, 0x4b, 0xf7, 0x3c, 0x76, 0x29, 0x78, 0x02, 0x54, 0x82, 0xc1, 0x31, 0x15, 0xe4, 0x01, 0x5a, 0xac, 0x99, 0x2e, 0x56, 0x13, 0xa3, 0xb5, 0xc2, 0xf6,
|
||||
0x85, 0xb8, 0x47, 0x95, 0xcb, 0x6e, 0x9b, 0x26, 0x56, 0xd8, 0xc8, 0x81, 0x57, 0xe5, 0x2c, 0x42, 0xf9, 0x78, 0xd8, 0x63, 0x4c, 0x43, 0xd0, 0x6f, 0xea, 0x92, 0x8f, 0x28, 0x22, 0xe4, 0x65, 0xaa,
|
||||
0x65, 0x76, 0xe9, 0xbf, 0x41, 0x93, 0x84, 0x50, 0x6c, 0xc3, 0xce, 0x3c, 0x54, 0xac, 0x1a, 0x6f, 0x67, 0xdc, 0x66, 0xf3, 0xb3, 0x01, 0x91, 0xe6, 0x98, 0x38, 0x0b, 0xc9, 0x99, 0xb0, 0x5a, 0xbc,
|
||||
0xe1, 0x9d, 0xc0, 0xc6, 0xdc, 0xc2, 0xdd, 0x00, 0x1e, 0xc5, 0x35, 0xba, 0x18, 0xde, 0xb2, 0xdf, 0x1a, 0x10, 0x10, 0x23, 0x10, 0x83, 0x18, 0xc7, 0x5d, 0xc9, 0x86, 0x11, 0xa0, 0x9d, 0xc4, 0x8a,
|
||||
0x0a, 0xcd, 0xec, 0x67, 0x6f, 0xab, 0xdf, 0x22, 0x2f, 0x07, 0xe0, 0x26, 0xf0, 0x59, 0xb6, 0x72, 0xb5, 0x6e, 0x5c, 0xbc, 0x8e, 0x1d, 0x21, 0xbb, 0xd8, 0x67, 0xdd, 0x92, 0x72, 0x12, 0x05, 0x46,
|
||||
0x81, 0xd7, 0x0e, 0xa7, 0x37, 0x13, 0x4c, 0xdf, 0xce, 0x93, 0xb6, 0xf8, 0x2a, 0xe2, 0x24, 0x23, 0x27, 0x4e, 0x58, 0xa0, 0x82, 0x1c, 0xc5, 0x50, 0x2e, 0x2d, 0x0a, 0xb4, 0x58, 0x5e, 0x94, 0xde,
|
||||
0x69, 0x75, 0xbe, 0x5e, 0x0b, 0x4e, 0xfc, 0xe5, 0x1c, 0xd3, 0xe7, 0x0c, 0x25, 0xa1, 0xfb, 0xbb, 0xd6, 0x09, 0xd2, 0x73, 0xad, 0x5b, 0x0d, 0x59, 0x63, 0x1c, 0x53, 0x1f, 0x6a, 0x0a, 0x57, 0xb9
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void EncryptionTest::TestXtsAES ()
|
||||
{
|
||||
unsigned __int8 p[ENCRYPTION_DATA_UNIT_SIZE];
|
||||
uint64 dataUnitNo;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < array_capacity (XtsTestVectors); i++)
|
||||
{
|
||||
AES aes;
|
||||
shared_ptr <EncryptionMode> xts (new EncryptionModeXTS);
|
||||
|
||||
aes.SetKey (ConstBufferPtr (XtsTestVectors[i].key1, sizeof (XtsTestVectors[i].key1)));
|
||||
xts->SetKey (ConstBufferPtr (XtsTestVectors[i].key2, sizeof (XtsTestVectors[i].key2)));
|
||||
aes.SetMode (xts);
|
||||
|
||||
memcpy (p, XtsTestVectors[i].plaintext, sizeof (p));
|
||||
|
||||
dataUnitNo = Endian::Big (*((uint64 *) XtsTestVectors[i].dataUnitNo));
|
||||
|
||||
aes.EncryptSectors (p, dataUnitNo, sizeof (p) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
|
||||
aes.DecryptSectors (p, dataUnitNo, sizeof (p) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
if (memcmp (XtsTestVectors[i].ciphertext, p, sizeof (p)) == 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
aes.EncryptSectors (p, dataUnitNo, sizeof (p) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
|
||||
if (memcmp (XtsTestVectors[i].ciphertext, p, sizeof (p)) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
}
|
||||
}
|
||||
|
||||
void EncryptionTest::TestXts ()
|
||||
{
|
||||
unsigned char buf [ENCRYPTION_DATA_UNIT_SIZE * 4];
|
||||
unsigned int i;
|
||||
uint32 crc;
|
||||
uint64 unitNo;
|
||||
uint64 nbrUnits;
|
||||
uint64 writeOffset;
|
||||
int testCase = 0;
|
||||
int nTestsPerformed = 0;
|
||||
|
||||
static const byte testKey[] =
|
||||
{
|
||||
0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27,
|
||||
0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13
|
||||
};
|
||||
|
||||
/* Encryption/decryption of data units (typically, volume data sectors) */
|
||||
|
||||
nbrUnits = sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE;
|
||||
|
||||
/* The buffer can accommodate 4 data units and we'll test 4 cases by "scrolling". The data unit 0xFFFFFFFFFF
|
||||
will "move" from the start of the buffer to its end. For a 512-byte data unit, the byte offset 562949953420800
|
||||
corresponds to the data unit 0xFFFFFFFFFF. */
|
||||
for (writeOffset = 562949953420800LL;
|
||||
writeOffset > 562949953420800LL - nbrUnits * ENCRYPTION_DATA_UNIT_SIZE;
|
||||
writeOffset -= ENCRYPTION_DATA_UNIT_SIZE)
|
||||
{
|
||||
unitNo = writeOffset / ENCRYPTION_DATA_UNIT_SIZE;
|
||||
|
||||
// Test all EAs that support this mode of operation
|
||||
foreach_ref (EncryptionAlgorithm &ea, EncryptionAlgorithm::GetAvailableAlgorithms())
|
||||
{
|
||||
shared_ptr <EncryptionMode> mode (new EncryptionModeXTS);
|
||||
|
||||
if (!ea.IsModeSupported (mode))
|
||||
continue;
|
||||
|
||||
ea.SetKey (ConstBufferPtr (testKey, ea.GetKeySize()));
|
||||
|
||||
Buffer modeKey (ea.GetKeySize());
|
||||
for (size_t mi = 0; mi < modeKey.Size(); mi++)
|
||||
modeKey[mi] = (byte) mi;
|
||||
modeKey.CopyFrom (ConstBufferPtr (XtsTestVectors[array_capacity (XtsTestVectors)-1].key2, sizeof (XtsTestVectors[array_capacity (XtsTestVectors)-1].key2)));
|
||||
|
||||
mode->SetKey (modeKey);
|
||||
ea.SetMode (mode);
|
||||
|
||||
// Each data unit will contain the same plaintext
|
||||
for (i = 0; i < nbrUnits; i++)
|
||||
{
|
||||
memcpy ((unsigned char *) buf + i * ENCRYPTION_DATA_UNIT_SIZE,
|
||||
XtsTestVectors[array_capacity (XtsTestVectors)-1].plaintext,
|
||||
ENCRYPTION_DATA_UNIT_SIZE);
|
||||
}
|
||||
|
||||
ea.EncryptSectors (buf, unitNo, nbrUnits, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
|
||||
crc = GetCrc32 (buf, sizeof (buf));
|
||||
|
||||
if (typeid (ea) == typeid (AES))
|
||||
{
|
||||
// Verify the ciphertext of the "moving" data unit using the IEEE test vector #14
|
||||
if (memcmp (XtsTestVectors[array_capacity (XtsTestVectors)-1].ciphertext,
|
||||
(unsigned char *) buf + testCase * ENCRYPTION_DATA_UNIT_SIZE,
|
||||
ENCRYPTION_DATA_UNIT_SIZE) != 0)
|
||||
{
|
||||
throw TestFailed (SRC_POS);
|
||||
}
|
||||
|
||||
// CRC of all data units in the buffer for each test case
|
||||
switch (testCase)
|
||||
{
|
||||
case 0:
|
||||
if (crc != 0x888f2990)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 1:
|
||||
if (crc != 0xea28ea34)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 2:
|
||||
if (crc != 0xe058f5a2)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 3:
|
||||
if (crc != 0x10473dc9)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (typeid (ea) == typeid (Serpent))
|
||||
{
|
||||
switch (testCase)
|
||||
{
|
||||
case 0:
|
||||
if (crc != 0x7edfecb3)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 1:
|
||||
if (crc != 0x357baaaa)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 2:
|
||||
if (crc != 0xc7b9fca5)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 3:
|
||||
if (crc != 0xb5263e0c)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (typeid (ea) == typeid (Twofish))
|
||||
{
|
||||
switch (testCase)
|
||||
{
|
||||
case 0:
|
||||
if (crc != 0x91525124)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 1:
|
||||
if (crc != 0x2895cc47)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 2:
|
||||
if (crc != 0x6bee346d)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 3:
|
||||
if (crc != 0xb1c45759)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (typeid (ea) == typeid (AESTwofish))
|
||||
{
|
||||
switch (testCase)
|
||||
{
|
||||
case 0:
|
||||
if (crc != 0x6cea7fa2)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 1:
|
||||
if (crc != 0x69052c4c)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 2:
|
||||
if (crc != 0x88db8de5)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 3:
|
||||
if (crc != 0xf16fd8c5)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (typeid (ea) == typeid (AESTwofishSerpent))
|
||||
{
|
||||
switch (testCase)
|
||||
{
|
||||
case 0:
|
||||
if (crc != 0xa2d7d82a)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 1:
|
||||
if (crc != 0xdbf76412)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 2:
|
||||
if (crc != 0xdf0ea03e)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 3:
|
||||
if (crc != 0xdadedff7)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (typeid (ea) == typeid (SerpentAES))
|
||||
{
|
||||
switch (testCase)
|
||||
{
|
||||
case 0:
|
||||
if (crc != 0x6dd133b3)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 1:
|
||||
if (crc != 0x0e5717d2)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 2:
|
||||
if (crc != 0x39f83cd9)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 3:
|
||||
if (crc != 0x8a79fa2c)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (typeid (ea) == typeid (SerpentTwofishAES))
|
||||
{
|
||||
switch (testCase)
|
||||
{
|
||||
case 0:
|
||||
if (crc != 0xe536daf8)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 1:
|
||||
if (crc != 0x3ae89e7f)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 2:
|
||||
if (crc != 0x2cc1301a)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 3:
|
||||
if (crc != 0xcac7bdc7)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (typeid (ea) == typeid (TwofishSerpent))
|
||||
{
|
||||
switch (testCase)
|
||||
{
|
||||
case 0:
|
||||
if (crc != 0x2686c859)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 1:
|
||||
if (crc != 0x8a201780)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 2:
|
||||
if (crc != 0x8dd13796)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
case 3:
|
||||
if (crc != 0xe95196cb)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (crc == 0x9f5edd58)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
ea.DecryptSectors (buf, unitNo, nbrUnits, ENCRYPTION_DATA_UNIT_SIZE);
|
||||
|
||||
if (GetCrc32 (buf, sizeof (buf)) != 0x9f5edd58)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
nTestsPerformed++;
|
||||
}
|
||||
testCase++;
|
||||
}
|
||||
|
||||
/* Encryption/decryption of a buffer (typically, a volume header) */
|
||||
|
||||
nbrUnits = sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE;
|
||||
|
||||
// Test all EAs that support this mode of operation
|
||||
foreach_ref (EncryptionAlgorithm &ea, EncryptionAlgorithm::GetAvailableAlgorithms())
|
||||
{
|
||||
shared_ptr <EncryptionMode> mode (new EncryptionModeXTS);
|
||||
|
||||
if (!ea.IsModeSupported (mode))
|
||||
continue;
|
||||
|
||||
ea.SetKey (ConstBufferPtr (testKey, ea.GetKeySize()));
|
||||
|
||||
Buffer modeKey (ea.GetKeySize());
|
||||
for (size_t mi = 0; mi < modeKey.Size(); mi++)
|
||||
modeKey[mi] = (byte) mi;
|
||||
modeKey.CopyFrom (ConstBufferPtr (XtsTestVectors[array_capacity (XtsTestVectors)-1].key2, sizeof (XtsTestVectors[array_capacity (XtsTestVectors)-1].key2)));
|
||||
|
||||
mode->SetKey (modeKey);
|
||||
ea.SetMode (mode);
|
||||
|
||||
// Each data unit will contain the same plaintext
|
||||
for (i = 0; i < nbrUnits; i++)
|
||||
{
|
||||
memcpy ((unsigned char *) buf + i * ENCRYPTION_DATA_UNIT_SIZE,
|
||||
XtsTestVectors[array_capacity (XtsTestVectors)-1].plaintext,
|
||||
ENCRYPTION_DATA_UNIT_SIZE);
|
||||
}
|
||||
|
||||
ea.Encrypt (buf, sizeof (buf));
|
||||
|
||||
crc = GetCrc32 (buf, sizeof (buf));
|
||||
|
||||
if (typeid (ea) == typeid (AES))
|
||||
{
|
||||
if (crc != 0x33b91fab)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
}
|
||||
else if (typeid (ea) == typeid (Serpent))
|
||||
{
|
||||
if (crc != 0x3494d480)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
}
|
||||
else if (typeid (ea) == typeid (Twofish))
|
||||
{
|
||||
if (crc != 0xc4d65b46)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
}
|
||||
else if (typeid (ea) == typeid (AESTwofish))
|
||||
{
|
||||
if (crc != 0x14ce7385)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
}
|
||||
else if (typeid (ea) == typeid (AESTwofishSerpent))
|
||||
{
|
||||
if (crc != 0x0ec81bf7)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
}
|
||||
else if (typeid (ea) == typeid (SerpentAES))
|
||||
{
|
||||
if (crc != 0x42f919ad)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
}
|
||||
else if (typeid (ea) == typeid (SerpentTwofishAES))
|
||||
{
|
||||
if (crc != 0x208d5c58)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
}
|
||||
else if (typeid (ea) == typeid (TwofishSerpent))
|
||||
{
|
||||
if (crc != 0xbe78cec1)
|
||||
throw TestFailed (SRC_POS);
|
||||
nTestsPerformed++;
|
||||
}
|
||||
|
||||
if (crc == 0x9f5edd58)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
ea.Decrypt (buf, sizeof (buf));
|
||||
|
||||
if (GetCrc32 (buf, sizeof (buf)) != 0x9f5edd58)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
nTestsPerformed++;
|
||||
}
|
||||
|
||||
if (nTestsPerformed != 80)
|
||||
throw TestFailed (SRC_POS);
|
||||
}
|
||||
|
||||
void EncryptionTest::TestPkcs5 ()
|
||||
{
|
||||
VolumePassword password ("password", 8);
|
||||
static const byte saltData[] = { 0x12, 0x34, 0x56, 0x78 };
|
||||
ConstBufferPtr salt (saltData, sizeof (saltData));
|
||||
Buffer derivedKey (4);
|
||||
|
||||
Pkcs5HmacRipemd160 pkcs5HmacRipemd160;
|
||||
pkcs5HmacRipemd160.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (memcmp (derivedKey.Ptr(), "\x7a\x3d\x7c\x03", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
Pkcs5HmacSha1 pkcs5HmacSha1;
|
||||
pkcs5HmacSha1.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (memcmp (derivedKey.Ptr(), "\x5c\x75\xce\xf0", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
Pkcs5HmacSha512 pkcs5HmacSha512;
|
||||
pkcs5HmacSha512.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (memcmp (derivedKey.Ptr(), "\x13\x64\xae\xf8", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
|
||||
Pkcs5HmacWhirlpool pkcs5HmacWhirlpool;
|
||||
pkcs5HmacWhirlpool.DeriveKey (derivedKey, password, salt, 5);
|
||||
if (memcmp (derivedKey.Ptr(), "\x50\x7c\x36\x6f", 4) != 0)
|
||||
throw TestFailed (SRC_POS);
|
||||
}
|
||||
}
|
||||
50
src/Volume/EncryptionTest.h
Normal file
50
src/Volume/EncryptionTest.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_EncryptionTest
|
||||
#define TC_HEADER_Encryption_EncryptionTest
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Common/Crypto.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class EncryptionTest
|
||||
{
|
||||
public:
|
||||
static void TestAll ();
|
||||
static void TestAll (bool enableCpuEncryptionSupport);
|
||||
|
||||
protected:
|
||||
static void TestCiphers ();
|
||||
static void TestLegacyModes ();
|
||||
static void TestPkcs5 ();
|
||||
static void TestXts ();
|
||||
static void TestXtsAES ();
|
||||
|
||||
struct XtsTestVector
|
||||
{
|
||||
byte key1[32];
|
||||
byte key2[32];
|
||||
byte dataUnitNo[8];
|
||||
unsigned int blockNo;
|
||||
byte plaintext[ENCRYPTION_DATA_UNIT_SIZE];
|
||||
byte ciphertext[ENCRYPTION_DATA_UNIT_SIZE];
|
||||
};
|
||||
|
||||
static const XtsTestVector XtsTestVectors[];
|
||||
|
||||
private:
|
||||
EncryptionTest ();
|
||||
virtual ~EncryptionTest ();
|
||||
EncryptionTest (const EncryptionTest &);
|
||||
EncryptionTest &operator= (const EncryptionTest &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_EncryptionTest
|
||||
325
src/Volume/EncryptionThreadPool.cpp
Normal file
325
src/Volume/EncryptionThreadPool.cpp
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifdef TC_UNIX
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef TC_MACOSX
|
||||
# include <sys/types.h>
|
||||
# include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include "Platform/SyncEvent.h"
|
||||
#include "Platform/SystemLog.h"
|
||||
#include "Common/Crypto.h"
|
||||
#include "EncryptionThreadPool.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
void EncryptionThreadPool::DoWork (WorkType::Enum type, const EncryptionMode *encryptionMode, byte *data, uint64 startUnitNo, uint64 unitCount, size_t sectorSize)
|
||||
{
|
||||
size_t fragmentCount;
|
||||
size_t unitsPerFragment;
|
||||
size_t remainder;
|
||||
|
||||
byte *fragmentData;
|
||||
uint64 fragmentStartUnitNo;
|
||||
|
||||
WorkItem *workItem;
|
||||
WorkItem *firstFragmentWorkItem;
|
||||
|
||||
if (unitCount == 0)
|
||||
return;
|
||||
|
||||
if (!ThreadPoolRunning || unitCount == 1)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case WorkType::DecryptDataUnits:
|
||||
encryptionMode->DecryptSectorsCurrentThread (data, startUnitNo, unitCount, sectorSize);
|
||||
break;
|
||||
|
||||
case WorkType::EncryptDataUnits:
|
||||
encryptionMode->EncryptSectorsCurrentThread (data, startUnitNo, unitCount, sectorSize);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (unitCount <= ThreadCount)
|
||||
{
|
||||
fragmentCount = (size_t) unitCount;
|
||||
unitsPerFragment = 1;
|
||||
remainder = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentCount = ThreadCount;
|
||||
unitsPerFragment = (size_t) unitCount / ThreadCount;
|
||||
remainder = (size_t) unitCount % ThreadCount;
|
||||
|
||||
if (remainder > 0)
|
||||
++unitsPerFragment;
|
||||
}
|
||||
|
||||
fragmentData = data;
|
||||
fragmentStartUnitNo = startUnitNo;
|
||||
|
||||
{
|
||||
ScopeLock lock (EnqueueMutex);
|
||||
firstFragmentWorkItem = &WorkItemQueue[EnqueuePosition];
|
||||
|
||||
while (firstFragmentWorkItem->State != WorkItem::State::Free)
|
||||
{
|
||||
WorkItemCompletedEvent.Wait();
|
||||
}
|
||||
|
||||
firstFragmentWorkItem->OutstandingFragmentCount.Set (fragmentCount);
|
||||
firstFragmentWorkItem->ItemException.reset();
|
||||
|
||||
while (fragmentCount-- > 0)
|
||||
{
|
||||
workItem = &WorkItemQueue[EnqueuePosition++];
|
||||
|
||||
if (EnqueuePosition >= QueueSize)
|
||||
EnqueuePosition = 0;
|
||||
|
||||
while (workItem->State != WorkItem::State::Free)
|
||||
{
|
||||
WorkItemCompletedEvent.Wait();
|
||||
}
|
||||
|
||||
workItem->Type = type;
|
||||
workItem->FirstFragment = firstFragmentWorkItem;
|
||||
|
||||
workItem->Encryption.Mode = encryptionMode;
|
||||
workItem->Encryption.Data = fragmentData;
|
||||
workItem->Encryption.UnitCount = unitsPerFragment;
|
||||
workItem->Encryption.StartUnitNo = fragmentStartUnitNo;
|
||||
workItem->Encryption.SectorSize = sectorSize;
|
||||
|
||||
fragmentData += unitsPerFragment * ENCRYPTION_DATA_UNIT_SIZE;
|
||||
fragmentStartUnitNo += unitsPerFragment;
|
||||
|
||||
if (remainder > 0 && --remainder == 0)
|
||||
--unitsPerFragment;
|
||||
|
||||
workItem->State.Set (WorkItem::State::Ready);
|
||||
WorkItemReadyEvent.Signal();
|
||||
}
|
||||
}
|
||||
|
||||
firstFragmentWorkItem->ItemCompletedEvent.Wait();
|
||||
|
||||
auto_ptr <Exception> itemException;
|
||||
if (firstFragmentWorkItem->ItemException.get())
|
||||
itemException = firstFragmentWorkItem->ItemException;
|
||||
|
||||
firstFragmentWorkItem->State.Set (WorkItem::State::Free);
|
||||
WorkItemCompletedEvent.Signal();
|
||||
|
||||
if (itemException.get())
|
||||
itemException->Throw();
|
||||
}
|
||||
|
||||
void EncryptionThreadPool::Start ()
|
||||
{
|
||||
if (ThreadPoolRunning)
|
||||
return;
|
||||
|
||||
size_t cpuCount;
|
||||
|
||||
#ifdef TC_WINDOWS
|
||||
|
||||
SYSTEM_INFO sysInfo;
|
||||
GetSystemInfo (&sysInfo);
|
||||
cpuCount = sysInfo.dwNumberOfProcessors;
|
||||
|
||||
#elif defined (_SC_NPROCESSORS_ONLN)
|
||||
|
||||
cpuCount = (size_t) sysconf (_SC_NPROCESSORS_ONLN);
|
||||
if (cpuCount == (size_t) -1)
|
||||
cpuCount = 1;
|
||||
|
||||
#elif defined (TC_MACOSX)
|
||||
|
||||
int cpuCountSys;
|
||||
int mib[2] = { CTL_HW, HW_NCPU };
|
||||
|
||||
size_t len = sizeof (cpuCountSys);
|
||||
if (sysctl (mib, 2, &cpuCountSys, &len, nullptr, 0) == -1)
|
||||
cpuCountSys = 1;
|
||||
|
||||
cpuCount = (size_t) cpuCountSys;
|
||||
|
||||
#else
|
||||
# error Cannot determine CPU count
|
||||
#endif
|
||||
|
||||
if (cpuCount < 2)
|
||||
return;
|
||||
|
||||
if (cpuCount > MaxThreadCount)
|
||||
cpuCount = MaxThreadCount;
|
||||
|
||||
StopPending = false;
|
||||
DequeuePosition = 0;
|
||||
EnqueuePosition = 0;
|
||||
|
||||
for (size_t i = 0; i < sizeof (WorkItemQueue) / sizeof (WorkItemQueue[0]); ++i)
|
||||
{
|
||||
WorkItemQueue[i].State.Set (WorkItem::State::Free);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
for (ThreadCount = 0; ThreadCount < cpuCount; ++ThreadCount)
|
||||
{
|
||||
struct ThreadFunctor : public Functor
|
||||
{
|
||||
virtual void operator() ()
|
||||
{
|
||||
WorkThreadProc();
|
||||
}
|
||||
};
|
||||
|
||||
make_shared_auto (Thread, thread);
|
||||
thread->Start (new ThreadFunctor ());
|
||||
RunningThreads.push_back (thread);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
try
|
||||
{
|
||||
ThreadPoolRunning = true;
|
||||
Stop();
|
||||
} catch (...) { }
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
ThreadPoolRunning = true;
|
||||
}
|
||||
|
||||
void EncryptionThreadPool::Stop ()
|
||||
{
|
||||
if (!ThreadPoolRunning)
|
||||
return;
|
||||
|
||||
StopPending = true;
|
||||
WorkItemReadyEvent.Signal();
|
||||
|
||||
foreach_ref (const Thread &thread, RunningThreads)
|
||||
{
|
||||
thread.Join();
|
||||
}
|
||||
|
||||
ThreadCount = 0;
|
||||
ThreadPoolRunning = false;
|
||||
}
|
||||
|
||||
void EncryptionThreadPool::WorkThreadProc ()
|
||||
{
|
||||
try
|
||||
{
|
||||
WorkItem *workItem;
|
||||
|
||||
while (!StopPending)
|
||||
{
|
||||
{
|
||||
ScopeLock lock (DequeueMutex);
|
||||
|
||||
workItem = &WorkItemQueue[DequeuePosition++];
|
||||
|
||||
if (DequeuePosition >= QueueSize)
|
||||
DequeuePosition = 0;
|
||||
|
||||
while (!StopPending && workItem->State != WorkItem::State::Ready)
|
||||
{
|
||||
WorkItemReadyEvent.Wait();
|
||||
}
|
||||
|
||||
workItem->State.Set (WorkItem::State::Busy);
|
||||
}
|
||||
|
||||
if (StopPending)
|
||||
break;
|
||||
|
||||
try
|
||||
{
|
||||
switch (workItem->Type)
|
||||
{
|
||||
case WorkType::DecryptDataUnits:
|
||||
workItem->Encryption.Mode->DecryptSectorsCurrentThread (workItem->Encryption.Data, workItem->Encryption.StartUnitNo, workItem->Encryption.UnitCount, workItem->Encryption.SectorSize);
|
||||
break;
|
||||
|
||||
case WorkType::EncryptDataUnits:
|
||||
workItem->Encryption.Mode->EncryptSectorsCurrentThread (workItem->Encryption.Data, workItem->Encryption.StartUnitNo, workItem->Encryption.UnitCount, workItem->Encryption.SectorSize);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
workItem->FirstFragment->ItemException.reset (e.CloneNew());
|
||||
}
|
||||
catch (exception &e)
|
||||
{
|
||||
workItem->FirstFragment->ItemException.reset (new ExternalException (SRC_POS, StringConverter::ToExceptionString (e)));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
workItem->FirstFragment->ItemException.reset (new UnknownException (SRC_POS));
|
||||
}
|
||||
|
||||
if (workItem != workItem->FirstFragment)
|
||||
{
|
||||
workItem->State.Set (WorkItem::State::Free);
|
||||
WorkItemCompletedEvent.Signal();
|
||||
}
|
||||
|
||||
if (workItem->FirstFragment->OutstandingFragmentCount.Decrement() == 0)
|
||||
workItem->FirstFragment->ItemCompletedEvent.Signal();
|
||||
}
|
||||
}
|
||||
catch (exception &e)
|
||||
{
|
||||
SystemLog::WriteException (e);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
SystemLog::WriteException (UnknownException (SRC_POS));
|
||||
}
|
||||
}
|
||||
|
||||
volatile bool EncryptionThreadPool::ThreadPoolRunning = false;
|
||||
volatile bool EncryptionThreadPool::StopPending = false;
|
||||
|
||||
size_t EncryptionThreadPool::ThreadCount;
|
||||
|
||||
EncryptionThreadPool::WorkItem EncryptionThreadPool::WorkItemQueue[QueueSize];
|
||||
|
||||
volatile size_t EncryptionThreadPool::EnqueuePosition;
|
||||
volatile size_t EncryptionThreadPool::DequeuePosition;
|
||||
|
||||
Mutex EncryptionThreadPool::EnqueueMutex;
|
||||
Mutex EncryptionThreadPool::DequeueMutex;
|
||||
|
||||
SyncEvent EncryptionThreadPool::WorkItemReadyEvent;
|
||||
SyncEvent EncryptionThreadPool::WorkItemCompletedEvent;
|
||||
|
||||
list < shared_ptr <Thread> > EncryptionThreadPool::RunningThreads;
|
||||
}
|
||||
87
src/Volume/EncryptionThreadPool.h
Normal file
87
src/Volume/EncryptionThreadPool.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Volume_EncryptionThreadPool
|
||||
#define TC_HEADER_Volume_EncryptionThreadPool
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "EncryptionMode.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class EncryptionThreadPool
|
||||
{
|
||||
public:
|
||||
struct WorkType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
EncryptDataUnits,
|
||||
DecryptDataUnits,
|
||||
DeriveKey
|
||||
};
|
||||
};
|
||||
|
||||
struct WorkItem
|
||||
{
|
||||
struct State
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Free,
|
||||
Ready,
|
||||
Busy
|
||||
};
|
||||
};
|
||||
|
||||
struct WorkItem *FirstFragment;
|
||||
auto_ptr <Exception> ItemException;
|
||||
SyncEvent ItemCompletedEvent;
|
||||
SharedVal <size_t> OutstandingFragmentCount;
|
||||
SharedVal <State::Enum> State;
|
||||
WorkType::Enum Type;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
const EncryptionMode *Mode;
|
||||
byte *Data;
|
||||
uint64 StartUnitNo;
|
||||
uint64 UnitCount;
|
||||
size_t SectorSize;
|
||||
} Encryption;
|
||||
};
|
||||
};
|
||||
|
||||
static void DoWork (WorkType::Enum type, const EncryptionMode *mode, byte *data, uint64 startUnitNo, uint64 unitCount, size_t sectorSize);
|
||||
static bool IsRunning () { return ThreadPoolRunning; }
|
||||
static void Start ();
|
||||
static void Stop ();
|
||||
|
||||
protected:
|
||||
static void WorkThreadProc ();
|
||||
|
||||
static const size_t MaxThreadCount = 32;
|
||||
static const size_t QueueSize = MaxThreadCount * 2;
|
||||
|
||||
static Mutex DequeueMutex;
|
||||
static volatile size_t DequeuePosition;
|
||||
static volatile size_t EnqueuePosition;
|
||||
static Mutex EnqueueMutex;
|
||||
static list < shared_ptr <Thread> > RunningThreads;
|
||||
static volatile bool StopPending;
|
||||
static size_t ThreadCount;
|
||||
static volatile bool ThreadPoolRunning;
|
||||
static SyncEvent WorkItemCompletedEvent;
|
||||
static WorkItem WorkItemQueue[QueueSize];
|
||||
static SyncEvent WorkItemReadyEvent;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Volume_EncryptionThreadPool
|
||||
138
src/Volume/Hash.cpp
Normal file
138
src/Volume/Hash.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Hash.h"
|
||||
|
||||
#include "Crypto/Rmd160.h"
|
||||
#include "Crypto/Sha1.h"
|
||||
#include "Crypto/Sha2.h"
|
||||
#include "Crypto/Whirlpool.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
HashList Hash::GetAvailableAlgorithms ()
|
||||
{
|
||||
HashList l;
|
||||
|
||||
l.push_back (shared_ptr <Hash> (new Ripemd160 ()));
|
||||
l.push_back (shared_ptr <Hash> (new Sha512 ()));
|
||||
l.push_back (shared_ptr <Hash> (new Whirlpool ()));
|
||||
l.push_back (shared_ptr <Hash> (new Sha1 ()));
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void Hash::ValidateDataParameters (const ConstBufferPtr &data) const
|
||||
{
|
||||
if (data.Size() < 1)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
void Hash::ValidateDigestParameters (const BufferPtr &buffer) const
|
||||
{
|
||||
if (buffer.Size() != GetDigestSize ())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
// RIPEMD-160
|
||||
Ripemd160::Ripemd160 ()
|
||||
{
|
||||
Context.Allocate (sizeof (RMD160_CTX));
|
||||
Init();
|
||||
}
|
||||
|
||||
void Ripemd160::GetDigest (const BufferPtr &buffer)
|
||||
{
|
||||
if_debug (ValidateDigestParameters (buffer));
|
||||
RMD160Final (buffer, (RMD160_CTX *) Context.Ptr());
|
||||
}
|
||||
|
||||
void Ripemd160::Init ()
|
||||
{
|
||||
RMD160Init ((RMD160_CTX *) Context.Ptr());
|
||||
}
|
||||
|
||||
void Ripemd160::ProcessData (const ConstBufferPtr &data)
|
||||
{
|
||||
if_debug (ValidateDataParameters (data));
|
||||
RMD160Update ((RMD160_CTX *) Context.Ptr(), data.Get(), (int) data.Size());
|
||||
}
|
||||
|
||||
// SHA-1
|
||||
Sha1::Sha1 ()
|
||||
{
|
||||
Deprecated = true;
|
||||
Context.Allocate (sizeof (sha1_ctx));
|
||||
Init();
|
||||
}
|
||||
|
||||
void Sha1::GetDigest (const BufferPtr &buffer)
|
||||
{
|
||||
if_debug (ValidateDigestParameters (buffer));
|
||||
sha1_end (buffer, (sha1_ctx *) Context.Ptr());
|
||||
}
|
||||
|
||||
void Sha1::Init ()
|
||||
{
|
||||
sha1_begin ((sha1_ctx *) Context.Ptr());
|
||||
}
|
||||
|
||||
void Sha1::ProcessData (const ConstBufferPtr &data)
|
||||
{
|
||||
if_debug (ValidateDataParameters (data));
|
||||
sha1_hash (data.Get(), (int) data.Size(), (sha1_ctx *) Context.Ptr());
|
||||
}
|
||||
|
||||
// SHA-512
|
||||
Sha512::Sha512 ()
|
||||
{
|
||||
Context.Allocate (sizeof (sha512_ctx));
|
||||
Init();
|
||||
}
|
||||
|
||||
void Sha512::GetDigest (const BufferPtr &buffer)
|
||||
{
|
||||
if_debug (ValidateDigestParameters (buffer));
|
||||
sha512_end (buffer, (sha512_ctx *) Context.Ptr());
|
||||
}
|
||||
|
||||
void Sha512::Init ()
|
||||
{
|
||||
sha512_begin ((sha512_ctx *) Context.Ptr());
|
||||
}
|
||||
|
||||
void Sha512::ProcessData (const ConstBufferPtr &data)
|
||||
{
|
||||
if_debug (ValidateDataParameters (data));
|
||||
sha512_hash (data.Get(), (int) data.Size(), (sha512_ctx *) Context.Ptr());
|
||||
}
|
||||
|
||||
// Whirlpool
|
||||
Whirlpool::Whirlpool ()
|
||||
{
|
||||
Context.Allocate (sizeof (WHIRLPOOL_CTX));
|
||||
Init();
|
||||
}
|
||||
|
||||
void Whirlpool::GetDigest (const BufferPtr &buffer)
|
||||
{
|
||||
if_debug (ValidateDigestParameters (buffer));
|
||||
WHIRLPOOL_finalize ((WHIRLPOOL_CTX *) Context.Ptr(), buffer);
|
||||
}
|
||||
|
||||
void Whirlpool::Init ()
|
||||
{
|
||||
WHIRLPOOL_init ((WHIRLPOOL_CTX *) Context.Ptr());
|
||||
}
|
||||
|
||||
void Whirlpool::ProcessData (const ConstBufferPtr &data)
|
||||
{
|
||||
if_debug (ValidateDataParameters (data));
|
||||
WHIRLPOOL_add (data.Get(), (int) data.Size() * 8, (WHIRLPOOL_CTX *) Context.Ptr());
|
||||
}
|
||||
}
|
||||
135
src/Volume/Hash.h
Normal file
135
src/Volume/Hash.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_Hash
|
||||
#define TC_HEADER_Encryption_Hash
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class Hash;
|
||||
typedef list < shared_ptr <Hash> > HashList;
|
||||
|
||||
class Hash
|
||||
{
|
||||
public:
|
||||
Hash () : Deprecated (false) { }
|
||||
virtual ~Hash () { }
|
||||
|
||||
static HashList GetAvailableAlgorithms ();
|
||||
virtual void GetDigest (const BufferPtr &buffer) = 0;
|
||||
virtual size_t GetBlockSize () const = 0;
|
||||
virtual size_t GetDigestSize () const = 0;
|
||||
virtual wstring GetName () const = 0;
|
||||
virtual shared_ptr <Hash> GetNew () const = 0;
|
||||
virtual void Init () = 0;
|
||||
bool IsDeprecated () const { return Deprecated; }
|
||||
virtual void ProcessData (const ConstBufferPtr &data) = 0;
|
||||
virtual void ValidateDataParameters (const ConstBufferPtr &data) const;
|
||||
virtual void ValidateDigestParameters (const BufferPtr &buffer) const;
|
||||
|
||||
protected:
|
||||
SecureBuffer Context;
|
||||
bool Deprecated;
|
||||
|
||||
private:
|
||||
Hash (const Hash &);
|
||||
Hash &operator= (const Hash &);
|
||||
};
|
||||
|
||||
// RIPEMD-160
|
||||
class Ripemd160 : public Hash
|
||||
{
|
||||
public:
|
||||
Ripemd160 ();
|
||||
virtual ~Ripemd160 () { }
|
||||
|
||||
virtual void GetDigest (const BufferPtr &buffer);
|
||||
virtual size_t GetBlockSize () const { return 64; }
|
||||
virtual size_t GetDigestSize () const { return 160 / 8; }
|
||||
virtual wstring GetName () const { return L"RIPEMD-160"; }
|
||||
virtual shared_ptr <Hash> GetNew () const { return shared_ptr <Hash> (new Ripemd160); }
|
||||
virtual void Init ();
|
||||
virtual void ProcessData (const ConstBufferPtr &data);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
Ripemd160 (const Ripemd160 &);
|
||||
Ripemd160 &operator= (const Ripemd160 &);
|
||||
};
|
||||
|
||||
// SHA-1
|
||||
class Sha1 : public Hash
|
||||
{
|
||||
public:
|
||||
Sha1 ();
|
||||
virtual ~Sha1 () { }
|
||||
|
||||
virtual void GetDigest (const BufferPtr &buffer);
|
||||
virtual size_t GetBlockSize () const { return 64; }
|
||||
virtual size_t GetDigestSize () const { return 160 / 8; }
|
||||
virtual wstring GetName () const { return L"SHA-1"; }
|
||||
virtual shared_ptr <Hash> GetNew () const { return shared_ptr <Hash> (new Sha1); }
|
||||
virtual void Init ();
|
||||
virtual void ProcessData (const ConstBufferPtr &data);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
Sha1 (const Sha1 &);
|
||||
Sha1 &operator= (const Sha1 &);
|
||||
};
|
||||
|
||||
// SHA-512
|
||||
class Sha512 : public Hash
|
||||
{
|
||||
public:
|
||||
Sha512 ();
|
||||
virtual ~Sha512 () { }
|
||||
|
||||
virtual void GetDigest (const BufferPtr &buffer);
|
||||
virtual size_t GetBlockSize () const { return 128; }
|
||||
virtual size_t GetDigestSize () const { return 512 / 8; }
|
||||
virtual wstring GetName () const { return L"SHA-512"; }
|
||||
virtual shared_ptr <Hash> GetNew () const { return shared_ptr <Hash> (new Sha512); }
|
||||
virtual void Init ();
|
||||
virtual void ProcessData (const ConstBufferPtr &data);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
Sha512 (const Sha512 &);
|
||||
Sha512 &operator= (const Sha512 &);
|
||||
};
|
||||
|
||||
// Whirlpool
|
||||
class Whirlpool : public Hash
|
||||
{
|
||||
public:
|
||||
Whirlpool ();
|
||||
virtual ~Whirlpool () { }
|
||||
|
||||
virtual void GetDigest (const BufferPtr &buffer);
|
||||
virtual size_t GetBlockSize () const { return 64; }
|
||||
virtual size_t GetDigestSize () const { return 512 / 8; }
|
||||
virtual wstring GetName () const { return L"Whirlpool"; }
|
||||
virtual shared_ptr <Hash> GetNew () const { return shared_ptr <Hash> (new Whirlpool); }
|
||||
virtual void Init ();
|
||||
virtual void ProcessData (const ConstBufferPtr &data);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
Whirlpool (const Whirlpool &);
|
||||
Whirlpool &operator= (const Whirlpool &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_Hash
|
||||
181
src/Volume/Keyfile.cpp
Normal file
181
src/Volume/Keyfile.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Platform/Serializer.h"
|
||||
#include "Common/SecurityToken.h"
|
||||
#include "Crc32.h"
|
||||
#include "Keyfile.h"
|
||||
#include "VolumeException.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
void Keyfile::Apply (const BufferPtr &pool) const
|
||||
{
|
||||
if (Path.IsDirectory())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
File file;
|
||||
|
||||
Crc32 crc32;
|
||||
size_t poolPos = 0;
|
||||
uint64 totalLength = 0;
|
||||
uint64 readLength;
|
||||
|
||||
SecureBuffer keyfileBuf (File::GetOptimalReadSize());
|
||||
|
||||
if (SecurityToken::IsKeyfilePathValid (Path))
|
||||
{
|
||||
// Apply keyfile generated by a security token
|
||||
vector <byte> keyfileData;
|
||||
SecurityToken::GetKeyfileData (SecurityTokenKeyfile (wstring (Path)), keyfileData);
|
||||
|
||||
if (keyfileData.size() < MinProcessedLength)
|
||||
throw InsufficientData (SRC_POS, Path);
|
||||
|
||||
for (size_t i = 0; i < keyfileData.size(); i++)
|
||||
{
|
||||
uint32 crc = crc32.Process (keyfileData[i]);
|
||||
|
||||
pool[poolPos++] += (byte) (crc >> 24);
|
||||
pool[poolPos++] += (byte) (crc >> 16);
|
||||
pool[poolPos++] += (byte) (crc >> 8);
|
||||
pool[poolPos++] += (byte) crc;
|
||||
|
||||
if (poolPos >= pool.Size())
|
||||
poolPos = 0;
|
||||
|
||||
if (++totalLength >= MaxProcessedLength)
|
||||
break;
|
||||
}
|
||||
|
||||
Memory::Erase (&keyfileData.front(), keyfileData.size());
|
||||
goto done;
|
||||
}
|
||||
|
||||
file.Open (Path, File::OpenRead, File::ShareRead);
|
||||
|
||||
while ((readLength = file.Read (keyfileBuf)) > 0)
|
||||
{
|
||||
for (size_t i = 0; i < readLength; i++)
|
||||
{
|
||||
uint32 crc = crc32.Process (keyfileBuf[i]);
|
||||
|
||||
pool[poolPos++] += (byte) (crc >> 24);
|
||||
pool[poolPos++] += (byte) (crc >> 16);
|
||||
pool[poolPos++] += (byte) (crc >> 8);
|
||||
pool[poolPos++] += (byte) crc;
|
||||
|
||||
if (poolPos >= pool.Size())
|
||||
poolPos = 0;
|
||||
|
||||
if (++totalLength >= MaxProcessedLength)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
if (totalLength < MinProcessedLength)
|
||||
throw InsufficientData (SRC_POS, Path);
|
||||
}
|
||||
|
||||
shared_ptr <VolumePassword> Keyfile::ApplyListToPassword (shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> password)
|
||||
{
|
||||
if (!password)
|
||||
password.reset (new VolumePassword);
|
||||
|
||||
if (!keyfiles || keyfiles->size() < 1)
|
||||
return password;
|
||||
|
||||
KeyfileList keyfilesExp;
|
||||
HiddenFileWasPresentInKeyfilePath = false;
|
||||
|
||||
// Enumerate directories
|
||||
foreach (shared_ptr <Keyfile> keyfile, *keyfiles)
|
||||
{
|
||||
if (FilesystemPath (*keyfile).IsDirectory())
|
||||
{
|
||||
size_t keyfileCount = 0;
|
||||
foreach_ref (const FilePath &path, Directory::GetFilePaths (*keyfile))
|
||||
{
|
||||
#ifdef TC_UNIX
|
||||
// Skip hidden files
|
||||
if (wstring (path.ToBaseName()).find (L'.') == 0)
|
||||
{
|
||||
HiddenFileWasPresentInKeyfilePath = true;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
keyfilesExp.push_back (make_shared <Keyfile> (path));
|
||||
++keyfileCount;
|
||||
}
|
||||
|
||||
if (keyfileCount == 0)
|
||||
throw KeyfilePathEmpty (SRC_POS, FilesystemPath (*keyfile));
|
||||
}
|
||||
else
|
||||
{
|
||||
keyfilesExp.push_back (keyfile);
|
||||
}
|
||||
}
|
||||
|
||||
make_shared_auto (VolumePassword, newPassword);
|
||||
|
||||
if (keyfilesExp.size() < 1)
|
||||
{
|
||||
newPassword->Set (*password);
|
||||
}
|
||||
else
|
||||
{
|
||||
SecureBuffer keyfilePool (VolumePassword::MaxSize);
|
||||
|
||||
// Pad password with zeros if shorter than max length
|
||||
keyfilePool.Zero();
|
||||
keyfilePool.CopyFrom (ConstBufferPtr (password->DataPtr(), password->Size()));
|
||||
|
||||
// Apply all keyfiles
|
||||
foreach_ref (const Keyfile &k, keyfilesExp)
|
||||
{
|
||||
k.Apply (keyfilePool);
|
||||
}
|
||||
|
||||
newPassword->Set (keyfilePool);
|
||||
}
|
||||
|
||||
return newPassword;
|
||||
}
|
||||
|
||||
shared_ptr <KeyfileList> Keyfile::DeserializeList (shared_ptr <Stream> stream, const string &name)
|
||||
{
|
||||
shared_ptr <KeyfileList> keyfiles;
|
||||
Serializer sr (stream);
|
||||
|
||||
if (!sr.DeserializeBool (name + "Null"))
|
||||
{
|
||||
keyfiles.reset (new KeyfileList);
|
||||
foreach (const wstring &k, sr.DeserializeWStringList (name))
|
||||
keyfiles->push_back (make_shared <Keyfile> (k));
|
||||
}
|
||||
return keyfiles;
|
||||
}
|
||||
|
||||
void Keyfile::SerializeList (shared_ptr <Stream> stream, const string &name, shared_ptr <KeyfileList> keyfiles)
|
||||
{
|
||||
Serializer sr (stream);
|
||||
sr.Serialize (name + "Null", keyfiles == nullptr);
|
||||
if (keyfiles)
|
||||
{
|
||||
list <wstring> sl;
|
||||
|
||||
foreach_ref (const Keyfile &k, *keyfiles)
|
||||
sl.push_back (FilesystemPath (k));
|
||||
|
||||
sr.Serialize (name, sl);
|
||||
}
|
||||
}
|
||||
|
||||
bool Keyfile::HiddenFileWasPresentInKeyfilePath = false;
|
||||
}
|
||||
49
src/Volume/Keyfile.h
Normal file
49
src/Volume/Keyfile.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_Keyfile
|
||||
#define TC_HEADER_Encryption_Keyfile
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Platform/Stream.h"
|
||||
#include "VolumePassword.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class Keyfile;
|
||||
typedef list < shared_ptr <Keyfile> > KeyfileList;
|
||||
|
||||
class Keyfile
|
||||
{
|
||||
public:
|
||||
Keyfile (const FilesystemPath &path) : Path (path) { }
|
||||
virtual ~Keyfile () { };
|
||||
|
||||
operator FilesystemPath () const { return Path; }
|
||||
static shared_ptr <VolumePassword> ApplyListToPassword (shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> password);
|
||||
static shared_ptr <KeyfileList> DeserializeList (shared_ptr <Stream> stream, const string &name);
|
||||
static void SerializeList (shared_ptr <Stream> stream, const string &name, shared_ptr <KeyfileList> keyfiles);
|
||||
static bool WasHiddenFilePresentInKeyfilePath() { bool r = HiddenFileWasPresentInKeyfilePath; HiddenFileWasPresentInKeyfilePath = false; return r; }
|
||||
|
||||
static const size_t MinProcessedLength = 1;
|
||||
static const size_t MaxProcessedLength = 1024 * 1024;
|
||||
|
||||
protected:
|
||||
void Apply (const BufferPtr &pool) const;
|
||||
|
||||
static bool HiddenFileWasPresentInKeyfilePath;
|
||||
|
||||
FilesystemPath Path;
|
||||
|
||||
private:
|
||||
Keyfile (const Keyfile &);
|
||||
Keyfile &operator= (const Keyfile &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_Keyfile
|
||||
96
src/Volume/Pkcs5Kdf.cpp
Normal file
96
src/Volume/Pkcs5Kdf.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Common/Pkcs5.h"
|
||||
#include "Pkcs5Kdf.h"
|
||||
#include "VolumePassword.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
Pkcs5Kdf::Pkcs5Kdf ()
|
||||
{
|
||||
}
|
||||
|
||||
Pkcs5Kdf::~Pkcs5Kdf ()
|
||||
{
|
||||
}
|
||||
|
||||
void Pkcs5Kdf::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt) const
|
||||
{
|
||||
DeriveKey (key, password, salt, GetIterationCount());
|
||||
}
|
||||
|
||||
shared_ptr <Pkcs5Kdf> Pkcs5Kdf::GetAlgorithm (const wstring &name)
|
||||
{
|
||||
foreach (shared_ptr <Pkcs5Kdf> kdf, GetAvailableAlgorithms())
|
||||
{
|
||||
if (kdf->GetName() == name)
|
||||
return kdf;
|
||||
}
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
shared_ptr <Pkcs5Kdf> Pkcs5Kdf::GetAlgorithm (const Hash &hash)
|
||||
{
|
||||
foreach (shared_ptr <Pkcs5Kdf> kdf, GetAvailableAlgorithms())
|
||||
{
|
||||
if (typeid (*kdf->GetHash()) == typeid (hash))
|
||||
return kdf;
|
||||
}
|
||||
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
Pkcs5KdfList Pkcs5Kdf::GetAvailableAlgorithms ()
|
||||
{
|
||||
Pkcs5KdfList l;
|
||||
|
||||
l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacRipemd160 ()));
|
||||
l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacSha512 ()));
|
||||
l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacWhirlpool ()));
|
||||
l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacSha1 ()));
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void Pkcs5Kdf::ValidateParameters (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||
{
|
||||
if (key.Size() < 1 || password.Size() < 1 || salt.Size() < 1 || iterationCount < 1)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
void Pkcs5HmacRipemd160::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||
{
|
||||
ValidateParameters (key, password, salt, iterationCount);
|
||||
derive_key_ripemd160 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size());
|
||||
}
|
||||
|
||||
void Pkcs5HmacRipemd160_1000::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||
{
|
||||
ValidateParameters (key, password, salt, iterationCount);
|
||||
derive_key_ripemd160 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size());
|
||||
}
|
||||
|
||||
void Pkcs5HmacSha1::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||
{
|
||||
ValidateParameters (key, password, salt, iterationCount);
|
||||
derive_key_sha1 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size());
|
||||
}
|
||||
|
||||
void Pkcs5HmacSha512::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||
{
|
||||
ValidateParameters (key, password, salt, iterationCount);
|
||||
derive_key_sha512 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size());
|
||||
}
|
||||
|
||||
void Pkcs5HmacWhirlpool::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||
{
|
||||
ValidateParameters (key, password, salt, iterationCount);
|
||||
derive_key_whirlpool ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size());
|
||||
}
|
||||
}
|
||||
127
src/Volume/Pkcs5Kdf.h
Normal file
127
src/Volume/Pkcs5Kdf.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_Pkcs5
|
||||
#define TC_HEADER_Encryption_Pkcs5
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Hash.h"
|
||||
#include "VolumePassword.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class Pkcs5Kdf;
|
||||
typedef list < shared_ptr <Pkcs5Kdf> > Pkcs5KdfList;
|
||||
|
||||
class Pkcs5Kdf
|
||||
{
|
||||
public:
|
||||
virtual ~Pkcs5Kdf ();
|
||||
|
||||
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt) const;
|
||||
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const = 0;
|
||||
static shared_ptr <Pkcs5Kdf> GetAlgorithm (const wstring &name);
|
||||
static shared_ptr <Pkcs5Kdf> GetAlgorithm (const Hash &hash);
|
||||
static Pkcs5KdfList GetAvailableAlgorithms ();
|
||||
virtual shared_ptr <Hash> GetHash () const = 0;
|
||||
virtual int GetIterationCount () const = 0;
|
||||
virtual wstring GetName () const = 0;
|
||||
virtual bool IsDeprecated () const { return GetHash()->IsDeprecated(); }
|
||||
|
||||
protected:
|
||||
Pkcs5Kdf ();
|
||||
|
||||
void ValidateParameters (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||
|
||||
private:
|
||||
Pkcs5Kdf (const Pkcs5Kdf &);
|
||||
Pkcs5Kdf &operator= (const Pkcs5Kdf &);
|
||||
};
|
||||
|
||||
class Pkcs5HmacRipemd160 : public Pkcs5Kdf
|
||||
{
|
||||
public:
|
||||
Pkcs5HmacRipemd160 () { }
|
||||
virtual ~Pkcs5HmacRipemd160 () { }
|
||||
|
||||
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Ripemd160); }
|
||||
virtual int GetIterationCount () const { return 2000; }
|
||||
virtual wstring GetName () const { return L"HMAC-RIPEMD-160"; }
|
||||
|
||||
private:
|
||||
Pkcs5HmacRipemd160 (const Pkcs5HmacRipemd160 &);
|
||||
Pkcs5HmacRipemd160 &operator= (const Pkcs5HmacRipemd160 &);
|
||||
};
|
||||
|
||||
class Pkcs5HmacRipemd160_1000 : public Pkcs5Kdf
|
||||
{
|
||||
public:
|
||||
Pkcs5HmacRipemd160_1000 () { }
|
||||
virtual ~Pkcs5HmacRipemd160_1000 () { }
|
||||
|
||||
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Ripemd160); }
|
||||
virtual int GetIterationCount () const { return 1000; }
|
||||
virtual wstring GetName () const { return L"HMAC-RIPEMD-160"; }
|
||||
|
||||
private:
|
||||
Pkcs5HmacRipemd160_1000 (const Pkcs5HmacRipemd160_1000 &);
|
||||
Pkcs5HmacRipemd160_1000 &operator= (const Pkcs5HmacRipemd160_1000 &);
|
||||
};
|
||||
|
||||
class Pkcs5HmacSha1 : public Pkcs5Kdf
|
||||
{
|
||||
public:
|
||||
Pkcs5HmacSha1 () { }
|
||||
virtual ~Pkcs5HmacSha1 () { }
|
||||
|
||||
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha1); }
|
||||
virtual int GetIterationCount () const { return 2000; }
|
||||
virtual wstring GetName () const { return L"HMAC-SHA-1"; }
|
||||
|
||||
private:
|
||||
Pkcs5HmacSha1 (const Pkcs5HmacSha1 &);
|
||||
Pkcs5HmacSha1 &operator= (const Pkcs5HmacSha1 &);
|
||||
};
|
||||
|
||||
class Pkcs5HmacSha512 : public Pkcs5Kdf
|
||||
{
|
||||
public:
|
||||
Pkcs5HmacSha512 () { }
|
||||
virtual ~Pkcs5HmacSha512 () { }
|
||||
|
||||
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha512); }
|
||||
virtual int GetIterationCount () const { return 1000; }
|
||||
virtual wstring GetName () const { return L"HMAC-SHA-512"; }
|
||||
|
||||
private:
|
||||
Pkcs5HmacSha512 (const Pkcs5HmacSha512 &);
|
||||
Pkcs5HmacSha512 &operator= (const Pkcs5HmacSha512 &);
|
||||
};
|
||||
|
||||
class Pkcs5HmacWhirlpool : public Pkcs5Kdf
|
||||
{
|
||||
public:
|
||||
Pkcs5HmacWhirlpool () { }
|
||||
virtual ~Pkcs5HmacWhirlpool () { }
|
||||
|
||||
virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Whirlpool); }
|
||||
virtual int GetIterationCount () const { return 1000; }
|
||||
virtual wstring GetName () const { return L"HMAC-Whirlpool"; }
|
||||
|
||||
private:
|
||||
Pkcs5HmacWhirlpool (const Pkcs5HmacWhirlpool &);
|
||||
Pkcs5HmacWhirlpool &operator= (const Pkcs5HmacWhirlpool &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_Pkcs5
|
||||
25
src/Volume/Version.h
Normal file
25
src/Volume/Version.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Volume_Version
|
||||
#define TC_HEADER_Volume_Version
|
||||
|
||||
#include "Platform/PlatformBase.h"
|
||||
#include "Common/Tcdefs.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class Version
|
||||
{
|
||||
public:
|
||||
static const string String () { return VERSION_STRING; }
|
||||
static const uint16 Number () { return VERSION_NUM; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Volume_Version
|
||||
388
src/Volume/Volume.cpp
Normal file
388
src/Volume/Volume.cpp
Normal file
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_WINDOWS
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include "EncryptionModeLRW.h"
|
||||
#include "EncryptionModeXTS.h"
|
||||
#include "Volume.h"
|
||||
#include "VolumeHeader.h"
|
||||
#include "VolumeLayout.h"
|
||||
#include "Common/Crypto.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
Volume::Volume ()
|
||||
: HiddenVolumeProtectionTriggered (false),
|
||||
SystemEncryption (false),
|
||||
VolumeDataSize (0),
|
||||
TopWriteOffset (0),
|
||||
TotalDataRead (0),
|
||||
TotalDataWritten (0)
|
||||
{
|
||||
}
|
||||
|
||||
Volume::~Volume ()
|
||||
{
|
||||
}
|
||||
|
||||
void Volume::CheckProtectedRange (uint64 writeHostOffset, uint64 writeLength)
|
||||
{
|
||||
uint64 writeHostEndOffset = writeHostOffset + writeLength - 1;
|
||||
|
||||
if ((writeHostOffset < ProtectedRangeStart) ? (writeHostEndOffset >= ProtectedRangeStart) : (writeHostOffset <= ProtectedRangeEnd - 1))
|
||||
{
|
||||
HiddenVolumeProtectionTriggered = true;
|
||||
throw VolumeProtected (SRC_POS);
|
||||
}
|
||||
}
|
||||
|
||||
void Volume::Close ()
|
||||
{
|
||||
if (VolumeFile.get() == nullptr)
|
||||
throw NotInitialized (SRC_POS);
|
||||
|
||||
VolumeFile.reset();
|
||||
}
|
||||
|
||||
shared_ptr <EncryptionAlgorithm> Volume::GetEncryptionAlgorithm () const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
return EA;
|
||||
}
|
||||
|
||||
shared_ptr <EncryptionMode> Volume::GetEncryptionMode () const
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
return EA->GetMode();
|
||||
}
|
||||
|
||||
void Volume::Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, shared_ptr <KeyfileList> protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope)
|
||||
{
|
||||
make_shared_auto (File, file);
|
||||
|
||||
File::FileOpenFlags flags = (preserveTimestamps ? File::PreserveTimestamps : File::FlagsNone);
|
||||
|
||||
try
|
||||
{
|
||||
if (protection == VolumeProtection::ReadOnly)
|
||||
file->Open (volumePath, File::OpenRead, File::ShareRead, flags);
|
||||
else
|
||||
file->Open (volumePath, File::OpenReadWrite, File::ShareNone, flags);
|
||||
}
|
||||
catch (SystemException &e)
|
||||
{
|
||||
if (e.GetErrorCode() ==
|
||||
#ifdef TC_WINDOWS
|
||||
ERROR_SHARING_VIOLATION)
|
||||
#else
|
||||
EAGAIN)
|
||||
#endif
|
||||
{
|
||||
if (!sharedAccessAllowed)
|
||||
throw VolumeHostInUse (SRC_POS);
|
||||
|
||||
file->Open (volumePath, protection == VolumeProtection::ReadOnly ? File::OpenRead : File::OpenReadWrite, File::ShareReadWriteIgnoreLock, flags);
|
||||
}
|
||||
else
|
||||
throw;
|
||||
}
|
||||
|
||||
return Open (file, password, keyfiles, protection, protectionPassword, protectionKeyfiles, volumeType, useBackupHeaders, partitionInSystemEncryptionScope);
|
||||
}
|
||||
|
||||
void Volume::Open (shared_ptr <File> volumeFile, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, shared_ptr <KeyfileList> protectionKeyfiles, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope)
|
||||
{
|
||||
if (!volumeFile)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
Protection = protection;
|
||||
VolumeFile = volumeFile;
|
||||
SystemEncryption = partitionInSystemEncryptionScope;
|
||||
|
||||
try
|
||||
{
|
||||
VolumeHostSize = VolumeFile->Length();
|
||||
shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (keyfiles, password);
|
||||
|
||||
bool skipLayoutV1Normal = false;
|
||||
|
||||
bool deviceHosted = GetPath().IsDevice();
|
||||
size_t hostDeviceSectorSize = 0;
|
||||
if (deviceHosted)
|
||||
hostDeviceSectorSize = volumeFile->GetDeviceSectorSize();
|
||||
|
||||
// Test volume layouts
|
||||
foreach (shared_ptr <VolumeLayout> layout, VolumeLayout::GetAvailableLayouts (volumeType))
|
||||
{
|
||||
if (skipLayoutV1Normal && typeid (*layout) == typeid (VolumeLayoutV1Normal))
|
||||
{
|
||||
// Skip VolumeLayoutV1Normal as it shares header location with VolumeLayoutV2Normal
|
||||
continue;
|
||||
}
|
||||
|
||||
if (useBackupHeaders && !layout->HasBackupHeader())
|
||||
continue;
|
||||
|
||||
if (typeid (*layout) == typeid (VolumeLayoutV1Hidden)
|
||||
&& deviceHosted
|
||||
&& hostDeviceSectorSize != TC_SECTOR_SIZE_LEGACY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SecureBuffer headerBuffer (layout->GetHeaderSize());
|
||||
|
||||
if (layout->HasDriveHeader())
|
||||
{
|
||||
if (!partitionInSystemEncryptionScope)
|
||||
continue;
|
||||
|
||||
if (!GetPath().IsDevice())
|
||||
throw PartitionDeviceRequired (SRC_POS);
|
||||
|
||||
File driveDevice;
|
||||
driveDevice.Open (DevicePath (wstring (GetPath())).ToHostDriveOfPartition());
|
||||
|
||||
int headerOffset = layout->GetHeaderOffset();
|
||||
|
||||
if (headerOffset >= 0)
|
||||
driveDevice.SeekAt (headerOffset);
|
||||
else
|
||||
driveDevice.SeekEnd (headerOffset);
|
||||
|
||||
if (driveDevice.Read (headerBuffer) != layout->GetHeaderSize())
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (partitionInSystemEncryptionScope)
|
||||
continue;
|
||||
|
||||
int headerOffset = useBackupHeaders ? layout->GetBackupHeaderOffset() : layout->GetHeaderOffset();
|
||||
|
||||
if (headerOffset >= 0)
|
||||
VolumeFile->SeekAt (headerOffset);
|
||||
else
|
||||
VolumeFile->SeekEnd (headerOffset);
|
||||
|
||||
if (VolumeFile->Read (headerBuffer) != layout->GetHeaderSize())
|
||||
continue;
|
||||
}
|
||||
|
||||
EncryptionAlgorithmList layoutEncryptionAlgorithms = layout->GetSupportedEncryptionAlgorithms();
|
||||
EncryptionModeList layoutEncryptionModes = layout->GetSupportedEncryptionModes();
|
||||
|
||||
if (typeid (*layout) == typeid (VolumeLayoutV2Normal))
|
||||
{
|
||||
skipLayoutV1Normal = true;
|
||||
|
||||
// Test all algorithms and modes of VolumeLayoutV1Normal as it shares header location with VolumeLayoutV2Normal
|
||||
layoutEncryptionAlgorithms = EncryptionAlgorithm::GetAvailableAlgorithms();
|
||||
layoutEncryptionModes = EncryptionMode::GetAvailableModes();
|
||||
}
|
||||
|
||||
shared_ptr <VolumeHeader> header = layout->GetHeader();
|
||||
|
||||
if (header->Decrypt (headerBuffer, *passwordKey, layout->GetSupportedKeyDerivationFunctions(), layoutEncryptionAlgorithms, layoutEncryptionModes))
|
||||
{
|
||||
// Header decrypted
|
||||
|
||||
if (typeid (*layout) == typeid (VolumeLayoutV2Normal) && header->GetRequiredMinProgramVersion() < 0x600)
|
||||
{
|
||||
// VolumeLayoutV1Normal has been opened as VolumeLayoutV2Normal
|
||||
layout.reset (new VolumeLayoutV1Normal);
|
||||
header->SetSize (layout->GetHeaderSize());
|
||||
layout->SetHeader (header);
|
||||
}
|
||||
|
||||
Type = layout->GetType();
|
||||
SectorSize = header->GetSectorSize();
|
||||
|
||||
VolumeDataOffset = layout->GetDataOffset (VolumeHostSize);
|
||||
VolumeDataSize = layout->GetDataSize (VolumeHostSize);
|
||||
|
||||
Header = header;
|
||||
Layout = layout;
|
||||
EA = header->GetEncryptionAlgorithm();
|
||||
EncryptionMode &mode = *EA->GetMode();
|
||||
|
||||
if (layout->HasDriveHeader())
|
||||
{
|
||||
if (header->GetEncryptedAreaLength() != header->GetVolumeDataSize())
|
||||
throw VolumeEncryptionNotCompleted (SRC_POS);
|
||||
|
||||
uint64 partitionStartOffset = VolumeFile->GetPartitionDeviceStartOffset();
|
||||
|
||||
if (partitionStartOffset < header->GetEncryptedAreaStart()
|
||||
|| partitionStartOffset >= header->GetEncryptedAreaStart() + header->GetEncryptedAreaLength())
|
||||
throw PasswordIncorrect (SRC_POS);
|
||||
|
||||
mode.SetSectorOffset (partitionStartOffset / ENCRYPTION_DATA_UNIT_SIZE);
|
||||
}
|
||||
else if (typeid (mode) == typeid (EncryptionModeLRW))
|
||||
{
|
||||
mode.SetSectorOffset (VolumeDataOffset / SectorSize);
|
||||
}
|
||||
|
||||
// Volume protection
|
||||
if (Protection == VolumeProtection::HiddenVolumeReadOnly)
|
||||
{
|
||||
if (Type == VolumeType::Hidden)
|
||||
throw PasswordIncorrect (SRC_POS);
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Volume protectedVolume;
|
||||
|
||||
protectedVolume.Open (VolumeFile,
|
||||
protectionPassword, protectionKeyfiles,
|
||||
VolumeProtection::ReadOnly,
|
||||
shared_ptr <VolumePassword> (), shared_ptr <KeyfileList> (),
|
||||
VolumeType::Hidden,
|
||||
useBackupHeaders);
|
||||
|
||||
if (protectedVolume.GetType() != VolumeType::Hidden)
|
||||
ParameterIncorrect (SRC_POS);
|
||||
|
||||
ProtectedRangeStart = protectedVolume.VolumeDataOffset;
|
||||
ProtectedRangeEnd = protectedVolume.VolumeDataOffset + protectedVolume.VolumeDataSize;
|
||||
|
||||
if (typeid (*protectedVolume.Layout) == typeid (VolumeLayoutV1Hidden))
|
||||
ProtectedRangeEnd += protectedVolume.Layout->GetHeaderSize();
|
||||
}
|
||||
catch (PasswordException&)
|
||||
{
|
||||
if (protectionKeyfiles && !protectionKeyfiles->empty())
|
||||
throw ProtectionPasswordKeyfilesIncorrect (SRC_POS);
|
||||
throw ProtectionPasswordIncorrect (SRC_POS);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (partitionInSystemEncryptionScope)
|
||||
throw PasswordOrKeyboardLayoutIncorrect (SRC_POS);
|
||||
|
||||
if (!partitionInSystemEncryptionScope && GetPath().IsDevice())
|
||||
{
|
||||
// Check if the device contains TrueCrypt Boot Loader
|
||||
try
|
||||
{
|
||||
File driveDevice;
|
||||
driveDevice.Open (DevicePath (wstring (GetPath())).ToHostDriveOfPartition());
|
||||
|
||||
Buffer mbr (VolumeFile->GetDeviceSectorSize());
|
||||
driveDevice.ReadAt (mbr, 0);
|
||||
|
||||
// Search for the string "TrueCrypt"
|
||||
size_t nameLen = strlen (TC_APP_NAME);
|
||||
for (size_t i = 0; i < mbr.Size() - nameLen; ++i)
|
||||
{
|
||||
if (memcmp (mbr.Ptr() + i, TC_APP_NAME, nameLen) == 0)
|
||||
throw PasswordOrMountOptionsIncorrect (SRC_POS);
|
||||
}
|
||||
}
|
||||
catch (PasswordOrMountOptionsIncorrect&) { throw; }
|
||||
catch (...) { }
|
||||
}
|
||||
|
||||
if (keyfiles && !keyfiles->empty())
|
||||
throw PasswordKeyfilesIncorrect (SRC_POS);
|
||||
throw PasswordIncorrect (SRC_POS);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Close();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void Volume::ReadSectors (const BufferPtr &buffer, uint64 byteOffset)
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
|
||||
uint64 length = buffer.Size();
|
||||
uint64 hostOffset = VolumeDataOffset + byteOffset;
|
||||
|
||||
if (length % SectorSize != 0 || byteOffset % SectorSize != 0)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
if (VolumeFile->ReadAt (buffer, hostOffset) != length)
|
||||
throw MissingVolumeData (SRC_POS);
|
||||
|
||||
EA->DecryptSectors (buffer, hostOffset / SectorSize, length / SectorSize, SectorSize);
|
||||
|
||||
TotalDataRead += length;
|
||||
}
|
||||
|
||||
void Volume::ReEncryptHeader (bool backupHeader, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr <Pkcs5Kdf> newPkcs5Kdf)
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
|
||||
if (Protection == VolumeProtection::ReadOnly)
|
||||
throw VolumeReadOnly (SRC_POS);
|
||||
|
||||
SecureBuffer newHeaderBuffer (Layout->GetHeaderSize());
|
||||
|
||||
Header->EncryptNew (newHeaderBuffer, newSalt, newHeaderKey, newPkcs5Kdf);
|
||||
|
||||
int headerOffset = backupHeader ? Layout->GetBackupHeaderOffset() : Layout->GetHeaderOffset();
|
||||
|
||||
if (headerOffset >= 0)
|
||||
VolumeFile->SeekAt (headerOffset);
|
||||
else
|
||||
VolumeFile->SeekEnd (headerOffset);
|
||||
|
||||
VolumeFile->Write (newHeaderBuffer);
|
||||
}
|
||||
|
||||
void Volume::ValidateState () const
|
||||
{
|
||||
if (VolumeFile.get() == nullptr)
|
||||
throw NotInitialized (SRC_POS);
|
||||
}
|
||||
|
||||
void Volume::WriteSectors (const ConstBufferPtr &buffer, uint64 byteOffset)
|
||||
{
|
||||
if_debug (ValidateState ());
|
||||
|
||||
uint64 length = buffer.Size();
|
||||
uint64 hostOffset = VolumeDataOffset + byteOffset;
|
||||
|
||||
if (length % SectorSize != 0
|
||||
|| byteOffset % SectorSize != 0
|
||||
|| byteOffset + length > VolumeDataSize)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
if (Protection == VolumeProtection::ReadOnly)
|
||||
throw VolumeReadOnly (SRC_POS);
|
||||
|
||||
if (HiddenVolumeProtectionTriggered)
|
||||
throw VolumeProtected (SRC_POS);
|
||||
|
||||
if (Protection == VolumeProtection::HiddenVolumeReadOnly)
|
||||
CheckProtectedRange (hostOffset, length);
|
||||
|
||||
SecureBuffer encBuf (buffer.Size());
|
||||
encBuf.CopyFrom (buffer);
|
||||
|
||||
EA->EncryptSectors (encBuf, hostOffset / SectorSize, length / SectorSize, SectorSize);
|
||||
VolumeFile->WriteAt (encBuf, hostOffset);
|
||||
|
||||
TotalDataWritten += length;
|
||||
|
||||
uint64 writeEndOffset = byteOffset + buffer.Size();
|
||||
if (writeEndOffset > TopWriteOffset)
|
||||
TopWriteOffset = writeEndOffset;
|
||||
}
|
||||
}
|
||||
126
src/Volume/Volume.h
Normal file
126
src/Volume/Volume.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Volume_Volume
|
||||
#define TC_HEADER_Volume_Volume
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Platform/StringConverter.h"
|
||||
#include "EncryptionAlgorithm.h"
|
||||
#include "EncryptionMode.h"
|
||||
#include "Keyfile.h"
|
||||
#include "VolumePassword.h"
|
||||
#include "VolumeException.h"
|
||||
#include "VolumeLayout.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class VolumePath
|
||||
{
|
||||
public:
|
||||
VolumePath () { }
|
||||
VolumePath (const wstring &path) { Data = path; }
|
||||
VolumePath (const FilesystemPath &path) { Data = path; }
|
||||
|
||||
bool operator== (const VolumePath &other) const { return Data == other.Data; }
|
||||
bool operator!= (const VolumePath &other) const { return Data != other.Data; }
|
||||
operator FilesystemPath () const { return FilesystemPath (Data); }
|
||||
operator string () const { return StringConverter::ToSingle (Data); }
|
||||
operator wstring () const { return Data; }
|
||||
|
||||
bool IsDevice () const { return FilesystemPath (Data).IsBlockDevice() || FilesystemPath (Data).IsCharacterDevice(); }
|
||||
bool IsEmpty () const { return Data.empty(); }
|
||||
|
||||
protected:
|
||||
wstring Data;
|
||||
};
|
||||
|
||||
typedef list <VolumePath> VolumePathList;
|
||||
|
||||
struct VolumeHostType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unknown,
|
||||
File,
|
||||
Device
|
||||
};
|
||||
};
|
||||
|
||||
struct VolumeProtection
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
None,
|
||||
ReadOnly,
|
||||
HiddenVolumeReadOnly
|
||||
};
|
||||
};
|
||||
|
||||
class Volume
|
||||
{
|
||||
public:
|
||||
Volume ();
|
||||
virtual ~Volume ();
|
||||
|
||||
void Close ();
|
||||
shared_ptr <EncryptionAlgorithm> GetEncryptionAlgorithm () const;
|
||||
shared_ptr <EncryptionMode> GetEncryptionMode () const;
|
||||
shared_ptr <File> GetFile () const { return VolumeFile; }
|
||||
shared_ptr <VolumeHeader> GetHeader () const { return Header; }
|
||||
uint64 GetHeaderCreationTime () const { return Header->GetHeaderCreationTime(); }
|
||||
uint64 GetHostSize () const { return VolumeHostSize; }
|
||||
shared_ptr <VolumeLayout> GetLayout () const { return Layout; }
|
||||
VolumePath GetPath () const { return VolumeFile->GetPath(); }
|
||||
VolumeProtection::Enum GetProtectionType () const { return Protection; }
|
||||
shared_ptr <Pkcs5Kdf> GetPkcs5Kdf () const { return Header->GetPkcs5Kdf(); }
|
||||
uint32 GetSaltSize () const { return Header->GetSaltSize(); }
|
||||
size_t GetSectorSize () const { return SectorSize; }
|
||||
uint64 GetSize () const { return VolumeDataSize; }
|
||||
uint64 GetTopWriteOffset () const { return TopWriteOffset; }
|
||||
uint64 GetTotalDataRead () const { return TotalDataRead; }
|
||||
uint64 GetTotalDataWritten () const { return TotalDataWritten; }
|
||||
VolumeType::Enum GetType () const { return Type; }
|
||||
uint64 GetVolumeCreationTime () const { return Header->GetVolumeCreationTime(); }
|
||||
bool IsHiddenVolumeProtectionTriggered () const { return HiddenVolumeProtectionTriggered; }
|
||||
bool IsInSystemEncryptionScope () const { return SystemEncryption; }
|
||||
void Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false);
|
||||
void Open (shared_ptr <File> volumeFile, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false);
|
||||
void ReadSectors (const BufferPtr &buffer, uint64 byteOffset);
|
||||
void ReEncryptHeader (bool backupHeader, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr <Pkcs5Kdf> newPkcs5Kdf);
|
||||
void WriteSectors (const ConstBufferPtr &buffer, uint64 byteOffset);
|
||||
|
||||
protected:
|
||||
void CheckProtectedRange (uint64 writeHostOffset, uint64 writeLength);
|
||||
void ValidateState () const;
|
||||
|
||||
shared_ptr <EncryptionAlgorithm> EA;
|
||||
shared_ptr <VolumeHeader> Header;
|
||||
bool HiddenVolumeProtectionTriggered;
|
||||
shared_ptr <VolumeLayout> Layout;
|
||||
uint64 ProtectedRangeStart;
|
||||
uint64 ProtectedRangeEnd;
|
||||
VolumeProtection::Enum Protection;
|
||||
size_t SectorSize;
|
||||
bool SystemEncryption;
|
||||
VolumeType::Enum Type;
|
||||
shared_ptr <File> VolumeFile;
|
||||
uint64 VolumeHostSize;
|
||||
uint64 VolumeDataOffset;
|
||||
uint64 VolumeDataSize;
|
||||
uint64 TopWriteOffset;
|
||||
uint64 TotalDataRead;
|
||||
uint64 TotalDataWritten;
|
||||
|
||||
private:
|
||||
Volume (const Volume &);
|
||||
Volume &operator= (const Volume &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Volume_Volume
|
||||
62
src/Volume/Volume.make
Normal file
62
src/Volume/Volume.make
Normal file
@@ -0,0 +1,62 @@
|
||||
#
|
||||
# Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
#
|
||||
# Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
# the file License.txt included in TrueCrypt binary and source code distribution
|
||||
# packages.
|
||||
#
|
||||
|
||||
OBJS :=
|
||||
OBJS += Cipher.o
|
||||
OBJS += EncryptionAlgorithm.o
|
||||
OBJS += EncryptionMode.o
|
||||
OBJS += EncryptionModeCBC.o
|
||||
OBJS += EncryptionModeLRW.o
|
||||
OBJS += EncryptionModeXTS.o
|
||||
OBJS += EncryptionTest.o
|
||||
OBJS += EncryptionThreadPool.o
|
||||
OBJS += Hash.o
|
||||
OBJS += Keyfile.o
|
||||
OBJS += Pkcs5Kdf.o
|
||||
OBJS += Volume.o
|
||||
OBJS += VolumeException.o
|
||||
OBJS += VolumeHeader.o
|
||||
OBJS += VolumeInfo.o
|
||||
OBJS += VolumeLayout.o
|
||||
OBJS += VolumePassword.o
|
||||
OBJS += VolumePasswordCache.o
|
||||
|
||||
ifeq "$(CPU_ARCH)" "x86"
|
||||
OBJS += ../Crypto/Aes_x86.o
|
||||
OBJS += ../Crypto/Aes_hw_cpu.o
|
||||
ifeq "$(PLATFORM)" "MacOSX"
|
||||
OBJS += ../Crypto/Aescrypt.o
|
||||
endif
|
||||
else ifeq "$(CPU_ARCH)" "x64"
|
||||
OBJS += ../Crypto/Aes_x64.o
|
||||
OBJS += ../Crypto/Aes_hw_cpu.o
|
||||
else
|
||||
OBJS += ../Crypto/Aescrypt.o
|
||||
endif
|
||||
|
||||
OBJS += ../Crypto/Aeskey.o
|
||||
OBJS += ../Crypto/Aestab.o
|
||||
OBJS += ../Crypto/Blowfish.o
|
||||
OBJS += ../Crypto/Cast.o
|
||||
OBJS += ../Crypto/Des.o
|
||||
OBJS += ../Crypto/Rmd160.o
|
||||
OBJS += ../Crypto/Serpent.o
|
||||
OBJS += ../Crypto/Sha1.o
|
||||
OBJS += ../Crypto/Sha2.o
|
||||
OBJS += ../Crypto/Twofish.o
|
||||
OBJS += ../Crypto/Whirlpool.o
|
||||
|
||||
OBJS += ../Common/Crc.o
|
||||
OBJS += ../Common/Endian.o
|
||||
OBJS += ../Common/GfMul.o
|
||||
OBJS += ../Common/Pkcs5.o
|
||||
OBJS += ../Common/SecurityToken.o
|
||||
|
||||
VolumeLibrary: Volume.a
|
||||
|
||||
include $(BUILD_INC)/Makefile.inc
|
||||
32
src/Volume/VolumeException.cpp
Normal file
32
src/Volume/VolumeException.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "VolumeException.h"
|
||||
#include "Platform/SerializerFactory.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
// Do not inline the constructors to ensure this module is not optimized away
|
||||
VolumeException::VolumeException ()
|
||||
{
|
||||
}
|
||||
|
||||
VolumeException::VolumeException (const string &message) : Exception (message)
|
||||
{
|
||||
}
|
||||
|
||||
VolumeException::VolumeException (const string &message, const wstring &subject) : Exception (message, subject)
|
||||
{
|
||||
}
|
||||
|
||||
#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
|
||||
#undef TC_EXCEPTION_NODECL
|
||||
#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
|
||||
|
||||
TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (VolumeException);
|
||||
}
|
||||
43
src/Volume/VolumeException.h
Normal file
43
src/Volume/VolumeException.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Volume_VolumeExceptions
|
||||
#define TC_HEADER_Volume_VolumeExceptions
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
struct VolumeException : public Exception
|
||||
{
|
||||
protected:
|
||||
VolumeException ();
|
||||
VolumeException (const string &message);
|
||||
VolumeException (const string &message, const wstring &subject);
|
||||
};
|
||||
|
||||
#define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,VolumeException)
|
||||
|
||||
#undef TC_EXCEPTION_SET
|
||||
#define TC_EXCEPTION_SET \
|
||||
TC_EXCEPTION (HigherVersionRequired); \
|
||||
TC_EXCEPTION (KeyfilePathEmpty); \
|
||||
TC_EXCEPTION (MissingVolumeData); \
|
||||
TC_EXCEPTION (MountedVolumeInUse); \
|
||||
TC_EXCEPTION (UnsupportedSectorSize); \
|
||||
TC_EXCEPTION (VolumeEncryptionNotCompleted); \
|
||||
TC_EXCEPTION (VolumeHostInUse); \
|
||||
TC_EXCEPTION (VolumeProtected); \
|
||||
TC_EXCEPTION (VolumeReadOnly);
|
||||
|
||||
TC_EXCEPTION_SET;
|
||||
|
||||
#undef TC_EXCEPTION
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Volume_VolumeExceptions
|
||||
340
src/Volume/VolumeHeader.cpp
Normal file
340
src/Volume/VolumeHeader.cpp
Normal file
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Crc32.h"
|
||||
#include "EncryptionModeXTS.h"
|
||||
#include "Pkcs5Kdf.h"
|
||||
#include "Pkcs5Kdf.h"
|
||||
#include "VolumeHeader.h"
|
||||
#include "VolumeException.h"
|
||||
#include "Common/Crypto.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
VolumeHeader::VolumeHeader (uint32 size)
|
||||
{
|
||||
Init();
|
||||
HeaderSize = size;
|
||||
EncryptedHeaderDataSize = size - EncryptedHeaderDataOffset;
|
||||
}
|
||||
|
||||
VolumeHeader::~VolumeHeader ()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void VolumeHeader::Init ()
|
||||
{
|
||||
VolumeKeyAreaCrc32 = 0;
|
||||
VolumeCreationTime = 0;
|
||||
HeaderCreationTime = 0;
|
||||
mVolumeType = VolumeType::Unknown;
|
||||
HiddenVolumeDataSize = 0;
|
||||
VolumeDataSize = 0;
|
||||
EncryptedAreaStart = 0;
|
||||
EncryptedAreaLength = 0;
|
||||
Flags = 0;
|
||||
SectorSize = 0;
|
||||
}
|
||||
|
||||
void VolumeHeader::Create (const BufferPtr &headerBuffer, VolumeHeaderCreationOptions &options)
|
||||
{
|
||||
if (options.DataKey.Size() != options.EA->GetKeySize() * 2 || options.Salt.Size() != GetSaltSize())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
headerBuffer.Zero();
|
||||
|
||||
HeaderVersion = CurrentHeaderVersion;
|
||||
RequiredMinProgramVersion = CurrentRequiredMinProgramVersion;
|
||||
|
||||
DataAreaKey.Zero();
|
||||
DataAreaKey.CopyFrom (options.DataKey);
|
||||
|
||||
VolumeCreationTime = 0;
|
||||
HiddenVolumeDataSize = (options.Type == VolumeType::Hidden ? options.VolumeDataSize : 0);
|
||||
VolumeDataSize = options.VolumeDataSize;
|
||||
|
||||
EncryptedAreaStart = options.VolumeDataStart;
|
||||
EncryptedAreaLength = options.VolumeDataSize;
|
||||
|
||||
SectorSize = options.SectorSize;
|
||||
|
||||
if (SectorSize < TC_MIN_VOLUME_SECTOR_SIZE
|
||||
|| SectorSize > TC_MAX_VOLUME_SECTOR_SIZE
|
||||
|| SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
|
||||
{
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
EA = options.EA;
|
||||
shared_ptr <EncryptionMode> mode (new EncryptionModeXTS ());
|
||||
EA->SetMode (mode);
|
||||
|
||||
EncryptNew (headerBuffer, options.Salt, options.HeaderKey, options.Kdf);
|
||||
}
|
||||
|
||||
bool VolumeHeader::Decrypt (const ConstBufferPtr &encryptedData, const VolumePassword &password, const Pkcs5KdfList &keyDerivationFunctions, const EncryptionAlgorithmList &encryptionAlgorithms, const EncryptionModeList &encryptionModes)
|
||||
{
|
||||
if (password.Size() < 1)
|
||||
throw PasswordEmpty (SRC_POS);
|
||||
|
||||
ConstBufferPtr salt (encryptedData.GetRange (SaltOffset, SaltSize));
|
||||
SecureBuffer header (EncryptedHeaderDataSize);
|
||||
SecureBuffer headerKey (GetLargestSerializedKeySize());
|
||||
|
||||
foreach (shared_ptr <Pkcs5Kdf> pkcs5, keyDerivationFunctions)
|
||||
{
|
||||
pkcs5->DeriveKey (headerKey, password, salt);
|
||||
|
||||
foreach (shared_ptr <EncryptionMode> mode, encryptionModes)
|
||||
{
|
||||
if (typeid (*mode) != typeid (EncryptionModeXTS))
|
||||
mode->SetKey (headerKey.GetRange (0, mode->GetKeySize()));
|
||||
|
||||
foreach (shared_ptr <EncryptionAlgorithm> ea, encryptionAlgorithms)
|
||||
{
|
||||
if (!ea->IsModeSupported (mode))
|
||||
continue;
|
||||
|
||||
if (typeid (*mode) == typeid (EncryptionModeXTS))
|
||||
{
|
||||
ea->SetKey (headerKey.GetRange (0, ea->GetKeySize()));
|
||||
|
||||
mode = mode->GetNew();
|
||||
mode->SetKey (headerKey.GetRange (ea->GetKeySize(), ea->GetKeySize()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ea->SetKey (headerKey.GetRange (LegacyEncryptionModeKeyAreaSize, ea->GetKeySize()));
|
||||
}
|
||||
|
||||
ea->SetMode (mode);
|
||||
|
||||
header.CopyFrom (encryptedData.GetRange (EncryptedHeaderDataOffset, EncryptedHeaderDataSize));
|
||||
ea->Decrypt (header);
|
||||
|
||||
if (Deserialize (header, ea, mode))
|
||||
{
|
||||
EA = ea;
|
||||
Pkcs5 = pkcs5;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VolumeHeader::Deserialize (const ConstBufferPtr &header, shared_ptr <EncryptionAlgorithm> &ea, shared_ptr <EncryptionMode> &mode)
|
||||
{
|
||||
if (header.Size() != EncryptedHeaderDataSize)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
if (header[0] != 'T' ||
|
||||
header[1] != 'R' ||
|
||||
header[2] != 'U' ||
|
||||
header[3] != 'E')
|
||||
return false;
|
||||
|
||||
size_t offset = 4;
|
||||
HeaderVersion = DeserializeEntry <uint16> (header, offset);
|
||||
|
||||
if (HeaderVersion < MinAllowedHeaderVersion)
|
||||
return false;
|
||||
|
||||
if (HeaderVersion > CurrentHeaderVersion)
|
||||
throw HigherVersionRequired (SRC_POS);
|
||||
|
||||
if (HeaderVersion >= 4
|
||||
&& Crc32::ProcessBuffer (header.GetRange (0, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
|
||||
!= DeserializeEntryAt <uint32> (header, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RequiredMinProgramVersion = DeserializeEntry <uint16> (header, offset);
|
||||
|
||||
if (RequiredMinProgramVersion > Version::Number())
|
||||
throw HigherVersionRequired (SRC_POS);
|
||||
|
||||
VolumeKeyAreaCrc32 = DeserializeEntry <uint32> (header, offset);
|
||||
VolumeCreationTime = DeserializeEntry <uint64> (header, offset);
|
||||
HeaderCreationTime = DeserializeEntry <uint64> (header, offset);
|
||||
HiddenVolumeDataSize = DeserializeEntry <uint64> (header, offset);
|
||||
mVolumeType = (HiddenVolumeDataSize != 0 ? VolumeType::Hidden : VolumeType::Normal);
|
||||
VolumeDataSize = DeserializeEntry <uint64> (header, offset);
|
||||
EncryptedAreaStart = DeserializeEntry <uint64> (header, offset);
|
||||
EncryptedAreaLength = DeserializeEntry <uint64> (header, offset);
|
||||
Flags = DeserializeEntry <uint32> (header, offset);
|
||||
|
||||
SectorSize = DeserializeEntry <uint32> (header, offset);
|
||||
if (HeaderVersion < 5)
|
||||
SectorSize = TC_SECTOR_SIZE_LEGACY;
|
||||
|
||||
if (SectorSize < TC_MIN_VOLUME_SECTOR_SIZE
|
||||
|| SectorSize > TC_MAX_VOLUME_SECTOR_SIZE
|
||||
|| SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
|
||||
{
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
#if !(defined (TC_WINDOWS) || defined (TC_LINUX))
|
||||
if (SectorSize != TC_SECTOR_SIZE_LEGACY)
|
||||
throw UnsupportedSectorSize (SRC_POS);
|
||||
#endif
|
||||
|
||||
offset = DataAreaKeyOffset;
|
||||
|
||||
if (VolumeKeyAreaCrc32 != Crc32::ProcessBuffer (header.GetRange (offset, DataKeyAreaMaxSize)))
|
||||
return false;
|
||||
|
||||
DataAreaKey.CopyFrom (header.GetRange (offset, DataKeyAreaMaxSize));
|
||||
|
||||
ea = ea->GetNew();
|
||||
mode = mode->GetNew();
|
||||
|
||||
if (typeid (*mode) == typeid (EncryptionModeXTS))
|
||||
{
|
||||
ea->SetKey (header.GetRange (offset, ea->GetKeySize()));
|
||||
mode->SetKey (header.GetRange (offset + ea->GetKeySize(), ea->GetKeySize()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mode->SetKey (header.GetRange (offset, mode->GetKeySize()));
|
||||
ea->SetKey (header.GetRange (offset + LegacyEncryptionModeKeyAreaSize, ea->GetKeySize()));
|
||||
}
|
||||
|
||||
ea->SetMode (mode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T VolumeHeader::DeserializeEntry (const ConstBufferPtr &header, size_t &offset) const
|
||||
{
|
||||
offset += sizeof (T);
|
||||
|
||||
if (offset > header.Size())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
return Endian::Big (*reinterpret_cast<const T *> (header.Get() + offset - sizeof (T)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T VolumeHeader::DeserializeEntryAt (const ConstBufferPtr &header, const size_t &offset) const
|
||||
{
|
||||
if (offset > header.Size())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
return Endian::Big (*reinterpret_cast<const T *> (header.Get() + offset));
|
||||
}
|
||||
|
||||
void VolumeHeader::EncryptNew (const BufferPtr &newHeaderBuffer, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr <Pkcs5Kdf> newPkcs5Kdf)
|
||||
{
|
||||
if (newHeaderBuffer.Size() != HeaderSize || newSalt.Size() != SaltSize)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
shared_ptr <EncryptionMode> mode = EA->GetMode()->GetNew();
|
||||
shared_ptr <EncryptionAlgorithm> ea = EA->GetNew();
|
||||
|
||||
if (typeid (*mode) == typeid (EncryptionModeXTS))
|
||||
{
|
||||
mode->SetKey (newHeaderKey.GetRange (EA->GetKeySize(), EA->GetKeySize()));
|
||||
ea->SetKey (newHeaderKey.GetRange (0, ea->GetKeySize()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mode->SetKey (newHeaderKey.GetRange (0, mode->GetKeySize()));
|
||||
ea->SetKey (newHeaderKey.GetRange (LegacyEncryptionModeKeyAreaSize, ea->GetKeySize()));
|
||||
}
|
||||
|
||||
ea->SetMode (mode);
|
||||
|
||||
newHeaderBuffer.CopyFrom (newSalt);
|
||||
|
||||
BufferPtr headerData = newHeaderBuffer.GetRange (EncryptedHeaderDataOffset, EncryptedHeaderDataSize);
|
||||
Serialize (headerData);
|
||||
ea->Encrypt (headerData);
|
||||
|
||||
if (newPkcs5Kdf)
|
||||
Pkcs5 = newPkcs5Kdf;
|
||||
}
|
||||
|
||||
size_t VolumeHeader::GetLargestSerializedKeySize ()
|
||||
{
|
||||
size_t largestKey = EncryptionAlgorithm::GetLargestKeySize (EncryptionAlgorithm::GetAvailableAlgorithms());
|
||||
|
||||
// XTS mode requires the same key size as the encryption algorithm.
|
||||
// Legacy modes may require larger key than XTS.
|
||||
if (LegacyEncryptionModeKeyAreaSize + largestKey > largestKey * 2)
|
||||
return LegacyEncryptionModeKeyAreaSize + largestKey;
|
||||
|
||||
return largestKey * 2;
|
||||
}
|
||||
|
||||
void VolumeHeader::Serialize (const BufferPtr &header) const
|
||||
{
|
||||
if (header.Size() != EncryptedHeaderDataSize)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
header.Zero();
|
||||
|
||||
header[0] = 'T';
|
||||
header[1] = 'R';
|
||||
header[2] = 'U';
|
||||
header[3] = 'E';
|
||||
size_t offset = 4;
|
||||
|
||||
header.GetRange (DataAreaKeyOffset, DataAreaKey.Size()).CopyFrom (DataAreaKey);
|
||||
|
||||
uint16 headerVersion = CurrentHeaderVersion;
|
||||
SerializeEntry (headerVersion, header, offset);
|
||||
SerializeEntry (RequiredMinProgramVersion, header, offset);
|
||||
SerializeEntry (Crc32::ProcessBuffer (header.GetRange (DataAreaKeyOffset, DataKeyAreaMaxSize)), header, offset);
|
||||
|
||||
uint64 reserved64 = 0;
|
||||
SerializeEntry (reserved64, header, offset);
|
||||
SerializeEntry (reserved64, header, offset);
|
||||
|
||||
SerializeEntry (HiddenVolumeDataSize, header, offset);
|
||||
SerializeEntry (VolumeDataSize, header, offset);
|
||||
SerializeEntry (EncryptedAreaStart, header, offset);
|
||||
SerializeEntry (EncryptedAreaLength, header, offset);
|
||||
SerializeEntry (Flags, header, offset);
|
||||
|
||||
if (SectorSize < TC_MIN_VOLUME_SECTOR_SIZE
|
||||
|| SectorSize > TC_MAX_VOLUME_SECTOR_SIZE
|
||||
|| SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
|
||||
{
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
SerializeEntry (SectorSize, header, offset);
|
||||
|
||||
offset = TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC;
|
||||
SerializeEntry (Crc32::ProcessBuffer (header.GetRange (0, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC)), header, offset);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void VolumeHeader::SerializeEntry (const T &entry, const BufferPtr &header, size_t &offset) const
|
||||
{
|
||||
offset += sizeof (T);
|
||||
|
||||
if (offset > header.Size())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
*reinterpret_cast<T *> (header.Get() + offset - sizeof (T)) = Endian::Big (entry);
|
||||
}
|
||||
|
||||
void VolumeHeader::SetSize (uint32 headerSize)
|
||||
{
|
||||
HeaderSize = headerSize;
|
||||
EncryptedHeaderDataSize = HeaderSize - EncryptedHeaderDataOffset;
|
||||
}
|
||||
}
|
||||
126
src/Volume/VolumeHeader.h
Normal file
126
src/Volume/VolumeHeader.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Volume_VolumeHeader
|
||||
#define TC_HEADER_Volume_VolumeHeader
|
||||
|
||||
#include "Common/Tcdefs.h"
|
||||
#include "Common/Volumes.h"
|
||||
#include "Platform/Platform.h"
|
||||
#include "Volume/EncryptionAlgorithm.h"
|
||||
#include "Volume/EncryptionMode.h"
|
||||
#include "Volume/Keyfile.h"
|
||||
#include "Volume/VolumePassword.h"
|
||||
#include "Volume/Pkcs5Kdf.h"
|
||||
#include "Version.h"
|
||||
|
||||
|
||||
// For specifications of the volume header see Common/Volumes.c
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
typedef uint64 VolumeTime;
|
||||
|
||||
struct VolumeType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unknown,
|
||||
Normal,
|
||||
Hidden
|
||||
};
|
||||
};
|
||||
|
||||
struct VolumeHeaderCreationOptions
|
||||
{
|
||||
ConstBufferPtr DataKey;
|
||||
shared_ptr <EncryptionAlgorithm> EA;
|
||||
shared_ptr <Pkcs5Kdf> Kdf;
|
||||
ConstBufferPtr HeaderKey;
|
||||
ConstBufferPtr Salt;
|
||||
uint32 SectorSize;
|
||||
uint64 VolumeDataSize;
|
||||
uint64 VolumeDataStart;
|
||||
VolumeType::Enum Type;
|
||||
};
|
||||
|
||||
class VolumeHeader
|
||||
{
|
||||
public:
|
||||
VolumeHeader (uint32 HeaderSize);
|
||||
virtual ~VolumeHeader ();
|
||||
|
||||
void Create (const BufferPtr &headerBuffer, VolumeHeaderCreationOptions &options);
|
||||
bool Decrypt (const ConstBufferPtr &encryptedData, const VolumePassword &password, const Pkcs5KdfList &keyDerivationFunctions, const EncryptionAlgorithmList &encryptionAlgorithms, const EncryptionModeList &encryptionModes);
|
||||
void EncryptNew (const BufferPtr &newHeaderBuffer, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr <Pkcs5Kdf> newPkcs5Kdf);
|
||||
uint64 GetEncryptedAreaStart () const { return EncryptedAreaStart; }
|
||||
uint64 GetEncryptedAreaLength () const { return EncryptedAreaLength; }
|
||||
shared_ptr <EncryptionAlgorithm> GetEncryptionAlgorithm () const { return EA; }
|
||||
uint32 GetFlags () const { return Flags; }
|
||||
VolumeTime GetHeaderCreationTime () const { return HeaderCreationTime; }
|
||||
uint64 GetHiddenVolumeDataSize () const { return HiddenVolumeDataSize; }
|
||||
static size_t GetLargestSerializedKeySize ();
|
||||
shared_ptr <Pkcs5Kdf> GetPkcs5Kdf () const { return Pkcs5; }
|
||||
uint16 GetRequiredMinProgramVersion () const { return RequiredMinProgramVersion; }
|
||||
size_t GetSectorSize () const { return SectorSize; }
|
||||
static uint32 GetSaltSize () { return SaltSize; }
|
||||
uint64 GetVolumeDataSize () const { return VolumeDataSize; }
|
||||
VolumeTime GetVolumeCreationTime () const { return VolumeCreationTime; }
|
||||
void SetSize (uint32 headerSize);
|
||||
|
||||
protected:
|
||||
bool Deserialize (const ConstBufferPtr &header, shared_ptr <EncryptionAlgorithm> &ea, shared_ptr <EncryptionMode> &mode);
|
||||
template <typename T> T DeserializeEntry (const ConstBufferPtr &header, size_t &offset) const;
|
||||
template <typename T> T DeserializeEntryAt (const ConstBufferPtr &header, const size_t &offset) const;
|
||||
void Init ();
|
||||
void Serialize (const BufferPtr &header) const;
|
||||
template <typename T> void SerializeEntry (const T &entry, const BufferPtr &header, size_t &offset) const;
|
||||
|
||||
uint32 HeaderSize;
|
||||
|
||||
static const uint16 CurrentHeaderVersion = VOLUME_HEADER_VERSION;
|
||||
static const uint16 CurrentRequiredMinProgramVersion = TC_VOLUME_MIN_REQUIRED_PROGRAM_VERSION;
|
||||
static const uint16 MinAllowedHeaderVersion = 1;
|
||||
|
||||
static const int SaltOffset = 0;
|
||||
static const uint32 SaltSize = 64;
|
||||
|
||||
static const int EncryptedHeaderDataOffset = SaltOffset + SaltSize;
|
||||
uint32 EncryptedHeaderDataSize;
|
||||
|
||||
static const uint32 LegacyEncryptionModeKeyAreaSize = 32;
|
||||
static const int DataKeyAreaMaxSize = 256;
|
||||
static const uint32 DataAreaKeyOffset = DataKeyAreaMaxSize - EncryptedHeaderDataOffset;
|
||||
|
||||
shared_ptr <EncryptionAlgorithm> EA;
|
||||
shared_ptr <Pkcs5Kdf> Pkcs5;
|
||||
|
||||
uint16 HeaderVersion;
|
||||
uint16 RequiredMinProgramVersion;
|
||||
uint32 VolumeKeyAreaCrc32;
|
||||
|
||||
VolumeTime VolumeCreationTime;
|
||||
VolumeTime HeaderCreationTime;
|
||||
|
||||
VolumeType::Enum mVolumeType;
|
||||
uint64 HiddenVolumeDataSize;
|
||||
uint64 VolumeDataSize;
|
||||
uint64 EncryptedAreaStart;
|
||||
uint64 EncryptedAreaLength;
|
||||
uint32 Flags;
|
||||
uint32 SectorSize;
|
||||
|
||||
SecureBuffer DataAreaKey;
|
||||
|
||||
private:
|
||||
VolumeHeader (const VolumeHeader &);
|
||||
VolumeHeader &operator= (const VolumeHeader &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Volume_VolumeHeader
|
||||
118
src/Volume/VolumeInfo.cpp
Normal file
118
src/Volume/VolumeInfo.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Common/Tcdefs.h"
|
||||
#include "VolumeInfo.h"
|
||||
#include "Platform/SerializerFactory.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
void VolumeInfo::Deserialize (shared_ptr <Stream> stream)
|
||||
{
|
||||
Serializer sr (stream);
|
||||
|
||||
sr.Deserialize ("ProgramVersion", ProgramVersion);
|
||||
AuxMountPoint = sr.DeserializeWString ("AuxMountPoint");
|
||||
sr.Deserialize ("EncryptionAlgorithmBlockSize", EncryptionAlgorithmBlockSize);
|
||||
sr.Deserialize ("EncryptionAlgorithmKeySize", EncryptionAlgorithmKeySize);
|
||||
sr.Deserialize ("EncryptionAlgorithmMinBlockSize", EncryptionAlgorithmMinBlockSize);
|
||||
EncryptionAlgorithmName = sr.DeserializeWString ("EncryptionAlgorithmName");
|
||||
EncryptionModeName = sr.DeserializeWString ("EncryptionModeName");
|
||||
sr.Deserialize ("HeaderCreationTime", HeaderCreationTime);
|
||||
sr.Deserialize ("HiddenVolumeProtectionTriggered", HiddenVolumeProtectionTriggered);
|
||||
LoopDevice = sr.DeserializeWString ("LoopDevice");
|
||||
|
||||
if (ProgramVersion >= 0x600)
|
||||
sr.Deserialize ("MinRequiredProgramVersion", MinRequiredProgramVersion);
|
||||
|
||||
MountPoint = sr.DeserializeWString ("MountPoint");
|
||||
Path = sr.DeserializeWString ("Path");
|
||||
sr.Deserialize ("Pkcs5IterationCount", Pkcs5IterationCount);
|
||||
Pkcs5PrfName = sr.DeserializeWString ("Pkcs5PrfName");
|
||||
Protection = static_cast <VolumeProtection::Enum> (sr.DeserializeInt32 ("Protection"));
|
||||
sr.Deserialize ("SerialInstanceNumber", SerialInstanceNumber);
|
||||
sr.Deserialize ("Size", Size);
|
||||
sr.Deserialize ("SlotNumber", SlotNumber);
|
||||
|
||||
if (ProgramVersion >= 0x620)
|
||||
sr.Deserialize ("SystemEncryption", SystemEncryption);
|
||||
|
||||
if (ProgramVersion >= 0x600)
|
||||
sr.Deserialize ("TopWriteOffset", TopWriteOffset);
|
||||
|
||||
sr.Deserialize ("TotalDataRead", TotalDataRead);
|
||||
sr.Deserialize ("TotalDataWritten", TotalDataWritten);
|
||||
Type = static_cast <VolumeType::Enum> (sr.DeserializeInt32 ("Type"));
|
||||
VirtualDevice = sr.DeserializeWString ("VirtualDevice");
|
||||
sr.Deserialize ("VolumeCreationTime", VolumeCreationTime);
|
||||
}
|
||||
|
||||
bool VolumeInfo::FirstVolumeMountedAfterSecond (shared_ptr <VolumeInfo> first, shared_ptr <VolumeInfo> second)
|
||||
{
|
||||
return first->SerialInstanceNumber > second->SerialInstanceNumber;
|
||||
}
|
||||
|
||||
void VolumeInfo::Serialize (shared_ptr <Stream> stream) const
|
||||
{
|
||||
Serializable::Serialize (stream);
|
||||
Serializer sr (stream);
|
||||
|
||||
const uint32 version = VERSION_NUM;
|
||||
sr.Serialize ("ProgramVersion", version);
|
||||
sr.Serialize ("AuxMountPoint", wstring (AuxMountPoint));
|
||||
sr.Serialize ("EncryptionAlgorithmBlockSize", EncryptionAlgorithmBlockSize);
|
||||
sr.Serialize ("EncryptionAlgorithmKeySize", EncryptionAlgorithmKeySize);
|
||||
sr.Serialize ("EncryptionAlgorithmMinBlockSize", EncryptionAlgorithmMinBlockSize);
|
||||
sr.Serialize ("EncryptionAlgorithmName", EncryptionAlgorithmName);
|
||||
sr.Serialize ("EncryptionModeName", EncryptionModeName);
|
||||
sr.Serialize ("HeaderCreationTime", HeaderCreationTime);
|
||||
sr.Serialize ("HiddenVolumeProtectionTriggered", HiddenVolumeProtectionTriggered);
|
||||
sr.Serialize ("LoopDevice", wstring (LoopDevice));
|
||||
sr.Serialize ("MinRequiredProgramVersion", MinRequiredProgramVersion);
|
||||
sr.Serialize ("MountPoint", wstring (MountPoint));
|
||||
sr.Serialize ("Path", wstring (Path));
|
||||
sr.Serialize ("Pkcs5IterationCount", Pkcs5IterationCount);
|
||||
sr.Serialize ("Pkcs5PrfName", Pkcs5PrfName);
|
||||
sr.Serialize ("Protection", static_cast <uint32> (Protection));
|
||||
sr.Serialize ("SerialInstanceNumber", SerialInstanceNumber);
|
||||
sr.Serialize ("Size", Size);
|
||||
sr.Serialize ("SlotNumber", SlotNumber);
|
||||
sr.Serialize ("SystemEncryption", SystemEncryption);
|
||||
sr.Serialize ("TopWriteOffset", TopWriteOffset);
|
||||
sr.Serialize ("TotalDataRead", TotalDataRead);
|
||||
sr.Serialize ("TotalDataWritten", TotalDataWritten);
|
||||
sr.Serialize ("Type", static_cast <uint32> (Type));
|
||||
sr.Serialize ("VirtualDevice", wstring (VirtualDevice));
|
||||
sr.Serialize ("VolumeCreationTime", VolumeCreationTime);
|
||||
}
|
||||
|
||||
void VolumeInfo::Set (const Volume &volume)
|
||||
{
|
||||
EncryptionAlgorithmBlockSize = static_cast <uint32> (volume.GetEncryptionAlgorithm()->GetMaxBlockSize());
|
||||
EncryptionAlgorithmKeySize = static_cast <uint32> (volume.GetEncryptionAlgorithm()->GetKeySize());
|
||||
EncryptionAlgorithmMinBlockSize = static_cast <uint32> (volume.GetEncryptionAlgorithm()->GetMinBlockSize());
|
||||
EncryptionAlgorithmName = volume.GetEncryptionAlgorithm()->GetName();
|
||||
EncryptionModeName = volume.GetEncryptionMode()->GetName();
|
||||
HeaderCreationTime = volume.GetHeaderCreationTime();
|
||||
VolumeCreationTime = volume.GetVolumeCreationTime();
|
||||
HiddenVolumeProtectionTriggered = volume.IsHiddenVolumeProtectionTriggered();
|
||||
MinRequiredProgramVersion = volume.GetHeader()->GetRequiredMinProgramVersion();
|
||||
Path = volume.GetPath();
|
||||
Pkcs5IterationCount = volume.GetPkcs5Kdf()->GetIterationCount();
|
||||
Pkcs5PrfName = volume.GetPkcs5Kdf()->GetName();
|
||||
Protection = volume.GetProtectionType();
|
||||
Size = volume.GetSize();
|
||||
SystemEncryption = volume.IsInSystemEncryptionScope();
|
||||
Type = volume.GetType();
|
||||
TopWriteOffset = volume.GetTopWriteOffset();
|
||||
TotalDataRead = volume.GetTotalDataRead();
|
||||
TotalDataWritten = volume.GetTotalDataWritten();
|
||||
}
|
||||
|
||||
TC_SERIALIZER_FACTORY_ADD_CLASS (VolumeInfo);
|
||||
}
|
||||
66
src/Volume/VolumeInfo.h
Normal file
66
src/Volume/VolumeInfo.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Volume_VolumeInfo
|
||||
#define TC_HEADER_Volume_VolumeInfo
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Platform/Serializable.h"
|
||||
#include "Volume/Volume.h"
|
||||
#include "Volume/VolumeSlot.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class VolumeInfo;
|
||||
typedef list < shared_ptr <VolumeInfo> > VolumeInfoList;
|
||||
|
||||
class VolumeInfo : public Serializable
|
||||
{
|
||||
public:
|
||||
VolumeInfo () { }
|
||||
virtual ~VolumeInfo () { }
|
||||
|
||||
TC_SERIALIZABLE (VolumeInfo);
|
||||
static bool FirstVolumeMountedAfterSecond (shared_ptr <VolumeInfo> first, shared_ptr <VolumeInfo> second);
|
||||
void Set (const Volume &volume);
|
||||
|
||||
// Modifying this structure can introduce incompatibility with previous versions
|
||||
DirectoryPath AuxMountPoint;
|
||||
uint32 EncryptionAlgorithmBlockSize;
|
||||
uint32 EncryptionAlgorithmKeySize;
|
||||
uint32 EncryptionAlgorithmMinBlockSize;
|
||||
wstring EncryptionAlgorithmName;
|
||||
wstring EncryptionModeName;
|
||||
VolumeTime HeaderCreationTime;
|
||||
bool HiddenVolumeProtectionTriggered;
|
||||
DevicePath LoopDevice;
|
||||
uint32 MinRequiredProgramVersion;
|
||||
DirectoryPath MountPoint;
|
||||
VolumePath Path;
|
||||
uint32 Pkcs5IterationCount;
|
||||
wstring Pkcs5PrfName;
|
||||
uint32 ProgramVersion;
|
||||
VolumeProtection::Enum Protection;
|
||||
uint64 SerialInstanceNumber;
|
||||
uint64 Size;
|
||||
VolumeSlotNumber SlotNumber;
|
||||
bool SystemEncryption;
|
||||
uint64 TopWriteOffset;
|
||||
uint64 TotalDataRead;
|
||||
uint64 TotalDataWritten;
|
||||
VolumeType::Enum Type;
|
||||
DevicePath VirtualDevice;
|
||||
VolumeTime VolumeCreationTime;
|
||||
|
||||
private:
|
||||
VolumeInfo (const VolumeInfo &);
|
||||
VolumeInfo &operator= (const VolumeInfo &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Volume_VolumeInfo
|
||||
254
src/Volume/VolumeLayout.cpp
Normal file
254
src/Volume/VolumeLayout.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Volume/EncryptionMode.h"
|
||||
#include "Volume/EncryptionModeCBC.h"
|
||||
#include "Volume/EncryptionModeLRW.h"
|
||||
#include "Volume/EncryptionModeXTS.h"
|
||||
#include "VolumeLayout.h"
|
||||
#include "Boot/Windows/BootCommon.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
VolumeLayout::VolumeLayout ()
|
||||
{
|
||||
}
|
||||
|
||||
VolumeLayout::~VolumeLayout ()
|
||||
{
|
||||
}
|
||||
|
||||
VolumeLayoutList VolumeLayout::GetAvailableLayouts (VolumeType::Enum type)
|
||||
{
|
||||
VolumeLayoutList layouts;
|
||||
|
||||
layouts.push_back (shared_ptr <VolumeLayout> (new VolumeLayoutV2Normal ()));
|
||||
layouts.push_back (shared_ptr <VolumeLayout> (new VolumeLayoutV1Normal ()));
|
||||
layouts.push_back (shared_ptr <VolumeLayout> (new VolumeLayoutV2Hidden ()));
|
||||
layouts.push_back (shared_ptr <VolumeLayout> (new VolumeLayoutV1Hidden ()));
|
||||
layouts.push_back (shared_ptr <VolumeLayout> (new VolumeLayoutSystemEncryption ()));
|
||||
|
||||
if (type != VolumeType::Unknown)
|
||||
{
|
||||
VolumeLayoutList l;
|
||||
|
||||
foreach (shared_ptr <VolumeLayout> vl, layouts)
|
||||
{
|
||||
if (vl->GetType() == type)
|
||||
l.push_back (vl);
|
||||
}
|
||||
|
||||
layouts = l;
|
||||
}
|
||||
|
||||
return layouts;
|
||||
}
|
||||
|
||||
shared_ptr <VolumeHeader> VolumeLayout::GetHeader ()
|
||||
{
|
||||
if (Header.get() == nullptr)
|
||||
Header.reset (new VolumeHeader (GetHeaderSize()));
|
||||
|
||||
return Header;
|
||||
}
|
||||
|
||||
|
||||
VolumeLayoutV1Normal::VolumeLayoutV1Normal ()
|
||||
{
|
||||
Type = VolumeType::Normal;
|
||||
HeaderOffset = TC_VOLUME_HEADER_OFFSET;
|
||||
HeaderSize = TC_VOLUME_HEADER_SIZE_LEGACY;
|
||||
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Serpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Twofish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofishSerpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentAES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentTwofishAES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new TwofishSerpent ()));
|
||||
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESBlowfish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESBlowfishSerpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Blowfish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Cast5 ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new TripleDES ()));
|
||||
|
||||
SupportedEncryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
SupportedEncryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedEncryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutV1Normal::GetDataOffset (uint64 volumeHostSize) const
|
||||
{
|
||||
return HeaderSize;
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutV1Normal::GetDataSize (uint64 volumeHostSize) const
|
||||
{
|
||||
return volumeHostSize - GetHeaderSize();
|
||||
}
|
||||
|
||||
|
||||
VolumeLayoutV1Hidden::VolumeLayoutV1Hidden ()
|
||||
{
|
||||
Type = VolumeType::Hidden;
|
||||
HeaderOffset = -TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY;
|
||||
HeaderSize = TC_VOLUME_HEADER_SIZE_LEGACY;
|
||||
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Serpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Twofish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofishSerpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentAES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentTwofishAES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new TwofishSerpent ()));
|
||||
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESBlowfish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESBlowfishSerpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Blowfish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Cast5 ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new TripleDES ()));
|
||||
|
||||
SupportedEncryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
SupportedEncryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeLRW ()));
|
||||
SupportedEncryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeCBC ()));
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutV1Hidden::GetDataOffset (uint64 volumeHostSize) const
|
||||
{
|
||||
return volumeHostSize - GetDataSize (volumeHostSize) + HeaderOffset;
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutV1Hidden::GetDataSize (uint64 volumeHostSize) const
|
||||
{
|
||||
return Header->GetHiddenVolumeDataSize ();
|
||||
}
|
||||
|
||||
|
||||
VolumeLayoutV2Normal::VolumeLayoutV2Normal ()
|
||||
{
|
||||
Type = VolumeType::Normal;
|
||||
HeaderOffset = TC_VOLUME_HEADER_OFFSET;
|
||||
HeaderSize = TC_VOLUME_HEADER_SIZE;
|
||||
BackupHeaderOffset = -TC_VOLUME_HEADER_GROUP_SIZE;
|
||||
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Serpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Twofish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofishSerpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentAES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentTwofishAES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new TwofishSerpent ()));
|
||||
|
||||
SupportedEncryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutV2Normal::GetDataOffset (uint64 volumeHostSize) const
|
||||
{
|
||||
return Header->GetEncryptedAreaStart();
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutV2Normal::GetDataSize (uint64 volumeHostSize) const
|
||||
{
|
||||
return Header->GetVolumeDataSize();
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutV2Normal::GetMaxDataSize (uint64 volumeSize) const
|
||||
{
|
||||
if (volumeSize < TC_TOTAL_VOLUME_HEADERS_SIZE)
|
||||
return 0;
|
||||
|
||||
return volumeSize - TC_TOTAL_VOLUME_HEADERS_SIZE;
|
||||
}
|
||||
|
||||
|
||||
VolumeLayoutV2Hidden::VolumeLayoutV2Hidden ()
|
||||
{
|
||||
Type = VolumeType::Hidden;
|
||||
HeaderOffset = TC_HIDDEN_VOLUME_HEADER_OFFSET;
|
||||
HeaderSize = TC_VOLUME_HEADER_SIZE;
|
||||
BackupHeaderOffset = -TC_HIDDEN_VOLUME_HEADER_OFFSET;
|
||||
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Serpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Twofish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofishSerpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentAES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentTwofishAES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new TwofishSerpent ()));
|
||||
|
||||
SupportedEncryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutV2Hidden::GetDataOffset (uint64 volumeHostSize) const
|
||||
{
|
||||
return Header->GetEncryptedAreaStart();
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutV2Hidden::GetDataSize (uint64 volumeHostSize) const
|
||||
{
|
||||
return Header->GetVolumeDataSize();
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutV2Hidden::GetMaxDataSize (uint64 volumeSize) const
|
||||
{
|
||||
// Reserve free space at the end of the host filesystem
|
||||
uint64 reservedSize;
|
||||
|
||||
if (volumeSize < TC_VOLUME_SMALL_SIZE_THRESHOLD)
|
||||
reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE;
|
||||
else
|
||||
reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH; // Ensure size of a hidden volume larger than TC_VOLUME_SMALL_SIZE_THRESHOLD is a multiple of the maximum supported sector size
|
||||
|
||||
if (volumeSize < reservedSize)
|
||||
return 0;
|
||||
|
||||
return volumeSize - reservedSize;
|
||||
}
|
||||
|
||||
|
||||
VolumeLayoutSystemEncryption::VolumeLayoutSystemEncryption ()
|
||||
{
|
||||
Type = VolumeType::Normal;
|
||||
HeaderOffset = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET;
|
||||
HeaderSize = TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE;
|
||||
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Serpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new Twofish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofish ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofishSerpent ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentAES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentTwofishAES ()));
|
||||
SupportedEncryptionAlgorithms.push_back (shared_ptr <EncryptionAlgorithm> (new TwofishSerpent ()));
|
||||
|
||||
SupportedEncryptionModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ()));
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutSystemEncryption::GetDataOffset (uint64 volumeHostSize) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 VolumeLayoutSystemEncryption::GetDataSize (uint64 volumeHostSize) const
|
||||
{
|
||||
return volumeHostSize;
|
||||
}
|
||||
|
||||
Pkcs5KdfList VolumeLayoutSystemEncryption::GetSupportedKeyDerivationFunctions () const
|
||||
{
|
||||
Pkcs5KdfList l;
|
||||
|
||||
l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacRipemd160_1000 ()));
|
||||
return l;
|
||||
}
|
||||
}
|
||||
153
src/Volume/VolumeLayout.h
Normal file
153
src/Volume/VolumeLayout.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Volume_VolumeLayout
|
||||
#define TC_HEADER_Volume_VolumeLayout
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Volume/EncryptionAlgorithm.h"
|
||||
#include "Volume/EncryptionMode.h"
|
||||
#include "Volume/Pkcs5Kdf.h"
|
||||
#include "VolumeHeader.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class VolumeLayout;
|
||||
typedef list < shared_ptr <VolumeLayout> > VolumeLayoutList;
|
||||
|
||||
class VolumeLayout
|
||||
{
|
||||
public:
|
||||
virtual ~VolumeLayout ();
|
||||
|
||||
static VolumeLayoutList GetAvailableLayouts (VolumeType::Enum type = VolumeType::Unknown);
|
||||
virtual int GetBackupHeaderOffset () const { return BackupHeaderOffset; } // Positive value: offset from the start of host, negative: offset from the end
|
||||
virtual uint64 GetDataOffset (uint64 volumeHostSize) const = 0;
|
||||
virtual uint64 GetDataSize (uint64 volumeHostSize) const = 0;
|
||||
virtual shared_ptr <VolumeHeader> GetHeader ();
|
||||
virtual int GetHeaderOffset () const { return HeaderOffset; } // Positive value: offset from the start of host, negative: offset from the end
|
||||
virtual uint32 GetHeaderSize () const { return HeaderSize; }
|
||||
virtual uint64 GetMaxDataSize (uint64 volumeSize) const = 0;
|
||||
virtual EncryptionAlgorithmList GetSupportedEncryptionAlgorithms () const { return SupportedEncryptionAlgorithms; }
|
||||
virtual Pkcs5KdfList GetSupportedKeyDerivationFunctions () const { return Pkcs5Kdf::GetAvailableAlgorithms(); }
|
||||
virtual EncryptionModeList GetSupportedEncryptionModes () const { return SupportedEncryptionModes; }
|
||||
virtual VolumeType::Enum GetType () const { return Type; }
|
||||
virtual bool HasBackupHeader () const = 0;
|
||||
virtual bool HasDriveHeader () const { return false; }
|
||||
virtual void SetHeader (shared_ptr <VolumeHeader> header) { Header = header; }
|
||||
|
||||
protected:
|
||||
VolumeLayout ();
|
||||
|
||||
EncryptionAlgorithmList SupportedEncryptionAlgorithms;
|
||||
EncryptionModeList SupportedEncryptionModes;
|
||||
|
||||
int BackupHeaderOffset;
|
||||
int HeaderOffset;
|
||||
uint32 HeaderSize;
|
||||
VolumeType::Enum Type;
|
||||
|
||||
shared_ptr <VolumeHeader> Header;
|
||||
|
||||
private:
|
||||
VolumeLayout (const VolumeLayout &);
|
||||
VolumeLayout &operator= (const VolumeLayout &);
|
||||
};
|
||||
|
||||
|
||||
class VolumeLayoutV1Normal : public VolumeLayout
|
||||
{
|
||||
public:
|
||||
VolumeLayoutV1Normal ();
|
||||
virtual ~VolumeLayoutV1Normal () { }
|
||||
|
||||
virtual int GetBackupHeaderOffset () const { throw NotApplicable (SRC_POS); }
|
||||
virtual uint64 GetDataOffset (uint64 volumeHostSize) const;
|
||||
virtual uint64 GetDataSize (uint64 volumeHostSize) const;
|
||||
virtual uint64 GetMaxDataSize (uint64 volumeSize) const { throw NotApplicable (SRC_POS); }
|
||||
virtual bool HasBackupHeader () const { return false; }
|
||||
|
||||
private:
|
||||
VolumeLayoutV1Normal (const VolumeLayoutV1Normal &);
|
||||
VolumeLayoutV1Normal &operator= (const VolumeLayoutV1Normal &);
|
||||
};
|
||||
|
||||
|
||||
class VolumeLayoutV1Hidden : public VolumeLayout
|
||||
{
|
||||
public:
|
||||
VolumeLayoutV1Hidden ();
|
||||
virtual ~VolumeLayoutV1Hidden () { }
|
||||
|
||||
virtual int GetBackupHeaderOffset () const { throw NotApplicable (SRC_POS); }
|
||||
virtual uint64 GetDataOffset (uint64 volumeHostSize) const;
|
||||
virtual uint64 GetDataSize (uint64 volumeHostSize) const;
|
||||
virtual uint64 GetMaxDataSize (uint64 volumeSize) const { throw NotApplicable (SRC_POS); }
|
||||
virtual bool HasBackupHeader () const { return false; }
|
||||
|
||||
private:
|
||||
VolumeLayoutV1Hidden (const VolumeLayoutV1Hidden &);
|
||||
VolumeLayoutV1Hidden &operator= (const VolumeLayoutV1Hidden &);
|
||||
};
|
||||
|
||||
|
||||
class VolumeLayoutV2Normal : public VolumeLayout
|
||||
{
|
||||
public:
|
||||
VolumeLayoutV2Normal ();
|
||||
virtual ~VolumeLayoutV2Normal () { }
|
||||
|
||||
virtual uint64 GetDataOffset (uint64 volumeHostSize) const;
|
||||
virtual uint64 GetDataSize (uint64 volumeHostSize) const;
|
||||
virtual uint64 GetMaxDataSize (uint64 volumeSize) const;
|
||||
virtual bool HasBackupHeader () const { return true; }
|
||||
|
||||
private:
|
||||
VolumeLayoutV2Normal (const VolumeLayoutV2Normal &);
|
||||
VolumeLayoutV2Normal &operator= (const VolumeLayoutV2Normal &);
|
||||
};
|
||||
|
||||
|
||||
class VolumeLayoutV2Hidden : public VolumeLayout
|
||||
{
|
||||
public:
|
||||
VolumeLayoutV2Hidden ();
|
||||
virtual ~VolumeLayoutV2Hidden () { }
|
||||
|
||||
virtual uint64 GetDataOffset (uint64 volumeHostSize) const;
|
||||
virtual uint64 GetDataSize (uint64 volumeHostSize) const;
|
||||
virtual uint64 GetMaxDataSize (uint64 volumeSize) const;
|
||||
virtual bool HasBackupHeader () const { return true; }
|
||||
|
||||
private:
|
||||
VolumeLayoutV2Hidden (const VolumeLayoutV2Hidden &);
|
||||
VolumeLayoutV2Hidden &operator= (const VolumeLayoutV2Hidden &);
|
||||
};
|
||||
|
||||
|
||||
class VolumeLayoutSystemEncryption : public VolumeLayout
|
||||
{
|
||||
public:
|
||||
VolumeLayoutSystemEncryption ();
|
||||
virtual ~VolumeLayoutSystemEncryption () { }
|
||||
|
||||
virtual int GetBackupHeaderOffset () const { throw NotApplicable (SRC_POS); }
|
||||
virtual uint64 GetDataOffset (uint64 volumeHostSize) const;
|
||||
virtual uint64 GetDataSize (uint64 volumeHostSize) const;
|
||||
virtual uint64 GetMaxDataSize (uint64 volumeSize) const { throw NotApplicable (SRC_POS); }
|
||||
virtual Pkcs5KdfList GetSupportedKeyDerivationFunctions () const;
|
||||
virtual bool HasBackupHeader () const { return false; }
|
||||
virtual bool HasDriveHeader () const { return true; }
|
||||
|
||||
private:
|
||||
VolumeLayoutSystemEncryption (const VolumeLayoutSystemEncryption &);
|
||||
VolumeLayoutSystemEncryption &operator= (const VolumeLayoutSystemEncryption &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Volume_VolumeLayout
|
||||
167
src/Volume/VolumePassword.cpp
Normal file
167
src/Volume/VolumePassword.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "VolumePassword.h"
|
||||
#include "Platform/SerializerFactory.h"
|
||||
#include "Platform/StringConverter.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
VolumePassword::VolumePassword () : PasswordSize (0), Unportable (false)
|
||||
{
|
||||
AllocateBuffer ();
|
||||
}
|
||||
|
||||
VolumePassword::VolumePassword (const char *password, size_t size)
|
||||
{
|
||||
Set ((const byte *) password, size);
|
||||
}
|
||||
|
||||
VolumePassword::VolumePassword (const byte *password, size_t size)
|
||||
{
|
||||
Set (password, size);
|
||||
}
|
||||
|
||||
VolumePassword::VolumePassword (const wchar_t *password, size_t charCount)
|
||||
{
|
||||
Set (password, charCount);
|
||||
}
|
||||
|
||||
VolumePassword::VolumePassword (const wstring &password)
|
||||
{
|
||||
Set (password.c_str(), password.size());
|
||||
}
|
||||
|
||||
VolumePassword::~VolumePassword ()
|
||||
{
|
||||
}
|
||||
|
||||
void VolumePassword::AllocateBuffer ()
|
||||
{
|
||||
if (!PasswordBuffer.IsAllocated ())
|
||||
PasswordBuffer.Allocate (MaxSize);
|
||||
}
|
||||
|
||||
void VolumePassword::CheckPortability () const
|
||||
{
|
||||
if (Unportable || !IsPortable())
|
||||
throw UnportablePassword (SRC_POS);
|
||||
}
|
||||
|
||||
void VolumePassword::Deserialize (shared_ptr <Stream> stream)
|
||||
{
|
||||
Serializer sr (stream);
|
||||
uint64 passwordSize;
|
||||
sr.Deserialize ("PasswordSize", passwordSize);
|
||||
PasswordSize = static_cast <size_t> (passwordSize);
|
||||
sr.Deserialize ("PasswordBuffer", BufferPtr (PasswordBuffer));
|
||||
|
||||
Buffer wipeBuffer (128 * 1024);
|
||||
sr.Deserialize ("WipeData", wipeBuffer);
|
||||
}
|
||||
|
||||
bool VolumePassword::IsPortable () const
|
||||
{
|
||||
for (size_t i = 0; i < PasswordSize; i++)
|
||||
{
|
||||
if (PasswordBuffer[i] >= 0x7f || PasswordBuffer[i] < 0x20)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void VolumePassword::Serialize (shared_ptr <Stream> stream) const
|
||||
{
|
||||
Serializable::Serialize (stream);
|
||||
Serializer sr (stream);
|
||||
sr.Serialize ("PasswordSize", static_cast <uint64> (PasswordSize));
|
||||
sr.Serialize ("PasswordBuffer", ConstBufferPtr (PasswordBuffer));
|
||||
|
||||
// Wipe password from an eventual pipe buffer
|
||||
Buffer wipeBuffer (128 * 1024);
|
||||
wipeBuffer.Zero();
|
||||
sr.Serialize ("WipeData", ConstBufferPtr (wipeBuffer));
|
||||
}
|
||||
|
||||
void VolumePassword::Set (const byte *password, size_t size)
|
||||
{
|
||||
AllocateBuffer ();
|
||||
|
||||
if (size > MaxSize)
|
||||
throw PasswordTooLong (SRC_POS);
|
||||
|
||||
PasswordBuffer.CopyFrom (ConstBufferPtr (password, size));
|
||||
PasswordSize = size;
|
||||
|
||||
Unportable = !IsPortable();
|
||||
}
|
||||
|
||||
void VolumePassword::Set (const wchar_t *password, size_t charCount)
|
||||
{
|
||||
if (charCount > MaxSize)
|
||||
throw PasswordTooLong (SRC_POS);
|
||||
|
||||
union Conv
|
||||
{
|
||||
byte b[sizeof (wchar_t)];
|
||||
wchar_t c;
|
||||
};
|
||||
|
||||
Conv conv;
|
||||
conv.c = L'A';
|
||||
|
||||
int lsbPos = -1;
|
||||
for (size_t i = 0; i < sizeof (conv.b); ++i)
|
||||
{
|
||||
if (conv.b[i] == L'A')
|
||||
{
|
||||
lsbPos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lsbPos == -1)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
bool unportable = false;
|
||||
byte passwordBuf[MaxSize];
|
||||
for (size_t i = 0; i < charCount; ++i)
|
||||
{
|
||||
conv.c = password[i];
|
||||
passwordBuf[i] = conv.b[lsbPos];
|
||||
for (int j = 0; j < (int) sizeof (wchar_t); ++j)
|
||||
{
|
||||
if (j != lsbPos && conv.b[j] != 0)
|
||||
unportable = true;
|
||||
}
|
||||
}
|
||||
|
||||
Set (passwordBuf, charCount);
|
||||
|
||||
if (unportable)
|
||||
Unportable = true;
|
||||
}
|
||||
|
||||
void VolumePassword::Set (const ConstBufferPtr &password)
|
||||
{
|
||||
Set (password, password.Size());
|
||||
}
|
||||
|
||||
void VolumePassword::Set (const VolumePassword &password)
|
||||
{
|
||||
Set (password.DataPtr(), password.Size());
|
||||
}
|
||||
|
||||
TC_SERIALIZER_FACTORY_ADD_CLASS (VolumePassword);
|
||||
|
||||
#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
|
||||
#undef TC_EXCEPTION_NODECL
|
||||
#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
|
||||
|
||||
TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (PasswordException);
|
||||
}
|
||||
92
src/Volume/VolumePassword.h
Normal file
92
src/Volume/VolumePassword.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Encryption_Password
|
||||
#define TC_HEADER_Encryption_Password
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "Platform/Serializable.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class VolumePassword : public Serializable
|
||||
{
|
||||
public:
|
||||
VolumePassword ();
|
||||
VolumePassword (const byte *password, size_t size);
|
||||
VolumePassword (const char *password, size_t size);
|
||||
VolumePassword (const wchar_t *password, size_t charCount);
|
||||
VolumePassword (const wstring &password);
|
||||
VolumePassword (const VolumePassword &password) { Set (password); }
|
||||
virtual ~VolumePassword ();
|
||||
|
||||
bool operator== (const VolumePassword &other) const { return ConstBufferPtr (DataPtr(), Size()).IsDataEqual (ConstBufferPtr (other.DataPtr(), other.Size())); }
|
||||
bool operator!= (const VolumePassword &other) const { return !(*this == other); }
|
||||
VolumePassword &operator= (const VolumePassword &password) { Set (password); return *this; }
|
||||
|
||||
operator BufferPtr () const { return BufferPtr (PasswordBuffer); }
|
||||
|
||||
void CheckPortability () const;
|
||||
byte *DataPtr () const { return PasswordBuffer; }
|
||||
bool IsEmpty () const { return PasswordSize == 0; }
|
||||
size_t Size () const { return PasswordSize; }
|
||||
void Set (const byte *password, size_t size);
|
||||
void Set (const wchar_t *password, size_t charCount);
|
||||
void Set (const ConstBufferPtr &password);
|
||||
void Set (const VolumePassword &password);
|
||||
|
||||
TC_SERIALIZABLE (VolumePassword);
|
||||
|
||||
static const size_t MaxSize = 64;
|
||||
static const size_t WarningSizeThreshold = 12;
|
||||
|
||||
protected:
|
||||
void AllocateBuffer ();
|
||||
bool IsPortable () const;
|
||||
|
||||
SecureBuffer PasswordBuffer;
|
||||
|
||||
size_t PasswordSize;
|
||||
bool Unportable;
|
||||
};
|
||||
|
||||
struct PasswordException : public Exception
|
||||
{
|
||||
protected:
|
||||
PasswordException () { }
|
||||
PasswordException (const string &message) : Exception (message) { }
|
||||
PasswordException (const string &message, const wstring &subject) : Exception (message, subject) { }
|
||||
};
|
||||
|
||||
TC_EXCEPTION_DECL (PasswordIncorrect, PasswordException);
|
||||
TC_EXCEPTION_DECL (PasswordKeyfilesIncorrect, PasswordIncorrect);
|
||||
TC_EXCEPTION_DECL (PasswordOrKeyboardLayoutIncorrect, PasswordException);
|
||||
TC_EXCEPTION_DECL (PasswordOrMountOptionsIncorrect, PasswordException);
|
||||
TC_EXCEPTION_DECL (ProtectionPasswordIncorrect, PasswordIncorrect);
|
||||
TC_EXCEPTION_DECL (ProtectionPasswordKeyfilesIncorrect, PasswordIncorrect);
|
||||
|
||||
#define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,PasswordException)
|
||||
|
||||
#undef TC_EXCEPTION_SET
|
||||
#define TC_EXCEPTION_SET \
|
||||
TC_EXCEPTION_NODECL (PasswordIncorrect); \
|
||||
TC_EXCEPTION_NODECL (PasswordKeyfilesIncorrect); \
|
||||
TC_EXCEPTION_NODECL (PasswordOrKeyboardLayoutIncorrect); \
|
||||
TC_EXCEPTION_NODECL (PasswordOrMountOptionsIncorrect); \
|
||||
TC_EXCEPTION_NODECL (ProtectionPasswordIncorrect); \
|
||||
TC_EXCEPTION_NODECL (ProtectionPasswordKeyfilesIncorrect); \
|
||||
TC_EXCEPTION (PasswordEmpty); \
|
||||
TC_EXCEPTION (PasswordTooLong); \
|
||||
TC_EXCEPTION (UnportablePassword);
|
||||
|
||||
TC_EXCEPTION_SET;
|
||||
|
||||
#undef TC_EXCEPTION
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Encryption_Password
|
||||
43
src/Volume/VolumePasswordCache.cpp
Normal file
43
src/Volume/VolumePasswordCache.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "VolumePasswordCache.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
CachedPasswordList VolumePasswordCache::GetPasswords ()
|
||||
{
|
||||
CachedPasswordList passwords;
|
||||
|
||||
foreach_ref (const VolumePassword &password, CachedPasswords)
|
||||
passwords.push_back (make_shared <VolumePassword> (VolumePassword (password)));
|
||||
|
||||
return passwords;
|
||||
}
|
||||
|
||||
void VolumePasswordCache::Store (const VolumePassword &newPassword)
|
||||
{
|
||||
CachedPasswordList::iterator iter = CachedPasswords.begin();
|
||||
foreach_ref (const VolumePassword &password, CachedPasswords)
|
||||
{
|
||||
if (newPassword == password)
|
||||
{
|
||||
CachedPasswords.erase (iter);
|
||||
break;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
CachedPasswords.push_front (make_shared <VolumePassword> (VolumePassword (newPassword)));
|
||||
|
||||
if (CachedPasswords.size() > Capacity)
|
||||
CachedPasswords.pop_back();
|
||||
}
|
||||
|
||||
CachedPasswordList VolumePasswordCache::CachedPasswords;
|
||||
}
|
||||
36
src/Volume/VolumePasswordCache.h
Normal file
36
src/Volume/VolumePasswordCache.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Volume_VolumePasswordCache
|
||||
#define TC_HEADER_Volume_VolumePasswordCache
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
#include "VolumePassword.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
typedef list < shared_ptr < VolumePassword > > CachedPasswordList;
|
||||
|
||||
class VolumePasswordCache
|
||||
{
|
||||
public:
|
||||
static CachedPasswordList GetPasswords ();
|
||||
static bool IsEmpty () { return CachedPasswords.empty(); }
|
||||
static void Store (const VolumePassword &newPassword);
|
||||
static void Clear () { CachedPasswords.clear(); }
|
||||
static const size_t Capacity = 4;
|
||||
|
||||
protected:
|
||||
static CachedPasswordList CachedPasswords;
|
||||
|
||||
private:
|
||||
VolumePasswordCache ();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Volume_VolumePasswordCache
|
||||
19
src/Volume/VolumeSlot.h
Normal file
19
src/Volume/VolumeSlot.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Volume_VolumeSlot
|
||||
#define TC_HEADER_Volume_VolumeSlot
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
typedef uint32 VolumeSlotNumber;
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Volume_VolumeSlot
|
||||
Reference in New Issue
Block a user