VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Volumes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/Volumes.c')
-rw-r--r--src/Common/Volumes.c83
1 files changed, 3 insertions, 80 deletions
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c
index 15ee8fe6..9a0d3efc 100644
--- a/src/Common/Volumes.c
+++ b/src/Common/Volumes.c
@@ -223,44 +223,41 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, PCR
{
CloseHandle (keyDerivationCompletedEvent);
TCfree (keyDerivationWorkItems);
return ERR_OUTOFMEMORY;
}
#endif
}
#ifndef DEVICE_DRIVER
VirtualLock (&keyInfo, sizeof (keyInfo));
VirtualLock (&dk, sizeof (dk));
#endif
crypto_loadkey (&keyInfo, password->Text, (int) password->Length);
// PKCS5 is used to derive the primary header key(s) and secondary header key(s) (XTS mode) from the password
memcpy (keyInfo.salt, encryptedHeader + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE);
// Test all available PKCS5 PRFs
for (enqPkcs5Prf = FIRST_PRF_ID; enqPkcs5Prf <= LAST_PRF_ID || queuedWorkItems > 0; ++enqPkcs5Prf)
- {
- BOOL lrw64InitDone = FALSE; // Deprecated/legacy
- BOOL lrw128InitDone = FALSE; // Deprecated/legacy
-
+ {
if (encryptionThreadCount > 1)
{
// Enqueue key derivation on thread pool
if (queuedWorkItems < encryptionThreadCount && enqPkcs5Prf <= LAST_PRF_ID)
{
for (i = 0; i < pkcs5PrfCount; ++i)
{
item = &keyDerivationWorkItems[i];
if (item->Free)
{
item->Free = FALSE;
item->KeyReady = FALSE;
item->Pkcs5Prf = enqPkcs5Prf;
EncryptionThreadPoolBeginKeyDerivation (&keyDerivationCompletedEvent, &noOutstandingWorkItemEvent,
&item->KeyReady, &outstandingWorkItemCount, enqPkcs5Prf, keyInfo.userKey,
keyInfo.keyLength, keyInfo.salt, get_pkcs5_iteration_count (enqPkcs5Prf, bBoot), item->DerivedKey);
++queuedWorkItems;
break;
@@ -297,124 +294,96 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, PCR
continue;
KeyReady: ;
}
else
{
pkcs5_prf = enqPkcs5Prf;
keyInfo.noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, bBoot);
switch (pkcs5_prf)
{
case RIPEMD160:
derive_key_ripemd160 (TRUE, keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;
case SHA512:
derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;
- case SHA1:
- // Deprecated/legacy
- derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
- PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
- break;
-
case WHIRLPOOL:
derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;
default:
// Unknown/wrong ID
TC_THROW_FATAL_EXCEPTION;
}
}
// Test all available modes of operation
for (cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
cryptoInfo->mode <= LAST_MODE_OF_OPERATION;
cryptoInfo->mode++)
{
switch (cryptoInfo->mode)
{
- case LRW:
- case CBC:
- case INNER_CBC:
- case OUTER_CBC:
-
- // For LRW (deprecated/legacy), copy the tweak key
- // For CBC (deprecated/legacy), copy the IV/whitening seed
- memcpy (cryptoInfo->k2, dk, LEGACY_VOL_IV_SIZE);
- primaryKeyOffset = LEGACY_VOL_IV_SIZE;
- break;
default:
primaryKeyOffset = 0;
}
// Test all available encryption algorithms
for (cryptoInfo->ea = EAGetFirst ();
cryptoInfo->ea != 0;
cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
{
int blockSize;
if (!EAIsModeSupported (cryptoInfo->ea, cryptoInfo->mode))
continue; // This encryption algorithm has never been available with this mode of operation
blockSize = CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea));
status = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
if (status == ERR_CIPHER_INIT_FAILURE)
goto err;
// Init objects related to the mode of operation
if (cryptoInfo->mode == XTS)
{
// Copy the secondary key (if cascade, multiple concatenated)
memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
// Secondary key schedule
if (!EAInitMode (cryptoInfo))
{
status = ERR_MODE_INIT_FAILED;
goto err;
}
}
- else if (cryptoInfo->mode == LRW
- && (blockSize == 8 && !lrw64InitDone || blockSize == 16 && !lrw128InitDone))
+ else
{
- // Deprecated/legacy
-
- if (!EAInitMode (cryptoInfo))
- {
- status = ERR_MODE_INIT_FAILED;
- goto err;
- }
-
- if (blockSize == 8)
- lrw64InitDone = TRUE;
- else if (blockSize == 16)
- lrw128InitDone = TRUE;
+ continue;
}
// Copy the header for decryption
memcpy (header, encryptedHeader, sizeof (header));
// Try to decrypt header
DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
// Magic 'VERA'
if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241)
continue;
// Header version
headerVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION);
if (headerVersion > VOLUME_HEADER_VERSION)
{
status = ERR_NEW_VERSION_REQUIRED;
goto err;
@@ -502,49 +471,40 @@ KeyReady: ;
memcpy (cryptoInfo, retHeaderCryptoInfo, sizeof (*cryptoInfo));
}
// Master key data
memcpy (keyInfo.master_keydata, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE);
memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
// PKCS #5
memcpy (cryptoInfo->salt, keyInfo.salt, PKCS5_SALT_SIZE);
cryptoInfo->pkcs5 = pkcs5_prf;
cryptoInfo->noIterations = keyInfo.noIterations;
// Init the cipher with the decrypted master key
status = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
if (status == ERR_CIPHER_INIT_FAILURE)
goto err;
switch (cryptoInfo->mode)
{
- case LRW:
- case CBC:
- case INNER_CBC:
- case OUTER_CBC:
-
- // For LRW (deprecated/legacy), the tweak key
- // For CBC (deprecated/legacy), the IV/whitening seed
- memcpy (cryptoInfo->k2, keyInfo.master_keydata, LEGACY_VOL_IV_SIZE);
- break;
default:
// The secondary master key (if cascade, multiple concatenated)
memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
}
if (!EAInitMode (cryptoInfo))
{
status = ERR_MODE_INIT_FAILED;
goto err;
}
status = ERR_SUCCESS;
goto ret;
}
}
}
status = ERR_PASSWORD_WRONG;
@@ -704,95 +664,77 @@ int CreateVolumeHeaderInMemory (BOOL bBoot, char *header, int ea, int mode, Pass
int primaryKeyOffset;
if (cryptoInfo == NULL)
return ERR_OUTOFMEMORY;
memset (header, 0, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
VirtualLock (&keyInfo, sizeof (keyInfo));
VirtualLock (&dk, sizeof (dk));
/* Encryption setup */
if (masterKeydata == NULL)
{
// We have no master key data (creating a new volume) so we'll use the TrueCrypt RNG to generate them
int bytesNeeded;
switch (mode)
{
- case LRW:
- case CBC:
- case INNER_CBC:
- case OUTER_CBC:
-
- // Deprecated/legacy modes of operation
- bytesNeeded = LEGACY_VOL_IV_SIZE + EAGetKeySize (ea);
-
- // In fact, this should never be the case since volumes being newly created are not
- // supposed to use any deprecated mode of operation.
- TC_THROW_FATAL_EXCEPTION;
- break;
default:
bytesNeeded = EAGetKeySize (ea) * 2; // Size of primary + secondary key(s)
}
if (!RandgetBytes (keyInfo.master_keydata, bytesNeeded, TRUE))
return ERR_CIPHER_INIT_WEAK_KEY;
}
else
{
// We already have existing master key data (the header is being re-encrypted)
memcpy (keyInfo.master_keydata, masterKeydata, MASTER_KEYDATA_SIZE);
}
// User key
memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
keyInfo.keyLength = nUserKeyLen;
keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, bBoot);
// User selected encryption algorithm
cryptoInfo->ea = ea;
// Mode of operation
cryptoInfo->mode = mode;
// Salt for header key derivation
if (!RandgetBytes (keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
return ERR_CIPHER_INIT_WEAK_KEY;
// PBKDF2 (PKCS5) is used to derive primary header key(s) and secondary header key(s) (XTS) from the password/keyfiles
switch (pkcs5_prf)
{
case SHA512:
derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;
- case SHA1:
- // Deprecated/legacy
- derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
- PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
- break;
-
case RIPEMD160:
derive_key_ripemd160 (TRUE, keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;
case WHIRLPOOL:
derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;
default:
// Unknown/wrong ID
TC_THROW_FATAL_EXCEPTION;
}
/* Header setup */
// Salt
mputBytes (p, keyInfo.salt, PKCS5_SALT_SIZE);
@@ -842,92 +784,73 @@ int CreateVolumeHeaderInMemory (BOOL bBoot, char *header, int ea, int mode, Pass
{
TC_THROW_FATAL_EXCEPTION;
}
cryptoInfo->SectorSize = sectorSize;
mputLong (p, sectorSize);
// CRC of the header fields
x = GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
p = header + TC_HEADER_OFFSET_HEADER_CRC;
mputLong (p, x);
// The master key data
memcpy (header + HEADER_MASTER_KEYDATA_OFFSET, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
/* Header encryption */
switch (mode)
{
- case LRW:
- case CBC:
- case INNER_CBC:
- case OUTER_CBC:
-
- // For LRW (deprecated/legacy), the tweak key
- // For CBC (deprecated/legacy), the IV/whitening seed
- memcpy (cryptoInfo->k2, dk, LEGACY_VOL_IV_SIZE);
- primaryKeyOffset = LEGACY_VOL_IV_SIZE;
- break;
default:
// The secondary key (if cascade, multiple concatenated)
memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
primaryKeyOffset = 0;
}
retVal = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
if (retVal != ERR_SUCCESS)
return retVal;
// Mode of operation
if (!EAInitMode (cryptoInfo))
return ERR_OUTOFMEMORY;
// Encrypt the entire header (except the salt)
EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET,
HEADER_ENCRYPTED_DATA_SIZE,
cryptoInfo);
/* cryptoInfo setup for further use (disk format) */
// Init with the master key(s)
retVal = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
if (retVal != ERR_SUCCESS)
return retVal;
memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
switch (cryptoInfo->mode)
{
- case LRW:
- case CBC:
- case INNER_CBC:
- case OUTER_CBC:
-
- // For LRW (deprecated/legacy), the tweak key
- // For CBC (deprecated/legacy), the IV/whitening seed
- memcpy (cryptoInfo->k2, keyInfo.master_keydata, LEGACY_VOL_IV_SIZE);
- break;
default:
// The secondary master key (if cascade, multiple concatenated)
memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
}
// Mode of operation
if (!EAInitMode (cryptoInfo))
return ERR_OUTOFMEMORY;
#ifdef VOLFORMAT
if (showKeys && !bInPlaceEncNonSys)
{
BOOL dots3 = FALSE;
int i, j;
j = EAGetKeySize (ea);
if (j > NBR_KEY_BYTES_TO_DISPLAY)