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.c99
1 files changed, 66 insertions, 33 deletions
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c
index 5b1d4065..7ee519f6 100644
--- a/src/Common/Volumes.c
+++ b/src/Common/Volumes.c
@@ -103,73 +103,73 @@
// 84 8 Header creation time
// 92 8 Size of hidden volume in bytes (0 = normal volume)
// 100 8 Size of the volume in bytes (identical with field 92 for hidden volumes)
// 108 8 Start byte offset of the encrypted area of the volume
// 116 8 Size of the encrypted area of the volume in bytes
// 124 132 Reserved (must contain zeroes)
// 256 256 Concatenated primary master key(s) and secondary master key(s) (XTS mode)
/* Deprecated/legacy volume header v2 structure (used before TrueCrypt 5.0): */
//
// Offset Length Description
// ------------------------------------------
// Unencrypted:
// 0 64 Salt
// Encrypted:
// 64 4 ASCII string 'VERA'
// 68 2 Header version
// 70 2 Required program version
// 72 4 CRC-32 checksum of the (decrypted) bytes 256-511
// 76 8 Volume creation time
// 84 8 Header creation time
// 92 8 Size of hidden volume in bytes (0 = normal volume)
// 100 156 Reserved (must contain zeroes)
// 256 32 For LRW (deprecated/legacy), secondary key
// For CBC (deprecated/legacy), data used to generate IV and whitening values
// 288 224 Master key(s)
-uint16 GetHeaderField16 (byte *header, int offset)
+uint16 GetHeaderField16 (uint8 *header, int offset)
{
return BE16 (*(uint16 *) (header + offset));
}
-uint32 GetHeaderField32 (byte *header, int offset)
+uint32 GetHeaderField32 (uint8 *header, int offset)
{
return BE32 (*(uint32 *) (header + offset));
}
-UINT64_STRUCT GetHeaderField64 (byte *header, int offset)
+UINT64_STRUCT GetHeaderField64 (uint8 *header, int offset)
{
UINT64_STRUCT uint64Struct;
#ifndef TC_NO_COMPILER_INT64
uint64Struct.Value = BE64 (*(uint64 *) (header + offset));
#else
uint64Struct.HighPart = BE32 (*(uint32 *) (header + offset));
uint64Struct.LowPart = BE32 (*(uint32 *) (header + offset + 4));
#endif
return uint64Struct;
}
#ifndef TC_WINDOWS_BOOT
typedef struct
{
char DerivedKey[MASTER_KEYDATA_SIZE];
BOOL Free;
LONG KeyReady;
int Pkcs5Prf;
} KeyDerivationWorkItem;
BOOL ReadVolumeHeaderRecoveryMode = FALSE;
int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int selected_pkcs5_prf, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
{
char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
unsigned char* keyInfoBuffer = NULL;
@@ -342,85 +342,88 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
{
for (i = 0; i < pkcs5PrfCount; ++i)
{
item = &keyDerivationWorkItems[i];
if (!item->Free && InterlockedExchangeAdd (&item->KeyReady, 0) == TRUE)
{
pkcs5_prf = item->Pkcs5Prf;
keyInfo->noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, bBoot);
memcpy (dk, item->DerivedKey, sizeof (dk));
item->Free = TRUE;
--queuedWorkItems;
goto KeyReady;
}
}
if (queuedWorkItems > 0)
TC_WAIT_EVENT (*keyDerivationCompletedEvent);
}
continue;
KeyReady: ;
}
else
#endif // !defined(_UEFI)
{
pkcs5_prf = enqPkcs5Prf;
keyInfo->noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot);
switch (pkcs5_prf)
{
- case BLAKE2S:
- derive_key_blake2s (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
+ case SHA512:
+ derive_key_sha512 (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,
+ case SHA256:
+ derive_key_sha256 (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,
+ #ifndef WOLFCRYPT_BACKEND
+ case BLAKE2S:
+ derive_key_blake2s (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
- case SHA256:
- derive_key_sha256 (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
+ case WHIRLPOOL:
+ derive_key_whirlpool (keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
- case STREEBOG:
+
+ case STREEBOG:
derive_key_streebog(keyInfo->userKey, keyInfo->keyLength, keyInfo->salt,
PKCS5_SALT_SIZE, keyInfo->noIterations, dk, GetMaxPkcs5OutSize());
break;
- default:
+ #endif
+ 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)
{
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);
@@ -567,280 +570,309 @@ KeyReady: ;
blake2s_update (&ctx, header, sizeof(header));
blake2s_final (&ctx, cryptoInfo->master_keydata_hash);
burn(&ctx, sizeof (ctx));
#ifndef _WIN64
if (NT_SUCCESS (saveStatus))
KeRestoreFloatingPointState (&floatingPointState);
#endif
}
#else
memcpy (cryptoInfo->master_keydata, keyInfo->master_keydata, MASTER_KEYDATA_SIZE);
#endif
// PKCS #5
cryptoInfo->pkcs5 = pkcs5_prf;
cryptoInfo->noIterations = keyInfo->noIterations;
cryptoInfo->volumePim = pim;
// 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;
#ifndef TC_WINDOWS_DRIVER
// The secondary master key (if cascade, multiple concatenated)
memcpy (cryptoInfo->k2, keyInfo->master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
#endif
if (!EAInitMode (cryptoInfo, keyInfo->master_keydata + EAGetKeySize (cryptoInfo->ea)))
{
status = ERR_MODE_INIT_FAILED;
goto err;
}
+ // check that first half of keyInfo.master_keydata is different from the second half. If they are the same return error
+ if (memcmp (keyInfo->master_keydata, keyInfo->master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea)) == 0)
+ {
+ cryptoInfo->bVulnerableMasterKey = TRUE;
+ if (retHeaderCryptoInfo)
+ retHeaderCryptoInfo->bVulnerableMasterKey = TRUE;
+ }
+
status = ERR_SUCCESS;
goto ret;
}
}
}
status = ERR_PASSWORD_WRONG;
err:
if (cryptoInfo != retHeaderCryptoInfo)
{
crypto_close(cryptoInfo);
*retInfo = NULL;
}
ret:
burn (dk, sizeof(dk));
burn (header, sizeof(header));
#if !defined(DEVICE_DRIVER) && !defined(_UEFI)
VirtualUnlock (&dk, sizeof (dk));
VirtualUnlock (&header, sizeof (header));
#endif
#if !defined(_UEFI)
if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
{
EncryptionThreadPoolBeginReadVolumeHeaderFinalization (keyDerivationCompletedEvent, noOutstandingWorkItemEvent, outstandingWorkItemCount,
keyInfoBuffer, keyInfoBufferSize,
keyDerivationWorkItems, keyDerivationWorkItemsSize);
}
else
#endif
{
burn (keyInfo, sizeof (KEY_INFO));
#if !defined(DEVICE_DRIVER) && !defined(_UEFI)
VirtualUnlock (keyInfoBuffer, keyInfoBufferSize);
#endif
TCfree(keyInfoBuffer);
}
return status;
}
#if defined(_WIN32) && !defined(_UEFI)
-void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderSize, byte* fingerprint)
+void ComputeBootloaderFingerprint (uint8 *bootLoaderBuf, unsigned int bootLoaderSize, uint8* fingerprint)
{
// compute Whirlpool+SHA512 fingerprint of bootloader including MBR
// we skip user configuration fields:
// TC_BOOT_SECTOR_PIM_VALUE_OFFSET = 400
// TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET = 402
// => TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE = 4
// TC_BOOT_SECTOR_USER_MESSAGE_OFFSET = 406
// => TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH = 24
// TC_BOOT_SECTOR_USER_CONFIG_OFFSET = 438
//
// we have: TC_BOOT_SECTOR_USER_MESSAGE_OFFSET = TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE
- WHIRLPOOL_CTX whirlpool;
+#ifndef WOLFCRYPT_BACKEND
+ WHIRLPOOL_CTX whirlpool;
sha512_ctx sha2;
WHIRLPOOL_init (&whirlpool);
sha512_begin (&sha2);
WHIRLPOOL_add (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &whirlpool);
sha512_hash (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &sha2);
WHIRLPOOL_add (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &whirlpool);
sha512_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2);
WHIRLPOOL_add (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &whirlpool);
sha512_hash (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &sha2);
WHIRLPOOL_finalize (&whirlpool, fingerprint);
sha512_end (&fingerprint [WHIRLPOOL_DIGESTSIZE], &sha2);
+#else
+ sha512_ctx sha2_512;
+ sha256_ctx sha2_256;
+
+ sha512_begin (&sha2_512);
+ sha256_begin (&sha2_256);
+
+ sha512_hash (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &sha2_512);
+ sha256_hash (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &sha2_256);
+
+ sha512_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2_512);
+ sha256_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2_256);
+
+ sha512_hash (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &sha2_512);
+ sha256_hash (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &sha2_256);
+
+ sha512_end (&fingerprint, &sha2_512);
+ sha256_end (&fingerprint [SHA512_DIGESTSIZE], &sha2_256);
+ sha256_end (&fingerprint [SHA512_DIGESTSIZE + SHA256_DIGESTSIZE], &sha2_256);
+#endif
}
#endif
#else // TC_WINDOWS_BOOT
int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
{
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
char dk[32 * 2]; // 2 * 256-bit key
#else
char dk[32 * 2 * 3]; // 6 * 256-bit key
#endif
PCRYPTO_INFO cryptoInfo;
int status = ERR_SUCCESS;
uint32 iterations = pim;
iterations <<= 16;
iterations |= bBoot;
if (retHeaderCryptoInfo != NULL)
cryptoInfo = retHeaderCryptoInfo;
else
cryptoInfo = *retInfo = crypto_open ();
// PKCS5 PRF
#ifdef TC_WINDOWS_BOOT_SHA2
derive_key_sha256 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
PKCS5_SALT_SIZE, iterations, dk, sizeof (dk));
#else
derive_key_blake2s (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
PKCS5_SALT_SIZE, iterations, dk, sizeof (dk));
#endif
// Mode of operation
cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
cryptoInfo->ea = 1;
#else
// Test all available encryption algorithms
for (cryptoInfo->ea = EAGetFirst (); cryptoInfo->ea != 0; cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
#endif
{
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
- #if defined (TC_WINDOWS_BOOT_SERPENT)
+ #if defined (TC_WINDOWS_BOOT_SERPENT) && !defined (WOLFCRYPT_BACKEND)
serpent_set_key (dk, cryptoInfo->ks);
- #elif defined (TC_WINDOWS_BOOT_TWOFISH)
+ #elif defined (TC_WINDOWS_BOOT_TWOFISH) && !defined (WOLFCRYPT_BACKEND)
twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk);
- #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
+ #elif defined (TC_WINDOWS_BOOT_CAMELLIA) && !defined (WOLFCRYPT_BACKEND)
camellia_set_key (dk, cryptoInfo->ks);
#else
status = EAInit (dk, cryptoInfo->ks);
if (status == ERR_CIPHER_INIT_FAILURE)
goto err;
#endif
#else
status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks);
if (status == ERR_CIPHER_INIT_FAILURE)
goto err;
#endif
// Secondary key schedule
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
- #if defined (TC_WINDOWS_BOOT_SERPENT)
+ #if defined (TC_WINDOWS_BOOT_SERPENT) && !defined (WOLFCRYPT_BACKEND)
serpent_set_key (dk + 32, cryptoInfo->ks2);
- #elif defined (TC_WINDOWS_BOOT_TWOFISH)
+ #elif defined (TC_WINDOWS_BOOT_TWOFISH) && !defined (WOLFCRYPT_BACKEND)
twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32));
- #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
+ #elif defined (TC_WINDOWS_BOOT_CAMELLIA) && !defined (WOLFCRYPT_BACKEND)
camellia_set_key (dk + 32, cryptoInfo->ks2);
#else
EAInit (dk + 32, cryptoInfo->ks2);
#endif
#else
EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
#endif
// Try to decrypt header
DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
// Check magic 'VERA' and CRC-32 of header fields and master keydata
if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241
|| (GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION) >= 4 && GetHeaderField32 (header, TC_HEADER_OFFSET_HEADER_CRC) != GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
|| GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
{
EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
status = ERR_PASSWORD_WRONG;
goto err;
#else
continue;
#endif
}
// Header decrypted
status = 0;
// Hidden volume status
cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE);
cryptoInfo->hiddenVolume = (cryptoInfo->VolumeSize.LowPart != 0 || cryptoInfo->VolumeSize.HighPart != 0);
// Volume size
cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);
// Encrypted area size and length
cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);
// Flags
cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);
#ifdef TC_WINDOWS_BOOT_SHA2
cryptoInfo->pkcs5 = SHA256;
#else
cryptoInfo->pkcs5 = BLAKE2S;
#endif
memcpy (dk, header + HEADER_MASTER_KEYDATA_OFFSET, sizeof (dk));
EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
if (retHeaderCryptoInfo)
goto ret;
// Init the encryption algorithm with the decrypted master key
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
- #if defined (TC_WINDOWS_BOOT_SERPENT)
+ #if defined (TC_WINDOWS_BOOT_SERPENT) && !defined (WOLFCRYPT_BACKEND)
serpent_set_key (dk, cryptoInfo->ks);
- #elif defined (TC_WINDOWS_BOOT_TWOFISH)
+ #elif defined (TC_WINDOWS_BOOT_TWOFISH) && !defined (WOLFCRYPT_BACKEND)
twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk);
- #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
+ #elif defined (TC_WINDOWS_BOOT_CAMELLIA) && !defined (WOLFCRYPT_BACKEND)
camellia_set_key (dk, cryptoInfo->ks);
#else
status = EAInit (dk, cryptoInfo->ks);
if (status == ERR_CIPHER_INIT_FAILURE)
goto err;
#endif
#else
status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks);
if (status == ERR_CIPHER_INIT_FAILURE)
goto err;
#endif
// The secondary master key (if cascade, multiple concatenated)
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
- #if defined (TC_WINDOWS_BOOT_SERPENT)
+ #if defined (TC_WINDOWS_BOOT_SERPENT) && !defined (WOLFCRYPT_BACKEND)
serpent_set_key (dk + 32, cryptoInfo->ks2);
- #elif defined (TC_WINDOWS_BOOT_TWOFISH)
+ #elif defined (TC_WINDOWS_BOOT_TWOFISH) && !defined (WOLFCRYPT_BACKEND)
twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32));
- #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
+ #elif defined (TC_WINDOWS_BOOT_CAMELLIA) && !defined (WOLFCRYPT_BACKEND)
camellia_set_key (dk + 32, cryptoInfo->ks2);
#else
EAInit (dk + 32, cryptoInfo->ks2);
#endif
#else
EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
#endif
goto ret;
}
status = ERR_PASSWORD_WRONG;
err:
if (cryptoInfo != retHeaderCryptoInfo)
{
crypto_close(cryptoInfo);
*retInfo = NULL;
}
ret:
burn (dk, sizeof(dk));
return status;
}
#endif // TC_WINDOWS_BOOT
#if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT)
#ifdef VOLFORMAT
@@ -949,75 +981,76 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
// Mode of operation
cryptoInfo->mode = mode;
// Salt for header key derivation
#if !defined(_UEFI)
if (!RandgetBytes(hwndDlg, keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
#else
if (!RandgetBytes(keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
#endif
{
crypto_close (cryptoInfo);
retVal = ERR_CIPHER_INIT_WEAK_KEY;
goto err;
}
if (password)
{
// 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 SHA256:
derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;
+ #ifndef WOLFCRYPT_BACKEND
case BLAKE2S:
derive_key_blake2s (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;
case STREEBOG:
derive_key_streebog(keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
break;
-
+ #endif
default:
// Unknown/wrong ID
crypto_close (cryptoInfo);
TC_THROW_FATAL_EXCEPTION;
}
}
else
{
// generate a random key
#if !defined(_UEFI)
if (!RandgetBytes(hwndDlg, dk, GetMaxPkcs5OutSize(), !bWipeMode))
#else
if (!RandgetBytes(dk, GetMaxPkcs5OutSize(), !bWipeMode))
#endif
{
crypto_close (cryptoInfo);
retVal = ERR_CIPHER_INIT_WEAK_KEY;
goto err;
}
}
/* Header setup */
// Salt
mputBytes (p, keyInfo.salt, PKCS5_SALT_SIZE);
// Magic
mputLong (p, 0x56455241);
// Header version
@@ -1162,100 +1195,100 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
StringCchPrintfW (tmp2, ARRAYSIZE(tmp2), L"%02X", (int) (unsigned char) dk[primaryKeyOffset + i]);
StringCchCatW (HeaderKeyGUIView, ARRAYSIZE(HeaderKeyGUIView), tmp2);
}
if (dots3)
{
DisplayPortionsOfKeys (hHeaderKey, hMasterKey, HeaderKeyGUIView, MasterKeyGUIView, !showKeys);
}
else
{
SendMessage (hMasterKey, WM_SETTEXT, 0, (LPARAM) MasterKeyGUIView);
SendMessage (hHeaderKey, WM_SETTEXT, 0, (LPARAM) HeaderKeyGUIView);
}
}
#endif // #ifdef VOLFORMAT
*retInfo = cryptoInfo;
err:
burn (dk, sizeof(dk));
burn (&keyInfo, sizeof (keyInfo));
#if !defined(_UEFI)
VirtualUnlock (&keyInfo, sizeof (keyInfo));
VirtualUnlock (&dk, sizeof (dk));
#endif // !defined(_UEFI)
return 0;
}
#if !defined(_UEFI)
-BOOL ReadEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header, DWORD *bytesRead)
+BOOL ReadEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, uint8 *header, DWORD *bytesRead)
{
#if TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
#error TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
#endif
- byte sectorBuffer[TC_MAX_VOLUME_SECTOR_SIZE];
+ uint8 sectorBuffer[TC_MAX_VOLUME_SECTOR_SIZE];
DISK_GEOMETRY geometry;
if (!device)
return ReadFile (fileHandle, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE, bytesRead, NULL);
if (!DeviceIoControl (fileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof (geometry), bytesRead, NULL))
return FALSE;
if (geometry.BytesPerSector > sizeof (sectorBuffer) || geometry.BytesPerSector < TC_MIN_VOLUME_SECTOR_SIZE)
{
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!ReadFile (fileHandle, sectorBuffer, max (TC_VOLUME_HEADER_EFFECTIVE_SIZE, geometry.BytesPerSector), bytesRead, NULL))
return FALSE;
memcpy (header, sectorBuffer, min (*bytesRead, TC_VOLUME_HEADER_EFFECTIVE_SIZE));
if (*bytesRead > TC_VOLUME_HEADER_EFFECTIVE_SIZE)
*bytesRead = TC_VOLUME_HEADER_EFFECTIVE_SIZE;
return TRUE;
}
-BOOL WriteEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header)
+BOOL WriteEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, uint8 *header)
{
#if TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
#error TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
#endif
- byte sectorBuffer[TC_MAX_VOLUME_SECTOR_SIZE];
+ uint8 sectorBuffer[TC_MAX_VOLUME_SECTOR_SIZE];
DWORD bytesDone;
DISK_GEOMETRY geometry;
if (!device)
{
if (!WriteFile (fileHandle, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE, &bytesDone, NULL))
return FALSE;
if (bytesDone != TC_VOLUME_HEADER_EFFECTIVE_SIZE)
{
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
return TRUE;
}
if (!DeviceIoControl (fileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof (geometry), &bytesDone, NULL))
return FALSE;
if (geometry.BytesPerSector > sizeof (sectorBuffer) || geometry.BytesPerSector < TC_MIN_VOLUME_SECTOR_SIZE)
{
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
if (geometry.BytesPerSector != TC_VOLUME_HEADER_EFFECTIVE_SIZE)
{
LARGE_INTEGER seekOffset;
@@ -1270,61 +1303,61 @@ BOOL WriteEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header)
}
seekOffset.QuadPart = -(int) bytesDone;
if (!SetFilePointerEx (fileHandle, seekOffset, NULL, FILE_CURRENT))
return FALSE;
}
memcpy (sectorBuffer, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
if (!WriteFile (fileHandle, sectorBuffer, geometry.BytesPerSector, &bytesDone, NULL))
return FALSE;
if (bytesDone != geometry.BytesPerSector)
{
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
return TRUE;
}
// Writes randomly generated data to unused/reserved header areas.
// When bPrimaryOnly is TRUE, then only the primary header area (not the backup header area) is filled with random data.
// When bBackupOnly is TRUE, only the backup header area (not the primary header area) is filled with random data.
int WriteRandomDataToReservedHeaderAreas (HWND hwndDlg, HANDLE dev, CRYPTO_INFO *cryptoInfo, uint64 dataAreaSize, BOOL bPrimaryOnly, BOOL bBackupOnly)
{
char temporaryKey[MASTER_KEYDATA_SIZE];
char originalK2[MASTER_KEYDATA_SIZE];
- byte buf[TC_VOLUME_HEADER_GROUP_SIZE];
+ uint8 buf[TC_VOLUME_HEADER_GROUP_SIZE];
LARGE_INTEGER offset;
int nStatus = ERR_SUCCESS;
DWORD dwError;
DWORD bytesDone;
BOOL backupHeaders = bBackupOnly;
if (bPrimaryOnly && bBackupOnly)
TC_THROW_FATAL_EXCEPTION;
memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2));
while (TRUE)
{
// Temporary keys
if (!RandgetBytes (hwndDlg, temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE)
|| !RandgetBytes (hwndDlg, cryptoInfo->k2, sizeof (cryptoInfo->k2), FALSE))
{
nStatus = ERR_PARAMETER_INCORRECT;
goto final_seq;
}
nStatus = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks);
if (nStatus != ERR_SUCCESS)
goto final_seq;
if (!EAInitMode (cryptoInfo, cryptoInfo->k2))
{
nStatus = ERR_MODE_INIT_FAILED;
goto final_seq;