mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-06-10 06:46:59 -05:00
Linux: parallelize header KDF autodetection
Extend the Unix encryption thread pool to run key-derivation work items and use it when mounting volumes without an explicitly selected KDF. This brings Linux/macOS header PRF autodetection closer to the Windows path while keeping selected-KDF mounts unchanged. Fixes #1610.
This commit is contained in:
@@ -29,6 +29,7 @@ namespace VeraCrypt
|
|||||||
SyncEvent ();
|
SyncEvent ();
|
||||||
~SyncEvent ();
|
~SyncEvent ();
|
||||||
|
|
||||||
|
void Reset ();
|
||||||
void Signal ();
|
void Signal ();
|
||||||
void Wait ();
|
void Wait ();
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,14 @@ namespace VeraCrypt
|
|||||||
Initialized = false;
|
Initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SyncEvent::Reset ()
|
||||||
|
{
|
||||||
|
assert (Initialized);
|
||||||
|
|
||||||
|
ScopeLock lock (EventMutex);
|
||||||
|
Signaled = false;
|
||||||
|
}
|
||||||
|
|
||||||
void SyncEvent::Signal ()
|
void SyncEvent::Signal ()
|
||||||
{
|
{
|
||||||
assert (Initialized);
|
assert (Initialized);
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ namespace VeraCrypt
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
|
{
|
||||||
|
(void) pAbortKeyDerivation;
|
||||||
|
return DeriveKey (key, password, salt, iterationCount);
|
||||||
|
}
|
||||||
|
|
||||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2b); }
|
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2b); }
|
||||||
virtual int GetIterationCount (int pim) const { return 1; }
|
virtual int GetIterationCount (int pim) const { return 1; }
|
||||||
virtual wstring GetName () const { return L"Argon2"; }
|
virtual wstring GetName () const { return L"Argon2"; }
|
||||||
|
|||||||
@@ -23,9 +23,62 @@
|
|||||||
#include "Platform/SystemLog.h"
|
#include "Platform/SystemLog.h"
|
||||||
#include "Common/Crypto.h"
|
#include "Common/Crypto.h"
|
||||||
#include "EncryptionThreadPool.h"
|
#include "EncryptionThreadPool.h"
|
||||||
|
#include "Pkcs5Kdf.h"
|
||||||
|
|
||||||
namespace VeraCrypt
|
namespace VeraCrypt
|
||||||
{
|
{
|
||||||
|
EncryptionThreadPool::KeyDerivationWorkItem::KeyDerivationWorkItem (shared_ptr <Pkcs5Kdf> kdf, size_t derivedKeySize)
|
||||||
|
: Completed (false), DerivedKey (derivedKeySize), Kdf (kdf), Processed (false), Result (0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EncryptionThreadPool::KeyDerivationWorkItem::~KeyDerivationWorkItem ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void EncryptionThreadPool::BeginKeyDerivation (KeyDerivationWorkItem &keyDerivationWorkItem, const VolumePassword &password, int pim, const ConstBufferPtr &salt, SyncEvent &completionEvent, SyncEvent &noOutstandingWorkItemEvent, SharedVal <size_t> &outstandingWorkItemCount, long volatile *abortFlag)
|
||||||
|
{
|
||||||
|
if (!ThreadPoolRunning)
|
||||||
|
throw NotInitialized (SRC_POS);
|
||||||
|
|
||||||
|
ScopeLock lock (EnqueueMutex);
|
||||||
|
|
||||||
|
WorkItem *workItem = &WorkItemQueue[EnqueuePosition++];
|
||||||
|
|
||||||
|
if (EnqueuePosition >= QueueSize)
|
||||||
|
EnqueuePosition = 0;
|
||||||
|
|
||||||
|
while (workItem->State != WorkItem::State::Free)
|
||||||
|
{
|
||||||
|
WorkItemCompletedEvent.Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
keyDerivationWorkItem.Completed.Set (false);
|
||||||
|
keyDerivationWorkItem.ItemException.reset();
|
||||||
|
keyDerivationWorkItem.Processed = false;
|
||||||
|
keyDerivationWorkItem.Result = 0;
|
||||||
|
|
||||||
|
workItem->Type = WorkType::DeriveKey;
|
||||||
|
workItem->KeyDerivation.AbortFlag = abortFlag;
|
||||||
|
workItem->KeyDerivation.CompletionEvent = &completionEvent;
|
||||||
|
workItem->KeyDerivation.NoOutstandingWorkItemEvent = &noOutstandingWorkItemEvent;
|
||||||
|
workItem->KeyDerivation.OutstandingWorkItemCount = &outstandingWorkItemCount;
|
||||||
|
workItem->KeyDerivation.Password = &password;
|
||||||
|
workItem->KeyDerivation.Pim = pim;
|
||||||
|
workItem->KeyDerivation.Salt = salt.Get();
|
||||||
|
workItem->KeyDerivation.SaltSize = salt.Size();
|
||||||
|
workItem->KeyDerivation.WorkItem = &keyDerivationWorkItem;
|
||||||
|
|
||||||
|
{
|
||||||
|
ScopeLock outstandingWorkItemLock (KeyDerivationCompletionMutex);
|
||||||
|
if (outstandingWorkItemCount.Increment() == 1)
|
||||||
|
noOutstandingWorkItemEvent.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
workItem->State.Set (WorkItem::State::Ready);
|
||||||
|
WorkItemReadyEvent.Signal();
|
||||||
|
}
|
||||||
|
|
||||||
void EncryptionThreadPool::DoWork (WorkType::Enum type, const EncryptionMode *encryptionMode, uint8 *data, uint64 startUnitNo, uint64 unitCount, size_t sectorSize)
|
void EncryptionThreadPool::DoWork (WorkType::Enum type, const EncryptionMode *encryptionMode, uint8 *data, uint64 startUnitNo, uint64 unitCount, size_t sectorSize)
|
||||||
{
|
{
|
||||||
size_t fragmentCount;
|
size_t fragmentCount;
|
||||||
@@ -272,23 +325,56 @@ namespace VeraCrypt
|
|||||||
workItem->Encryption.Mode->EncryptSectorsCurrentThread (workItem->Encryption.Data, workItem->Encryption.StartUnitNo, workItem->Encryption.UnitCount, workItem->Encryption.SectorSize);
|
workItem->Encryption.Mode->EncryptSectorsCurrentThread (workItem->Encryption.Data, workItem->Encryption.StartUnitNo, workItem->Encryption.UnitCount, workItem->Encryption.SectorSize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WorkType::DeriveKey:
|
||||||
|
{
|
||||||
|
KeyDerivationWorkItem *keyDerivationWorkItem = workItem->KeyDerivation.WorkItem;
|
||||||
|
if (workItem->KeyDerivation.AbortFlag && *workItem->KeyDerivation.AbortFlag)
|
||||||
|
keyDerivationWorkItem->Result = ERR_USER_ABORT;
|
||||||
|
else
|
||||||
|
keyDerivationWorkItem->Result = keyDerivationWorkItem->Kdf->DeriveKey (keyDerivationWorkItem->DerivedKey, *workItem->KeyDerivation.Password, workItem->KeyDerivation.Pim, ConstBufferPtr (workItem->KeyDerivation.Salt, workItem->KeyDerivation.SaltSize), workItem->KeyDerivation.AbortFlag);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw ParameterIncorrect (SRC_POS);
|
throw ParameterIncorrect (SRC_POS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception &e)
|
catch (Exception &e)
|
||||||
{
|
{
|
||||||
|
if (workItem->Type == WorkType::DeriveKey)
|
||||||
|
workItem->KeyDerivation.WorkItem->ItemException.reset (e.CloneNew());
|
||||||
|
else
|
||||||
workItem->FirstFragment->ItemException.reset (e.CloneNew());
|
workItem->FirstFragment->ItemException.reset (e.CloneNew());
|
||||||
}
|
}
|
||||||
catch (exception &e)
|
catch (exception &e)
|
||||||
{
|
{
|
||||||
|
if (workItem->Type == WorkType::DeriveKey)
|
||||||
|
workItem->KeyDerivation.WorkItem->ItemException.reset (new ExternalException (SRC_POS, StringConverter::ToExceptionString (e)));
|
||||||
|
else
|
||||||
workItem->FirstFragment->ItemException.reset (new ExternalException (SRC_POS, StringConverter::ToExceptionString (e)));
|
workItem->FirstFragment->ItemException.reset (new ExternalException (SRC_POS, StringConverter::ToExceptionString (e)));
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
if (workItem->Type == WorkType::DeriveKey)
|
||||||
|
workItem->KeyDerivation.WorkItem->ItemException.reset (new UnknownException (SRC_POS));
|
||||||
|
else
|
||||||
workItem->FirstFragment->ItemException.reset (new UnknownException (SRC_POS));
|
workItem->FirstFragment->ItemException.reset (new UnknownException (SRC_POS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (workItem->Type == WorkType::DeriveKey)
|
||||||
|
{
|
||||||
|
workItem->KeyDerivation.WorkItem->Completed.Set (true);
|
||||||
|
workItem->KeyDerivation.CompletionEvent->Signal();
|
||||||
|
{
|
||||||
|
ScopeLock outstandingWorkItemLock (KeyDerivationCompletionMutex);
|
||||||
|
if (workItem->KeyDerivation.OutstandingWorkItemCount->Decrement() == 0)
|
||||||
|
workItem->KeyDerivation.NoOutstandingWorkItemEvent->Signal();
|
||||||
|
}
|
||||||
|
workItem->State.Set (WorkItem::State::Free);
|
||||||
|
WorkItemCompletedEvent.Signal();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (workItem != workItem->FirstFragment)
|
if (workItem != workItem->FirstFragment)
|
||||||
{
|
{
|
||||||
workItem->State.Set (WorkItem::State::Free);
|
workItem->State.Set (WorkItem::State::Free);
|
||||||
@@ -321,6 +407,7 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
Mutex EncryptionThreadPool::EnqueueMutex;
|
Mutex EncryptionThreadPool::EnqueueMutex;
|
||||||
Mutex EncryptionThreadPool::DequeueMutex;
|
Mutex EncryptionThreadPool::DequeueMutex;
|
||||||
|
Mutex EncryptionThreadPool::KeyDerivationCompletionMutex;
|
||||||
|
|
||||||
SyncEvent EncryptionThreadPool::WorkItemReadyEvent;
|
SyncEvent EncryptionThreadPool::WorkItemReadyEvent;
|
||||||
SyncEvent EncryptionThreadPool::WorkItemCompletedEvent;
|
SyncEvent EncryptionThreadPool::WorkItemCompletedEvent;
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
|
|
||||||
namespace VeraCrypt
|
namespace VeraCrypt
|
||||||
{
|
{
|
||||||
|
class Pkcs5Kdf;
|
||||||
|
class VolumePassword;
|
||||||
|
|
||||||
class EncryptionThreadPool
|
class EncryptionThreadPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -31,6 +34,8 @@ namespace VeraCrypt
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct KeyDerivationWorkItem;
|
||||||
|
|
||||||
struct WorkItem
|
struct WorkItem
|
||||||
{
|
{
|
||||||
struct State
|
struct State
|
||||||
@@ -60,9 +65,37 @@ namespace VeraCrypt
|
|||||||
uint64 UnitCount;
|
uint64 UnitCount;
|
||||||
size_t SectorSize;
|
size_t SectorSize;
|
||||||
} Encryption;
|
} Encryption;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
long volatile *AbortFlag;
|
||||||
|
SyncEvent *CompletionEvent;
|
||||||
|
SyncEvent *NoOutstandingWorkItemEvent;
|
||||||
|
SharedVal <size_t> *OutstandingWorkItemCount;
|
||||||
|
const VolumePassword *Password;
|
||||||
|
int Pim;
|
||||||
|
const uint8 *Salt;
|
||||||
|
size_t SaltSize;
|
||||||
|
KeyDerivationWorkItem *WorkItem;
|
||||||
|
} KeyDerivation;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct KeyDerivationWorkItem
|
||||||
|
{
|
||||||
|
KeyDerivationWorkItem (shared_ptr <Pkcs5Kdf> kdf, size_t derivedKeySize);
|
||||||
|
~KeyDerivationWorkItem ();
|
||||||
|
|
||||||
|
SharedVal <bool> Completed;
|
||||||
|
SecureBuffer DerivedKey;
|
||||||
|
unique_ptr <Exception> ItemException;
|
||||||
|
shared_ptr <Pkcs5Kdf> Kdf;
|
||||||
|
bool Processed;
|
||||||
|
int Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Caller-owned references and pointers must remain valid until noOutstandingWorkItemEvent is signaled.
|
||||||
|
static void BeginKeyDerivation (KeyDerivationWorkItem &keyDerivationWorkItem, const VolumePassword &password, int pim, const ConstBufferPtr &salt, SyncEvent &completionEvent, SyncEvent &noOutstandingWorkItemEvent, SharedVal <size_t> &outstandingWorkItemCount, long volatile *abortFlag);
|
||||||
static void DoWork (WorkType::Enum type, const EncryptionMode *mode, uint8 *data, uint64 startUnitNo, uint64 unitCount, size_t sectorSize);
|
static void DoWork (WorkType::Enum type, const EncryptionMode *mode, uint8 *data, uint64 startUnitNo, uint64 unitCount, size_t sectorSize);
|
||||||
static bool IsRunning () { return ThreadPoolRunning; }
|
static bool IsRunning () { return ThreadPoolRunning; }
|
||||||
static void Start ();
|
static void Start ();
|
||||||
@@ -78,6 +111,8 @@ namespace VeraCrypt
|
|||||||
static volatile size_t DequeuePosition;
|
static volatile size_t DequeuePosition;
|
||||||
static volatile size_t EnqueuePosition;
|
static volatile size_t EnqueuePosition;
|
||||||
static Mutex EnqueueMutex;
|
static Mutex EnqueueMutex;
|
||||||
|
// Orders KDF outstanding-count transitions against no-outstanding event updates.
|
||||||
|
static Mutex KeyDerivationCompletionMutex;
|
||||||
static list < shared_ptr <Thread> > RunningThreads;
|
static list < shared_ptr <Thread> > RunningThreads;
|
||||||
static volatile bool StopPending;
|
static volatile bool StopPending;
|
||||||
static size_t ThreadCount;
|
static size_t ThreadCount;
|
||||||
|
|||||||
+72
-10
@@ -30,7 +30,18 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
int Pkcs5Kdf::DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const
|
int Pkcs5Kdf::DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const
|
||||||
{
|
{
|
||||||
return DeriveKey (key, password, salt, GetIterationCount(pim));
|
return DeriveKey (key, password, pim, salt, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5Kdf::DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt, long volatile *pAbortKeyDerivation) const
|
||||||
|
{
|
||||||
|
return DeriveKey (key, password, salt, GetIterationCount(pim), pAbortKeyDerivation);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5Kdf::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
|
{
|
||||||
|
(void) pAbortKeyDerivation;
|
||||||
|
return DeriveKey (key, password, salt, iterationCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring Pkcs5Kdf::GetDerivationFailureMessage (int result) const
|
wstring Pkcs5Kdf::GetDerivationFailureMessage (int result) const
|
||||||
@@ -88,65 +99,105 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
#ifndef WOLFCRYPT_BACKEND
|
#ifndef WOLFCRYPT_BACKEND
|
||||||
int Pkcs5HmacBlake2s_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
int Pkcs5HmacBlake2s_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||||
|
{
|
||||||
|
return DeriveKey (key, password, salt, iterationCount, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5HmacBlake2s_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
{
|
{
|
||||||
ValidateParameters (key, password, salt, iterationCount);
|
ValidateParameters (key, password, salt, iterationCount);
|
||||||
derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
|
derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), pAbortKeyDerivation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Pkcs5HmacBlake2s::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
int Pkcs5HmacBlake2s::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||||
|
{
|
||||||
|
return DeriveKey (key, password, salt, iterationCount, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5HmacBlake2s::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
{
|
{
|
||||||
ValidateParameters (key, password, salt, iterationCount);
|
ValidateParameters (key, password, salt, iterationCount);
|
||||||
derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
|
derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), pAbortKeyDerivation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int Pkcs5HmacSha256_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
int Pkcs5HmacSha256_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||||
|
{
|
||||||
|
return DeriveKey (key, password, salt, iterationCount, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5HmacSha256_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
{
|
{
|
||||||
ValidateParameters (key, password, salt, iterationCount);
|
ValidateParameters (key, password, salt, iterationCount);
|
||||||
derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
|
derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), pAbortKeyDerivation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Pkcs5HmacSha256::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
int Pkcs5HmacSha256::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||||
|
{
|
||||||
|
return DeriveKey (key, password, salt, iterationCount, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5HmacSha256::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
{
|
{
|
||||||
ValidateParameters (key, password, salt, iterationCount);
|
ValidateParameters (key, password, salt, iterationCount);
|
||||||
derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
|
derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), pAbortKeyDerivation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Pkcs5HmacSha512::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
int Pkcs5HmacSha512::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||||
|
{
|
||||||
|
return DeriveKey (key, password, salt, iterationCount, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5HmacSha512::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
{
|
{
|
||||||
ValidateParameters (key, password, salt, iterationCount);
|
ValidateParameters (key, password, salt, iterationCount);
|
||||||
derive_key_sha512 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
|
derive_key_sha512 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), pAbortKeyDerivation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WOLFCRYPT_BACKEND
|
#ifndef WOLFCRYPT_BACKEND
|
||||||
int Pkcs5HmacWhirlpool::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
int Pkcs5HmacWhirlpool::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||||
|
{
|
||||||
|
return DeriveKey (key, password, salt, iterationCount, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5HmacWhirlpool::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
{
|
{
|
||||||
ValidateParameters (key, password, salt, iterationCount);
|
ValidateParameters (key, password, salt, iterationCount);
|
||||||
derive_key_whirlpool (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
|
derive_key_whirlpool (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), pAbortKeyDerivation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Pkcs5HmacStreebog::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
int Pkcs5HmacStreebog::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||||
|
{
|
||||||
|
return DeriveKey (key, password, salt, iterationCount, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5HmacStreebog::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
{
|
{
|
||||||
ValidateParameters (key, password, salt, iterationCount);
|
ValidateParameters (key, password, salt, iterationCount);
|
||||||
derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
|
derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), pAbortKeyDerivation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef VC_DCS_DISABLE_ARGON2
|
#ifndef VC_DCS_DISABLE_ARGON2
|
||||||
int Pkcs5Argon2::DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const
|
int Pkcs5Argon2::DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const
|
||||||
|
{
|
||||||
|
return DeriveKey (key, password, pim, salt, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5Argon2::DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt, long volatile *pAbortKeyDerivation) const
|
||||||
{
|
{
|
||||||
int iterationCount;
|
int iterationCount;
|
||||||
int memoryCost;
|
int memoryCost;
|
||||||
get_argon2_params (pim, &iterationCount, &memoryCost);
|
get_argon2_params (pim, &iterationCount, &memoryCost);
|
||||||
|
|
||||||
ValidateParameters (key, password, salt, iterationCount);
|
ValidateParameters (key, password, salt, iterationCount);
|
||||||
return derive_key_argon2 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, memoryCost, key.Get(), (int) key.Size(), NULL);
|
return derive_key_argon2 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, memoryCost, key.Get(), (int) key.Size(), pAbortKeyDerivation);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Pkcs5Argon2::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
int Pkcs5Argon2::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||||
@@ -158,6 +209,12 @@ namespace VeraCrypt
|
|||||||
throw ParameterIncorrect (SRC_POS);
|
throw ParameterIncorrect (SRC_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Pkcs5Argon2::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
|
{
|
||||||
|
(void) pAbortKeyDerivation;
|
||||||
|
return DeriveKey (key, password, salt, iterationCount);
|
||||||
|
}
|
||||||
|
|
||||||
wstring Pkcs5Argon2::GetDerivationFailureMessage (int result) const
|
wstring Pkcs5Argon2::GetDerivationFailureMessage (int result) const
|
||||||
{
|
{
|
||||||
return L"Argon2 key derivation failed: " + StringConverter::ToWide (argon2_error_message (result));
|
return L"Argon2 key derivation failed: " + StringConverter::ToWide (argon2_error_message (result));
|
||||||
@@ -173,9 +230,14 @@ namespace VeraCrypt
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int Pkcs5HmacStreebog_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
int Pkcs5HmacStreebog_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const
|
||||||
|
{
|
||||||
|
return DeriveKey (key, password, salt, iterationCount, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pkcs5HmacStreebog_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const
|
||||||
{
|
{
|
||||||
ValidateParameters (key, password, salt, iterationCount);
|
ValidateParameters (key, password, salt, iterationCount);
|
||||||
derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), NULL);
|
derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size(), pAbortKeyDerivation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ namespace VeraCrypt
|
|||||||
virtual ~Pkcs5Kdf ();
|
virtual ~Pkcs5Kdf ();
|
||||||
|
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const = 0;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const = 0;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const = 0;
|
||||||
static shared_ptr <Pkcs5Kdf> GetAlgorithm (const wstring &name);
|
static shared_ptr <Pkcs5Kdf> GetAlgorithm (const wstring &name);
|
||||||
static shared_ptr <Pkcs5Kdf> GetAlgorithm (const Hash &hash);
|
static shared_ptr <Pkcs5Kdf> GetAlgorithm (const Hash &hash);
|
||||||
static Pkcs5KdfList GetAvailableAlgorithms ();
|
static Pkcs5KdfList GetAvailableAlgorithms ();
|
||||||
@@ -63,6 +65,7 @@ namespace VeraCrypt
|
|||||||
virtual ~Pkcs5HmacBlake2s_Boot () { }
|
virtual ~Pkcs5HmacBlake2s_Boot () { }
|
||||||
|
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2s); }
|
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2s); }
|
||||||
virtual int GetDefaultPim () const { return 98; }
|
virtual int GetDefaultPim () const { return 98; }
|
||||||
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 200000 : (pim * 2048); }
|
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 200000 : (pim * 2048); }
|
||||||
@@ -81,6 +84,7 @@ namespace VeraCrypt
|
|||||||
virtual ~Pkcs5HmacBlake2s () { }
|
virtual ~Pkcs5HmacBlake2s () { }
|
||||||
|
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2s); }
|
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2s); }
|
||||||
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 500000 : (15000 + (pim * 1000)); }
|
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 500000 : (15000 + (pim * 1000)); }
|
||||||
virtual wstring GetName () const { return L"HMAC-BLAKE2s-256"; }
|
virtual wstring GetName () const { return L"HMAC-BLAKE2s-256"; }
|
||||||
@@ -99,6 +103,7 @@ namespace VeraCrypt
|
|||||||
virtual ~Pkcs5HmacSha256_Boot () { }
|
virtual ~Pkcs5HmacSha256_Boot () { }
|
||||||
|
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha256); }
|
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha256); }
|
||||||
virtual int GetDefaultPim () const { return 98; }
|
virtual int GetDefaultPim () const { return 98; }
|
||||||
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 200000 : (pim * 2048); }
|
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 200000 : (pim * 2048); }
|
||||||
@@ -117,6 +122,7 @@ namespace VeraCrypt
|
|||||||
virtual ~Pkcs5HmacSha256 () { }
|
virtual ~Pkcs5HmacSha256 () { }
|
||||||
|
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha256); }
|
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha256); }
|
||||||
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 500000 : (15000 + (pim * 1000)); }
|
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 500000 : (15000 + (pim * 1000)); }
|
||||||
virtual wstring GetName () const { return L"HMAC-SHA-256"; }
|
virtual wstring GetName () const { return L"HMAC-SHA-256"; }
|
||||||
@@ -134,6 +140,7 @@ namespace VeraCrypt
|
|||||||
virtual ~Pkcs5HmacSha512 () { }
|
virtual ~Pkcs5HmacSha512 () { }
|
||||||
|
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha512); }
|
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Sha512); }
|
||||||
virtual int GetIterationCount (int pim) const { return (pim <= 0 ? 500000 : (15000 + (pim * 1000))); }
|
virtual int GetIterationCount (int pim) const { return (pim <= 0 ? 500000 : (15000 + (pim * 1000))); }
|
||||||
virtual wstring GetName () const { return L"HMAC-SHA-512"; }
|
virtual wstring GetName () const { return L"HMAC-SHA-512"; }
|
||||||
@@ -151,6 +158,7 @@ namespace VeraCrypt
|
|||||||
virtual ~Pkcs5HmacWhirlpool () { }
|
virtual ~Pkcs5HmacWhirlpool () { }
|
||||||
|
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Whirlpool); }
|
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Whirlpool); }
|
||||||
virtual int GetIterationCount (int pim) const { return (pim <= 0 ? 500000 : (15000 + (pim * 1000))); }
|
virtual int GetIterationCount (int pim) const { return (pim <= 0 ? 500000 : (15000 + (pim * 1000))); }
|
||||||
virtual wstring GetName () const { return L"HMAC-Whirlpool"; }
|
virtual wstring GetName () const { return L"HMAC-Whirlpool"; }
|
||||||
@@ -168,6 +176,7 @@ namespace VeraCrypt
|
|||||||
virtual ~Pkcs5HmacStreebog () { }
|
virtual ~Pkcs5HmacStreebog () { }
|
||||||
|
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Streebog); }
|
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Streebog); }
|
||||||
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 500000 : (15000 + (pim * 1000)); }
|
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 500000 : (15000 + (pim * 1000)); }
|
||||||
virtual wstring GetName () const { return L"HMAC-Streebog"; }
|
virtual wstring GetName () const { return L"HMAC-Streebog"; }
|
||||||
@@ -186,7 +195,9 @@ namespace VeraCrypt
|
|||||||
virtual ~Pkcs5Argon2 () { }
|
virtual ~Pkcs5Argon2 () { }
|
||||||
|
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, int pim, const ConstBufferPtr &salt, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual wstring GetDerivationFailureMessage (int result) const;
|
virtual wstring GetDerivationFailureMessage (int result) const;
|
||||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2b); }
|
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Blake2b); }
|
||||||
virtual int GetDefaultPim () const { return 12; }
|
virtual int GetDefaultPim () const { return 12; }
|
||||||
@@ -212,6 +223,7 @@ namespace VeraCrypt
|
|||||||
virtual ~Pkcs5HmacStreebog_Boot () { }
|
virtual ~Pkcs5HmacStreebog_Boot () { }
|
||||||
|
|
||||||
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const;
|
||||||
|
virtual int DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount, long volatile *pAbortKeyDerivation) const;
|
||||||
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Streebog); }
|
virtual shared_ptr <Hash> GetHash () const { return shared_ptr <Hash> (new Streebog); }
|
||||||
virtual int GetDefaultPim () const { return 98; }
|
virtual int GetDefaultPim () const { return 98; }
|
||||||
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 200000 : pim * 2048; }
|
virtual int GetIterationCount (int pim) const { return pim <= 0 ? 200000 : pim * 2048; }
|
||||||
|
|||||||
@@ -11,18 +11,27 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Crc32.h"
|
#include "Crc32.h"
|
||||||
|
#include "EncryptionThreadPool.h"
|
||||||
#include "EncryptionModeXTS.h"
|
#include "EncryptionModeXTS.h"
|
||||||
#ifdef WOLFCRYPT_BACKEND
|
#ifdef WOLFCRYPT_BACKEND
|
||||||
#include "EncryptionModeWolfCryptXTS.h"
|
#include "EncryptionModeWolfCryptXTS.h"
|
||||||
#endif
|
#endif
|
||||||
#include "Pkcs5Kdf.h"
|
#include "Pkcs5Kdf.h"
|
||||||
#include "Pkcs5Kdf.h"
|
|
||||||
#include "VolumeHeader.h"
|
#include "VolumeHeader.h"
|
||||||
#include "VolumeException.h"
|
#include "VolumeException.h"
|
||||||
#include "Common/Crypto.h"
|
#include "Common/Crypto.h"
|
||||||
|
|
||||||
namespace VeraCrypt
|
namespace VeraCrypt
|
||||||
{
|
{
|
||||||
|
static void DrainKeyDerivationWorkItems (SyncEvent &noOutstandingWorkItemEvent, size_t enqueuedWorkItemCount, bool &workItemsDrained)
|
||||||
|
{
|
||||||
|
if (enqueuedWorkItemCount > 0 && !workItemsDrained)
|
||||||
|
{
|
||||||
|
noOutstandingWorkItemEvent.Wait();
|
||||||
|
workItemsDrained = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VolumeHeader::VolumeHeader (uint32 size)
|
VolumeHeader::VolumeHeader (uint32 size)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
@@ -99,7 +108,76 @@ namespace VeraCrypt
|
|||||||
throw PasswordEmpty (SRC_POS);
|
throw PasswordEmpty (SRC_POS);
|
||||||
|
|
||||||
ConstBufferPtr salt (encryptedData.GetRange (SaltOffset, SaltSize));
|
ConstBufferPtr salt (encryptedData.GetRange (SaltOffset, SaltSize));
|
||||||
SecureBuffer header (EncryptedHeaderDataSize);
|
|
||||||
|
if (!kdf && EncryptionThreadPool::IsRunning() && keyDerivationFunctions.size() > 1)
|
||||||
|
{
|
||||||
|
typedef EncryptionThreadPool::KeyDerivationWorkItem KeyDerivationWorkItem;
|
||||||
|
|
||||||
|
list < shared_ptr <KeyDerivationWorkItem> > keyDerivationWorkItems;
|
||||||
|
SharedVal <size_t> outstandingWorkItemCount (0);
|
||||||
|
SyncEvent keyDerivationCompletedEvent;
|
||||||
|
SyncEvent noOutstandingWorkItemEvent;
|
||||||
|
long volatile abortKeyDerivation = 0;
|
||||||
|
size_t enqueuedWorkItemCount = 0;
|
||||||
|
size_t processedWorkItemCount = 0;
|
||||||
|
bool workItemsDrained = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (shared_ptr <Pkcs5Kdf> pkcs5, keyDerivationFunctions)
|
||||||
|
{
|
||||||
|
shared_ptr <KeyDerivationWorkItem> keyDerivationWorkItem (new KeyDerivationWorkItem (pkcs5, GetHeaderKeyDerivationSize (pkcs5)));
|
||||||
|
keyDerivationWorkItems.push_back (keyDerivationWorkItem);
|
||||||
|
EncryptionThreadPool::BeginKeyDerivation (*keyDerivationWorkItem, password, pim, salt, keyDerivationCompletedEvent, noOutstandingWorkItemEvent, outstandingWorkItemCount, &abortKeyDerivation);
|
||||||
|
++enqueuedWorkItemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (processedWorkItemCount < keyDerivationWorkItems.size())
|
||||||
|
{
|
||||||
|
bool processed = false;
|
||||||
|
|
||||||
|
foreach (shared_ptr <KeyDerivationWorkItem> keyDerivationWorkItem, keyDerivationWorkItems)
|
||||||
|
{
|
||||||
|
if (!keyDerivationWorkItem->Processed && keyDerivationWorkItem->Completed.Get())
|
||||||
|
{
|
||||||
|
keyDerivationWorkItem->Processed = true;
|
||||||
|
++processedWorkItemCount;
|
||||||
|
processed = true;
|
||||||
|
|
||||||
|
if (keyDerivationWorkItem->ItemException.get())
|
||||||
|
{
|
||||||
|
// KDF exceptions are fatal setup/runtime errors; candidate failures are reported via Result.
|
||||||
|
abortKeyDerivation = 1;
|
||||||
|
DrainKeyDerivationWorkItems (noOutstandingWorkItemEvent, enqueuedWorkItemCount, workItemsDrained);
|
||||||
|
keyDerivationWorkItem->ItemException->Throw();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyDerivationWorkItem->Result != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (DecryptWithHeaderKey (encryptedData, keyDerivationWorkItem->Kdf, keyDerivationWorkItem->DerivedKey, encryptionAlgorithms, encryptionModes))
|
||||||
|
{
|
||||||
|
abortKeyDerivation = 1;
|
||||||
|
DrainKeyDerivationWorkItems (noOutstandingWorkItemEvent, enqueuedWorkItemCount, workItemsDrained);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processedWorkItemCount < keyDerivationWorkItems.size() && !processed)
|
||||||
|
keyDerivationCompletedEvent.Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
abortKeyDerivation = 1;
|
||||||
|
DrainKeyDerivationWorkItems (noOutstandingWorkItemEvent, enqueuedWorkItemCount, workItemsDrained);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrainKeyDerivationWorkItems (noOutstandingWorkItemEvent, enqueuedWorkItemCount, workItemsDrained);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (shared_ptr <Pkcs5Kdf> pkcs5, keyDerivationFunctions)
|
foreach (shared_ptr <Pkcs5Kdf> pkcs5, keyDerivationFunctions)
|
||||||
{
|
{
|
||||||
@@ -116,6 +194,17 @@ namespace VeraCrypt
|
|||||||
throw ExternalException (SRC_POS, pkcs5->GetDerivationFailureMessage (derivationResult));
|
throw ExternalException (SRC_POS, pkcs5->GetDerivationFailureMessage (derivationResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DecryptWithHeaderKey (encryptedData, pkcs5, headerKey, encryptionAlgorithms, encryptionModes))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VolumeHeader::DecryptWithHeaderKey (const ConstBufferPtr &encryptedData, shared_ptr <Pkcs5Kdf> pkcs5, const ConstBufferPtr &headerKey, const EncryptionAlgorithmList &encryptionAlgorithms, const EncryptionModeList &encryptionModes)
|
||||||
|
{
|
||||||
|
SecureBuffer header (EncryptedHeaderDataSize);
|
||||||
|
|
||||||
foreach (shared_ptr <EncryptionMode> mode, encryptionModes)
|
foreach (shared_ptr <EncryptionMode> mode, encryptionModes)
|
||||||
{
|
{
|
||||||
#ifdef WOLFCRYPT_BACKEND
|
#ifdef WOLFCRYPT_BACKEND
|
||||||
@@ -168,7 +257,6 @@ namespace VeraCrypt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ namespace VeraCrypt
|
|||||||
bool IsMasterKeyVulnerable () const { return XtsKeyVulnerable; }
|
bool IsMasterKeyVulnerable () const { return XtsKeyVulnerable; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool DecryptWithHeaderKey (const ConstBufferPtr &encryptedData, shared_ptr <Pkcs5Kdf> pkcs5, const ConstBufferPtr &headerKey, const EncryptionAlgorithmList &encryptionAlgorithms, const EncryptionModeList &encryptionModes);
|
||||||
bool Deserialize (const ConstBufferPtr &header, shared_ptr <EncryptionAlgorithm> &ea, shared_ptr <EncryptionMode> &mode);
|
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 DeserializeEntry (const ConstBufferPtr &header, size_t &offset) const;
|
||||||
template <typename T> T DeserializeEntryAt (const ConstBufferPtr &header, const size_t &offset) const;
|
template <typename T> T DeserializeEntryAt (const ConstBufferPtr &header, const size_t &offset) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user