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.c192
1 files changed, 141 insertions, 51 deletions
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c
index 007a1c08..3228aadc 100644
--- a/src/Common/Volumes.c
+++ b/src/Common/Volumes.c
@@ -12,8 +12,8 @@
code distribution packages. */
#include "Tcdefs.h"
-
-#ifndef TC_WINDOWS_BOOT
+#if !defined(_UEFI)
+#if !defined(TC_WINDOWS_BOOT)
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -28,6 +28,7 @@
#ifndef DEVICE_DRIVER
#include "Random.h"
#endif
+#endif // !defined(_UEFI)
#include "Crc.h"
#include "Crypto.h"
@@ -35,7 +36,7 @@
#include "Volumes.h"
#include "Pkcs5.h"
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(_UEFI)
#include <Strsafe.h>
#include "../Boot/Windows/BootCommon.h"
#endif
@@ -171,21 +172,22 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
CRYPTOPP_ALIGN_DATA(16) KEY_INFO keyInfo;
PCRYPTO_INFO cryptoInfo;
- char dk[MASTER_KEYDATA_SIZE];
+ CRYPTOPP_ALIGN_DATA(16) char dk[MASTER_KEYDATA_SIZE];
int enqPkcs5Prf, pkcs5_prf;
uint16 headerVersion;
int status = ERR_PARAMETER_INCORRECT;
int primaryKeyOffset;
-
+ int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1;
+#if !defined(_UEFI)
TC_EVENT keyDerivationCompletedEvent;
TC_EVENT noOutstandingWorkItemEvent;
KeyDerivationWorkItem *keyDerivationWorkItems;
KeyDerivationWorkItem *item;
- int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1;
size_t encryptionThreadCount = GetEncryptionThreadCount();
- size_t queuedWorkItems = 0;
LONG outstandingWorkItemCount = 0;
int i;
+#endif
+ size_t queuedWorkItems = 0;
// if no PIM specified, use default value
if (pim < 0)
@@ -212,7 +214,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
if (cryptoInfo == NULL)
return ERR_OUTOFMEMORY;
}
-
+#if !defined(_UEFI)
/* use thread pool only if no PRF was specified */
if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
{
@@ -244,10 +246,11 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
#endif
}
-#ifndef DEVICE_DRIVER
+#if !defined(DEVICE_DRIVER)
VirtualLock (&keyInfo, sizeof (keyInfo));
VirtualLock (&dk, sizeof (dk));
#endif
+#endif // !defined(_UEFI)
crypto_loadkey (&keyInfo, password->Text, (int) password->Length);
@@ -264,7 +267,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
// skip SHA-256 in case of TrueCrypt mode
if (truecryptMode && (enqPkcs5Prf == SHA256))
continue;
-
+#if !defined(_UEFI)
if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
{
// Enqueue key derivation on thread pool
@@ -319,6 +322,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int
KeyReady: ;
}
else
+#endif // !defined(_UEFI)
{
pkcs5_prf = enqPkcs5Prf;
keyInfo.noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot);
@@ -345,6 +349,10 @@ KeyReady: ;
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;
default:
// Unknown/wrong ID
TC_THROW_FATAL_EXCEPTION;
@@ -564,11 +572,12 @@ ret:
burn (&keyInfo, sizeof (keyInfo));
burn (dk, sizeof(dk));
-#ifndef DEVICE_DRIVER
+#if !defined(DEVICE_DRIVER) && !defined(_UEFI)
VirtualUnlock (&keyInfo, sizeof (keyInfo));
VirtualUnlock (&dk, sizeof (dk));
#endif
+#if !defined(_UEFI)
if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
{
TC_WAIT_EVENT (noOutstandingWorkItemEvent);
@@ -576,16 +585,16 @@ ret:
burn (keyDerivationWorkItems, sizeof (KeyDerivationWorkItem) * pkcs5PrfCount);
TCfree (keyDerivationWorkItems);
-#ifndef DEVICE_DRIVER
+#if !defined(DEVICE_DRIVER)
CloseHandle (keyDerivationCompletedEvent);
CloseHandle (noOutstandingWorkItemEvent);
#endif
}
-
+#endif
return status;
}
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(_UEFI)
void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderSize, byte* fingerprint)
{
// compute Whirlpool+SHA512 fingerprint of bootloader including MBR
@@ -605,16 +614,16 @@ void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderS
WHIRLPOOL_init (&whirlpool);
sha512_begin (&sha2);
- WHIRLPOOL_add (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET * 8, &whirlpool);
+ 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)) * 8, &whirlpool);
+ 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_BOOT_SECTOR_USER_CONFIG_OFFSET + 1, (TC_MAX_MBR_BOOT_CODE_SIZE - (TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1)) * 8, &whirlpool);
+ WHIRLPOOL_add (bootLoaderBuf + TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1, (TC_MAX_MBR_BOOT_CODE_SIZE - (TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1)), &whirlpool);
sha512_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1, (TC_MAX_MBR_BOOT_CODE_SIZE - (TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1)), &sha2);
- WHIRLPOOL_add (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS) * 8, &whirlpool);
+ 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);
@@ -667,6 +676,8 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR
serpent_set_key (dk, cryptoInfo->ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk);
+ #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
+ camellia_set_key (dk, cryptoInfo->ks);
#else
status = EAInit (dk, cryptoInfo->ks);
if (status == ERR_CIPHER_INIT_FAILURE)
@@ -683,6 +694,8 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR
serpent_set_key (dk + 32, cryptoInfo->ks2);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32));
+ #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
+ camellia_set_key (dk + 32, cryptoInfo->ks2);
#else
EAInit (dk + 32, cryptoInfo->ks2);
#endif
@@ -742,6 +755,8 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR
serpent_set_key (dk, cryptoInfo->ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk);
+ #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
+ camellia_set_key (dk, cryptoInfo->ks);
#else
status = EAInit (dk, cryptoInfo->ks);
if (status == ERR_CIPHER_INIT_FAILURE)
@@ -759,6 +774,8 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR
serpent_set_key (dk + 32, cryptoInfo->ks2);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32));
+ #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
+ camellia_set_key (dk + 32, cryptoInfo->ks2);
#else
EAInit (dk + 32, cryptoInfo->ks2);
#endif
@@ -793,15 +810,22 @@ ret:
#endif
// Creates a volume header in memory
+#if defined(_UEFI)
+int CreateVolumeHeaderInMemory(BOOL bBoot, char *header, int ea, int mode, Password *password,
+ int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo,
+ unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize,
+ unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode)
+#else
int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, int mode, Password *password,
int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo,
unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize,
unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode)
+#endif // !defined(_UEFI)
{
unsigned char *p = (unsigned char *) header;
static CRYPTOPP_ALIGN_DATA(16) KEY_INFO keyInfo;
- int nUserKeyLen = password->Length;
+ int nUserKeyLen = password? password->Length : 0;
PCRYPTO_INFO cryptoInfo = crypto_open ();
static char dk[MASTER_KEYDATA_SIZE];
int x;
@@ -816,9 +840,10 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
pim = 0;
memset (header, 0, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
-
+#if !defined(_UEFI)
VirtualLock (&keyInfo, sizeof (keyInfo));
VirtualLock (&dk, sizeof (dk));
+#endif // !defined(_UEFI)
/* Encryption setup */
@@ -835,8 +860,15 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
bytesNeeded = EAGetKeySize (ea) * 2; // Size of primary + secondary key(s)
}
+#if !defined(_UEFI)
if (!RandgetBytes (hwndDlg, keyInfo.master_keydata, bytesNeeded, TRUE))
+#else
+ if (!RandgetBytes(keyInfo.master_keydata, bytesNeeded, TRUE))
+#endif
+ {
+ crypto_close (cryptoInfo);
return ERR_CIPHER_INIT_WEAK_KEY;
+ }
}
else
{
@@ -845,9 +877,17 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
}
// User key
- memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
- keyInfo.keyLength = nUserKeyLen;
- keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, FALSE, bBoot);
+ if (password)
+ {
+ memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
+ keyInfo.keyLength = nUserKeyLen;
+ keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, FALSE, bBoot);
+ }
+ else
+ {
+ keyInfo.keyLength = 0;
+ keyInfo.noIterations = 0;
+ }
// User selected encryption algorithm
cryptoInfo->ea = ea;
@@ -862,35 +902,64 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
cryptoInfo->mode = mode;
// Salt for header key derivation
- if (!RandgetBytes (hwndDlg, keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
- return ERR_CIPHER_INIT_WEAK_KEY;
+#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);
+ 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)
+ if (password)
{
- 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;
-
- case RIPEMD160:
- derive_key_ripemd160 (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;
+ // 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;
- default:
- // Unknown/wrong ID
- TC_THROW_FATAL_EXCEPTION;
+ case SHA256:
+ derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
+ PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
+ break;
+
+ case RIPEMD160:
+ derive_key_ripemd160 (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;
+
+ 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);
+ return ERR_CIPHER_INIT_WEAK_KEY;
+ }
}
/* Header setup */
@@ -942,6 +1011,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
|| sectorSize > TC_MAX_VOLUME_SECTOR_SIZE
|| sectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
{
+ crypto_close (cryptoInfo);
TC_THROW_FATAL_EXCEPTION;
}
@@ -970,11 +1040,17 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
retVal = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
if (retVal != ERR_SUCCESS)
+ {
+ crypto_close (cryptoInfo);
return retVal;
+ }
// Mode of operation
if (!EAInitMode (cryptoInfo))
+ {
+ crypto_close (cryptoInfo);
return ERR_OUTOFMEMORY;
+ }
// Encrypt the entire header (except the salt)
@@ -988,7 +1064,10 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
// Init with the master key(s)
retVal = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
if (retVal != ERR_SUCCESS)
+ {
+ crypto_close (cryptoInfo);
return retVal;
+ }
memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
@@ -1002,7 +1081,10 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
// Mode of operation
if (!EAInitMode (cryptoInfo))
+ {
+ crypto_close (cryptoInfo);
return ERR_OUTOFMEMORY;
+ }
#ifdef VOLFORMAT
@@ -1054,7 +1136,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
return 0;
}
-
+#if !defined(_UEFI)
BOOL ReadEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header, DWORD *bytesRead)
{
#if TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
@@ -1157,7 +1239,7 @@ BOOL WriteEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header)
// 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)
+int WriteRandomDataToReservedHeaderAreas (HWND hwndDlg, HANDLE dev, CRYPTO_INFO *cryptoInfo, uint64 dataAreaSize, BOOL bPrimaryOnly, BOOL bBackupOnly, BOOL bInPlaceEnc)
{
char temporaryKey[MASTER_KEYDATA_SIZE];
char originalK2[MASTER_KEYDATA_SIZE];
@@ -1216,6 +1298,13 @@ int WriteRandomDataToReservedHeaderAreas (HWND hwndDlg, HANDLE dev, CRYPTO_INFO
goto final_seq;
}
+ if (backupHeaders || !bInPlaceEnc)
+ {
+ // encrypt random data instead of existing data for better entropy, except in case of primary
+ // header of an in-place encrypted disk
+ RandgetBytes (hwndDlg, buf + TC_VOLUME_HEADER_EFFECTIVE_SIZE, sizeof (buf) - TC_VOLUME_HEADER_EFFECTIVE_SIZE, FALSE);
+ }
+
EncryptBuffer (buf + TC_VOLUME_HEADER_EFFECTIVE_SIZE, sizeof (buf) - TC_VOLUME_HEADER_EFFECTIVE_SIZE, cryptoInfo);
if (!SetFilePointerEx (dev, offset, NULL, FILE_BEGIN))
@@ -1267,4 +1356,5 @@ final_seq:
return nStatus;
}
+#endif // !defined(_UEFI)
#endif // !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT)