VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/Crypto.c')
-rw-r--r--src/Common/Crypto.c464
1 files changed, 411 insertions, 53 deletions
diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c
index 3f7e9871..49948107 100644
--- a/src/Common/Crypto.c
+++ b/src/Common/Crypto.c
@@ -19,6 +19,13 @@
#if !defined(_UEFI)
#include <string.h>
#ifndef TC_WINDOWS_BOOT
+#ifdef TC_WINDOWS_DRIVER
+#include <ntstrsafe.h>
+#define StringCchCatW RtlStringCchCatW
+#define StringCchCopyW RtlStringCchCopyW
+#else
+#include <strsafe.h>
+#endif
#include "EncryptionThreadPool.h"
#endif
#endif
@@ -50,18 +57,19 @@ static Cipher Ciphers[] =
// ID Name (Bytes) (Bytes) (Bytes)
#ifdef TC_WINDOWS_BOOT
{ AES, "AES", 16, 32, AES_KS },
- { SERPENT, "Serpent", 16, 32, 140*4 },
+#ifndef WOLFCRYPT_BACKEND
+ { SERPENT, "Serpent", 16, 32, 140*4 },
{ TWOFISH, "Twofish", 16, 32, TWOFISH_KS },
+#endif
#else
{ AES, L"AES", 16, 32, AES_KS },
+#ifndef WOLFCRYPT_BACKEND
{ SERPENT, L"Serpent", 16, 32, 140*4 },
{ TWOFISH, L"Twofish", 16, 32, TWOFISH_KS },
{ CAMELLIA, L"Camellia", 16, 32, CAMELLIA_KS },
-#if defined(CIPHER_GOST89)
- { GOST89, L"GOST89", 16, 32, GOST_KS },
-#endif // defined(CIPHER_GOST89)
{ KUZNYECHIK, L"Kuznyechik",16, 32, KUZNYECHIK_KS },
#endif
+#endif
{ 0, 0, 0, 0, 0 }
};
@@ -75,18 +83,22 @@ static EncryptionAlgorithm EncryptionAlgorithms[] =
{ { 0, 0 }, { 0, 0}, 0, 0 }, // Must be all-zero
{ { AES, 0 }, { XTS, 0 }, 1, 1 },
+#ifndef WOLFCRYPT_BACKEND
{ { SERPENT, 0 }, { XTS, 0 }, 1, 1 },
{ { TWOFISH, 0 }, { XTS, 0 }, 1, 1 },
{ { CAMELLIA, 0 }, { XTS, 0 }, 1, 1 },
-#if defined(CIPHER_GOST89)
- { { GOST89, 0 }, { XTS, 0 }, 0, 0 },
-#endif // defined(CIPHER_GOST89)
{ { KUZNYECHIK, 0 }, { XTS, 0 }, 0, 1 },
{ { TWOFISH, AES, 0 }, { XTS, 0 }, 1, 1 },
{ { SERPENT, TWOFISH, AES, 0 }, { XTS, 0 }, 1, 1 },
{ { AES, SERPENT, 0 }, { XTS, 0 }, 1, 1 },
{ { AES, TWOFISH, SERPENT, 0 }, { XTS, 0 }, 1, 1 },
{ { SERPENT, TWOFISH, 0 }, { XTS, 0 }, 1, 1 },
+ { { KUZNYECHIK, CAMELLIA, 0 }, { XTS, 0 }, 0, 1 },
+ { { TWOFISH, KUZNYECHIK, 0 }, { XTS, 0 }, 0, 1 },
+ { { SERPENT, CAMELLIA, 0 }, { XTS, 0 }, 0, 1 },
+ { { AES, KUZNYECHIK, 0 }, { XTS, 0 }, 0, 1 },
+ { { CAMELLIA, SERPENT, KUZNYECHIK, 0 }, { XTS, 0 }, 0, 1 },
+#endif
{ { 0, 0 }, { 0, 0}, 0, 0 } // Must be all-zero
#else // TC_WINDOWS_BOOT
@@ -94,6 +106,7 @@ static EncryptionAlgorithm EncryptionAlgorithms[] =
// Encryption algorithms available for boot drive encryption
{ { 0, 0 }, { 0, 0 }, 0 }, // Must be all-zero
{ { AES, 0 }, { XTS, 0 }, 1 },
+#ifndef WOLFCRYPT_BACKEND
{ { SERPENT, 0 }, { XTS, 0 }, 1 },
{ { TWOFISH, 0 }, { XTS, 0 }, 1 },
{ { TWOFISH, AES, 0 }, { XTS, 0 }, 1 },
@@ -101,6 +114,7 @@ static EncryptionAlgorithm EncryptionAlgorithms[] =
{ { AES, SERPENT, 0 }, { XTS, 0 }, 1 },
{ { AES, TWOFISH, SERPENT, 0 }, { XTS, 0 }, 1 },
{ { SERPENT, TWOFISH, 0 }, { XTS, 0 }, 1 },
+#endif
{ { 0, 0 }, { 0, 0 }, 0 }, // Must be all-zero
#endif
@@ -113,11 +127,13 @@ static EncryptionAlgorithm EncryptionAlgorithms[] =
static Hash Hashes[] =
{ // ID Name Deprecated System Encryption
{ SHA512, L"SHA-512", FALSE, FALSE },
- { WHIRLPOOL, L"Whirlpool", FALSE, FALSE },
{ SHA256, L"SHA-256", FALSE, TRUE },
- { RIPEMD160, L"RIPEMD-160", TRUE, TRUE },
+ #ifndef WOLFCRYPT_BACKEND
+ { BLAKE2S, L"BLAKE2s-256", FALSE, TRUE },
+ { WHIRLPOOL, L"Whirlpool", FALSE, FALSE },
{ STREEBOG, L"Streebog", FALSE, FALSE },
- { 0, 0, 0 }
+ #endif
+ { 0, 0, 0 }
};
#endif
@@ -141,6 +157,7 @@ int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks)
#endif
break;
+#ifndef WOLFCRYPT_BACKEND
case SERPENT:
serpent_set_key (key, ks);
break;
@@ -156,16 +173,12 @@ int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks)
#endif
#if !defined(TC_WINDOWS_BOOT)
-#if defined(CIPHER_GOST89)
- case GOST89:
- gost_set_key(key, (gost_kds*)ks, 1);
- break;
-#endif // && defined(CIPHER_GOST89)
case KUZNYECHIK:
kuznyechik_set_key(key, (kuznyechik_kds*)ks);
break;
#endif // !defined(TC_WINDOWS_BOOT)
+#endif
default:
// Unknown/wrong cipher ID
return ERR_CIPHER_INIT_FAILURE;
@@ -188,17 +201,16 @@ void EncipherBlock(int cipher, void *data, void *ks)
aes_encrypt (data, data, ks);
break;
+#ifndef WOLFCRYPT_BACKEND
case TWOFISH: twofish_encrypt (ks, data, data); break;
case SERPENT: serpent_encrypt (data, data, ks); break;
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_CAMELLIA)
case CAMELLIA: camellia_encrypt (data, data, ks); break;
#endif
#if !defined(TC_WINDOWS_BOOT)
-#if defined(CIPHER_GOST89)
- case GOST89: gost_encrypt(data, data, ks, 1); break;
-#endif // defined(CIPHER_GOST89)
case KUZNYECHIK: kuznyechik_encrypt_block(data, data, ks); break;
#endif // !defined(TC_WINDOWS_BOOT)
+#endif
default: TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID
}
}
@@ -232,6 +244,7 @@ void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
KeRestoreFloatingPointState (&floatingPointState);
#endif
}
+#ifndef WOLFCRYPT_BACKEND
#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined (_UEFI)
else if (cipher == SERPENT
&& (blockCount >= 4)
@@ -247,7 +260,7 @@ void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
#endif
}
#endif
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
else if (cipher == TWOFISH) {
twofish_encrypt_blocks(ks, data, data, (uint32) blockCount);
}
@@ -269,9 +282,7 @@ void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
#endif
}
#endif
- else if (cipher == GOST89) {
- gost_encrypt(data, data, ks, (int)blockCount);
- }
+#endif
else
{
size_t blockSize = CipherGetBlockSize (cipher);
@@ -289,17 +300,16 @@ void DecipherBlock(int cipher, void *data, void *ks)
{
switch (cipher)
{
+#ifndef WOLFCRYPT_BACKEND
case SERPENT: serpent_decrypt (data, data, ks); break;
case TWOFISH: twofish_decrypt (ks, data, data); break;
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_CAMELLIA)
case CAMELLIA: camellia_decrypt (data, data, ks); break;
#endif
#if !defined(TC_WINDOWS_BOOT)
-#if defined(CIPHER_GOST89)
- case GOST89: gost_decrypt(data, data, ks, 1); break;
-#endif // defined(CIPHER_GOST89)
case KUZNYECHIK: kuznyechik_decrypt_block(data, data, ks); break;
#endif // !defined(TC_WINDOWS_BOOT)
+#endif
#ifndef TC_WINDOWS_BOOT
@@ -349,6 +359,7 @@ void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
KeRestoreFloatingPointState (&floatingPointState);
#endif
}
+#ifndef WOLFCRYPT_BACKEND
#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined (_UEFI)
else if (cipher == SERPENT
&& (blockCount >= 4)
@@ -364,7 +375,7 @@ void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
#endif
}
#endif
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
else if (cipher == TWOFISH) {
twofish_decrypt_blocks(ks, data, data, (uint32) blockCount);
}
@@ -386,9 +397,7 @@ void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
#endif
}
#endif
- else if (cipher == GOST89) {
- gost_decrypt(data, data, ks, (int)blockCount);
- }
+#endif
else
{
size_t blockSize = CipherGetBlockSize (cipher);
@@ -454,12 +463,11 @@ int CipherGetKeyScheduleSize (int cipherId)
BOOL CipherSupportsIntraDataUnitParallelization (int cipher)
{
return (cipher == AES && IsAesHwCpuSupported())
- || (cipher == GOST89)
#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined (_UEFI)
|| (cipher == SERPENT && HasSSE2())
|| (cipher == KUZNYECHIK && HasSSE2())
#endif
-#if CRYPTOPP_BOOL_X64
+#if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM)
|| (cipher == TWOFISH)
|| (cipher == CAMELLIA)
#endif
@@ -527,16 +535,24 @@ int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
#ifndef TC_WINDOWS_BOOT
-BOOL EAInitMode (PCRYPTO_INFO ci)
+BOOL EAInitMode (PCRYPTO_INFO ci, unsigned char* key2)
{
switch (ci->mode)
{
case XTS:
// Secondary key schedule
- if (EAInit (ci->ea, ci->k2, ci->ks2) != ERR_SUCCESS)
+ if (EAInit (ci->ea, key2, ci->ks2) != ERR_SUCCESS)
return FALSE;
+
+ #ifdef WOLFCRYPT_BACKEND
+ if (xts_encrypt_key256 (key2, (aes_encrypt_ctx *) ci->ks) != EXIT_SUCCESS)
+ return ERR_CIPHER_INIT_FAILURE;
+
+ if (xts_decrypt_key256 (key2, (aes_decrypt_ctx *) (ci->ks + sizeof(aes_encrypt_ctx))) != EXIT_SUCCESS)
+ return ERR_CIPHER_INIT_FAILURE;
+ #endif
- /* Note: XTS mode could potentially be initialized with a weak key causing all blocks in one data unit
+ /* Note: XTS mode could potentially be initialized with a weak key causing all blocks in one data unit
on the volume to be tweaked with zero tweaks (i.e. 512 bytes of the volume would be encrypted in ECB
mode). However, to create a TrueCrypt volume with such a weak key, each human being on Earth would have
to create approximately 11,378,125,361,078,862 (about eleven quadrillion) TrueCrypt volumes (provided
@@ -550,33 +566,35 @@ BOOL EAInitMode (PCRYPTO_INFO ci)
return TRUE;
}
-static void EAGetDisplayName(wchar_t *buf, int ea, int i)
+static void EAGetDisplayName(wchar_t *buf, size_t bufLen, int ea, int i)
{
- wcscpy (buf, CipherGetName (i));
+ StringCchCopyW (buf, bufLen, CipherGetName (i));
if (i = EAGetPreviousCipher(ea, i))
{
- wcscat (buf, L"(");
- EAGetDisplayName (&buf[wcslen(buf)], ea, i);
- wcscat (buf, L")");
+ size_t curLen;
+ StringCchCatW (buf, bufLen, L"(");
+ curLen = wcslen(buf);
+ EAGetDisplayName (&buf[curLen], bufLen - curLen, ea, i);
+ StringCchCatW (buf, bufLen, L")");
}
}
// Returns name of EA, cascaded cipher names are separated by hyphens
-wchar_t *EAGetName (wchar_t *buf, int ea, int guiDisplay)
+wchar_t *EAGetName (wchar_t *buf, size_t bufLen, int ea, int guiDisplay)
{
if (guiDisplay)
{
- EAGetDisplayName (buf, ea, EAGetLastCipher(ea));
+ EAGetDisplayName (buf, bufLen, ea, EAGetLastCipher(ea));
}
else
{
int i = EAGetLastCipher(ea);
- wcscpy (buf, (i != 0) ? CipherGetName (i) : L"?");
+ StringCchCopyW (buf, bufLen, (i != 0) ? CipherGetName (i) : L"?");
while (i = EAGetPreviousCipher(ea, i))
{
- wcscat (buf, L"-");
- wcscat (buf, CipherGetName (i));
+ StringCchCatW (buf, bufLen, L"-");
+ StringCchCatW (buf, bufLen, CipherGetName (i));
}
}
return buf;
@@ -590,7 +608,7 @@ int EAGetByName (wchar_t *name)
do
{
- EAGetName(n, ea, 1);
+ EAGetName(n, 128, ea, 1);
#if defined(_UEFI)
if (wcscmp(n, name) == 0)
#else
@@ -780,11 +798,11 @@ const wchar_t *HashGetName (int hashId)
return pHash? pHash -> Name : L"";
}
-void HashGetName2 (wchar_t *buf, int hashId)
+void HashGetName2 (wchar_t *buf, size_t bufLen, int hashId)
{
Hash* pHash = HashGet(hashId);
if (pHash)
- wcscpy(buf, pHash -> Name);
+ StringCchCopyW (buf, bufLen, pHash -> Name);
else
buf[0] = L'\0';
}
@@ -879,6 +897,20 @@ void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen)
burn (keyInfo->userKey, sizeof (keyInfo->userKey));
memcpy (keyInfo->userKey, lpszUserKey, nUserKeyLen);
}
+
+void crypto_eraseKeys (PCRYPTO_INFO cryptoInfo)
+{
+ burn (cryptoInfo->ks, sizeof (cryptoInfo->ks));
+ burn (cryptoInfo->ks2, sizeof (cryptoInfo->ks2));
+#ifdef TC_WINDOWS_DRIVER
+ burn (cryptoInfo->master_keydata_hash, sizeof (cryptoInfo->master_keydata_hash));
+#else
+ burn (cryptoInfo->master_keydata, sizeof (cryptoInfo->master_keydata));
+ burn (cryptoInfo->k2, sizeof (cryptoInfo->k2));
+#endif
+ burn (&cryptoInfo->noIterations, sizeof (cryptoInfo->noIterations));
+ burn (&cryptoInfo->volumePim, sizeof (cryptoInfo->volumePim));
+}
#endif
void crypto_close (PCRYPTO_INFO cryptoInfo)
@@ -1089,11 +1121,11 @@ void EncipherBlock(int cipher, void *data, void *ks)
aes_hw_cpu_encrypt ((byte *) ks, data);
else
aes_encrypt (data, data, ks);
-#elif defined (TC_WINDOWS_BOOT_SERPENT)
+#elif defined (TC_WINDOWS_BOOT_SERPENT) && !defined (WOLFCRYPT_BACKEND)
serpent_encrypt (data, data, ks);
-#elif defined (TC_WINDOWS_BOOT_TWOFISH)
+#elif defined (TC_WINDOWS_BOOT_TWOFISH) && !defined (WOLFCRYPT_BACKEND)
twofish_encrypt (ks, data, data);
-#elif defined (TC_WINDOWS_BOOT_CAMELLIA)
+#elif defined (TC_WINDOWS_BOOT_CAMELLIA) && !defined (WOLFCRYPT_BACKEND)
camellia_encrypt (data, data, ks);
#endif
}
@@ -1105,11 +1137,11 @@ void DecipherBlock(int cipher, void *data, void *ks)
aes_hw_cpu_decrypt ((byte *) ks + sizeof (aes_encrypt_ctx) + 14 * 16, data);
else
aes_decrypt (data, data, (aes_decrypt_ctx *) ((byte *) ks + sizeof(aes_encrypt_ctx)));
-#elif defined (TC_WINDOWS_BOOT_SERPENT)
+#elif defined (TC_WINDOWS_BOOT_SERPENT) && !defined (WOLFCRYPT_BACKEND)
serpent_decrypt (data, data, ks);
-#elif defined (TC_WINDOWS_BOOT_TWOFISH)
+#elif defined (TC_WINDOWS_BOOT_TWOFISH) && !defined (WOLFCRYPT_BACKEND)
twofish_decrypt (ks, data, data);
-#elif defined (TC_WINDOWS_BOOT_CAMELLIA)
+#elif defined (TC_WINDOWS_BOOT_CAMELLIA) && !defined (WOLFCRYPT_BACKEND)
camellia_decrypt (data, data, ks);
#endif
}
@@ -1176,6 +1208,8 @@ BOOL IsAesHwCpuSupported ()
}
return state && !HwEncryptionDisabled;
+#elif defined (_M_ARM64) || defined(__arm__) || defined (__arm64__) || defined (__aarch64__)
+ return 0;
#else
return (HasAESNI() && !HwEncryptionDisabled)? TRUE : FALSE;
#endif
@@ -1197,3 +1231,327 @@ BOOL IsHwEncryptionEnabled ()
}
#endif // !TC_WINDOWS_BOOT
+
+#if !defined (TC_WINDOWS_BOOT) && !defined (_UEFI)
+
+static BOOL CpuRngDisabled = TRUE;
+static BOOL RamEncryptionEnabled = FALSE;
+
+BOOL IsCpuRngSupported ()
+{
+ if (HasRDSEED() || HasRDRAND())
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void EnableCpuRng (BOOL enable)
+{
+ CpuRngDisabled = !enable;
+}
+
+BOOL IsCpuRngEnabled ()
+{
+ return !CpuRngDisabled;
+}
+
+BOOL IsRamEncryptionSupported ()
+{
+#ifdef _WIN64
+ if (t1ha_selfcheck__t1ha2() == 0)
+ return TRUE;
+ else
+ return FALSE;
+#else
+ return FALSE;
+#endif
+}
+
+void EnableRamEncryption (BOOL enable)
+{
+ RamEncryptionEnabled = enable;
+}
+
+BOOL IsRamEncryptionEnabled ()
+{
+ return RamEncryptionEnabled;
+}
+
+/* masking for random index to remove bias */
+byte GetRngMask (byte count)
+{
+ if (count >= 128)
+ return 0xFF;
+ if (count >= 64)
+ return 0x7F;
+ if (count >= 32)
+ return 0x3F;
+ if (count >= 16)
+ return 0x1F;
+ if (count >= 8)
+ return 0x0F;
+ if (count >= 4)
+ return 0x07;
+ if (count >= 2)
+ return 0x03;
+ return 1;
+}
+
+byte GetRandomIndex (ChaCha20RngCtx* pCtx, byte elementsCount)
+{
+ byte index = 0;
+ byte mask = GetRngMask (elementsCount);
+
+ while (TRUE)
+ {
+ ChaCha20RngGetBytes (pCtx, &index, 1);
+ index &= mask;
+ if (index < elementsCount)
+ break;
+ }
+
+ return index;
+}
+
+#if defined(_WIN64) && !defined (_UEFI)
+/* declaration of variables and functions used for RAM encryption on 64-bit build */
+static byte* pbKeyDerivationArea = NULL;
+static ULONG cbKeyDerivationArea = 0;
+
+static uint64 HashSeedMask = 0;
+static uint64 CipherIVMask = 0;
+#ifdef TC_WINDOWS_DRIVER
+ULONG AllocTag = 'MMCV';
+#endif
+
+#if !defined(PAGE_SIZE)
+#define PAGE_SIZE 4096
+#endif
+
+BOOL InitializeSecurityParameters(GetRandSeedFn rngCallback)
+{
+ ChaCha20RngCtx ctx;
+ byte pbSeed[CHACHA20RNG_KEYSZ + CHACHA20RNG_IVSZ];
+#ifdef TC_WINDOWS_DRIVER
+ byte i;
+ char randomStr[4];
+ Dump ("InitializeSecurityParameters BEGIN\n");
+#endif
+
+ rngCallback (pbSeed, sizeof (pbSeed));
+
+ ChaCha20RngInit (&ctx, pbSeed, rngCallback, 0);
+
+#ifdef TC_WINDOWS_DRIVER
+
+ /* Generate random value for tag that is similar to pool tag values used by Windows kernel.
+ * Fully random tag would be too suspicious and outstanding.
+ * First character is always a capital letter.
+ * Second character is a letter, lowercase or uppercase.
+ * Third character is a letter, lowercase or uppercase.
+ * Fourth character is a letter or a digit.
+ */
+
+ /* 1. First character (Capital Letter) */
+ randomStr[0] = 'A' + GetRandomIndex(&ctx, 26);
+
+ /* 2. Second character (Letter) */
+ i = GetRandomIndex(&ctx, 52);
+ if (i < 26)
+ randomStr[1] = 'A' + i;
+ else
+ randomStr[1] = 'a' + (i - 26);
+
+ /* 3. Third character (Letter) */
+ i = GetRandomIndex(&ctx, 52);
+ if (i < 26)
+ randomStr[2] = 'A' + i;
+ else
+ randomStr[2] = 'a' + (i - 26);
+
+ /* 4. Fourth character (Letter or Digit) */
+ i = GetRandomIndex(&ctx, 62);
+ if (i < 26)
+ randomStr[3] = 'A' + i;
+ else if (i < 52)
+ randomStr[3] = 'a' + (i - 26);
+ else
+ randomStr[3] = '0' + (i - 52);
+
+ /* combine all characters in reverse order as explained in MSDN */
+ AllocTag = 0;
+ for (i = 0; i < 4; i++)
+ {
+ AllocTag = (AllocTag << 8) + randomStr[3-i];
+ }
+
+#endif
+
+ cbKeyDerivationArea = 1024 * 1024;
+ do
+ {
+ pbKeyDerivationArea = (byte*) TCalloc(cbKeyDerivationArea);
+ if (!pbKeyDerivationArea)
+ cbKeyDerivationArea >>= 1;
+ } while (!pbKeyDerivationArea && (cbKeyDerivationArea >= (2*PAGE_SIZE)));
+
+ if (!pbKeyDerivationArea)
+ {
+ cbKeyDerivationArea = 0;
+ Dump ("InitializeSecurityParameters return=FALSE END\n");
+ return FALSE;
+ }
+
+ /* fill key derivation area with random bytes */
+ ChaCha20RngGetBytes (&ctx, pbKeyDerivationArea, cbKeyDerivationArea);
+
+ /* generate hash seed mask */
+ ChaCha20RngGetBytes(&ctx, (unsigned char*) &HashSeedMask, sizeof (HashSeedMask));
+
+ /* generate IV mask */
+ ChaCha20RngGetBytes(&ctx, (unsigned char*) &CipherIVMask, sizeof (CipherIVMask));
+
+ FAST_ERASE64 (pbSeed, sizeof (pbSeed));
+ burn (&ctx, sizeof (ctx));
+#ifdef TC_WINDOWS_DRIVER
+ burn (randomStr, sizeof(randomStr));
+
+ Dump ("InitializeSecurityParameters return=TRUE END\n");
+#endif
+ return TRUE;
+}
+
+void ClearSecurityParameters()
+{
+ Dump ("ClearSecurityParameters BEGIN\n");
+ if (pbKeyDerivationArea)
+ {
+ FAST_ERASE64 (pbKeyDerivationArea, cbKeyDerivationArea);
+ TCfree (pbKeyDerivationArea);
+ pbKeyDerivationArea =NULL;
+ cbKeyDerivationArea = 0;
+ }
+
+ FAST_ERASE64 (&HashSeedMask, 8);
+ FAST_ERASE64 (&CipherIVMask, 8);
+#ifdef TC_WINDOWS_DRIVER
+ burn (&AllocTag, sizeof (AllocTag));
+#endif
+ Dump ("ClearSecurityParameters END\n");
+}
+
+#ifdef TC_WINDOWS_DRIVER
+void VcProtectMemory (uint64 encID, unsigned char* pbData, size_t cbData, unsigned char* pbData2, size_t cbData2)
+#else
+void VcProtectMemory (uint64 encID, unsigned char* pbData, size_t cbData,
+ unsigned char* pbData2, size_t cbData2,
+ unsigned char* pbData3, size_t cbData3,
+ unsigned char* pbData4, size_t cbData4)
+#endif
+{
+ if (pbKeyDerivationArea)
+ {
+ uint64 hashLow, hashHigh, hashSeed, cipherIV;
+ uint64 pbKey[4];
+ ChaCha256Ctx ctx;
+
+ hashSeed = (((uint64) pbKeyDerivationArea) + encID) ^ HashSeedMask;
+ hashLow = t1ha2_atonce128(&hashHigh, pbKeyDerivationArea, cbKeyDerivationArea, hashSeed);
+
+ /* set the key to the hash result */
+ pbKey[0] = hashLow;
+ pbKey[1] = hashHigh;
+ /* we now have a 128-bit key and we will expand it to 256-bit by using ChaCha12 cipher */
+ /* first we need to generate a the other 128-bit half of the key */
+ pbKey[2] = hashLow ^ hashHigh;
+ pbKey[3] = hashLow + hashHigh;
+
+ /* Initialize ChaCha12 cipher */
+ ChaCha256Init (&ctx, (unsigned char*) pbKey, (unsigned char*) &hashSeed, 12);
+ /* encrypt the key by itself */
+ ChaCha256Encrypt (&ctx, (unsigned char*) pbKey, sizeof(pbKey), (unsigned char*) pbKey);
+
+ /* Initialize ChaCha12 cipher */
+ cipherIV = (((uint64) pbKeyDerivationArea) + encID) ^ CipherIVMask;
+ ChaCha256Init (&ctx, (unsigned char*) pbKey, (unsigned char*) &cipherIV, 12);
+
+ ChaCha256Encrypt (&ctx, pbData, cbData, pbData);
+ ChaCha256Encrypt (&ctx, pbData2, cbData2, pbData2);
+#ifndef TC_WINDOWS_DRIVER
+ ChaCha256Encrypt (&ctx, pbData3, cbData3, pbData3);
+ ChaCha256Encrypt (&ctx, pbData4, cbData4, pbData4);
+#endif
+ FAST_ERASE64 (pbKey, sizeof(pbKey));
+ FAST_ERASE64 (&hashLow, 8);
+ FAST_ERASE64 (&hashHigh, 8);
+ FAST_ERASE64 (&hashSeed, 8);
+ FAST_ERASE64 (&cipherIV, 8);
+ burn (&ctx, sizeof (ctx));
+ }
+}
+
+uint64 VcGetEncryptionID (PCRYPTO_INFO pCryptoInfo)
+{
+ return ((uint64) pCryptoInfo->ks) + ((uint64) pCryptoInfo->ks2)
+#ifndef TC_WINDOWS_DRIVER
+ + ((uint64) pCryptoInfo->master_keydata) + ((uint64) pCryptoInfo->k2)
+#endif
+ ;
+}
+
+static void VcInternalProtectKeys (PCRYPTO_INFO pCryptoInfo, uint64 encID)
+{
+#ifdef TC_WINDOWS_DRIVER
+ VcProtectMemory (encID, pCryptoInfo->ks, MAX_EXPANDED_KEY, pCryptoInfo->ks2, MAX_EXPANDED_KEY);
+#else
+ VcProtectMemory (encID, pCryptoInfo->ks, MAX_EXPANDED_KEY,
+ pCryptoInfo->ks2, MAX_EXPANDED_KEY,
+ pCryptoInfo->master_keydata, MASTER_KEYDATA_SIZE,
+ pCryptoInfo->k2, MASTER_KEYDATA_SIZE);
+#endif
+
+}
+
+void VcProtectKeys (PCRYPTO_INFO pCryptoInfo, uint64 encID)
+{
+ Dump ("VcProtectKeys BEGIN\n");
+ VcInternalProtectKeys (pCryptoInfo, encID);
+ Dump ("VcProtectKeys END\n");
+}
+
+void VcUnprotectKeys (PCRYPTO_INFO pCryptoInfo, uint64 encID)
+{
+ Dump ("VcUnprotectKeys BEGIN\n");
+ VcInternalProtectKeys (pCryptoInfo, encID);
+ Dump ("VcUnprotectKeys END\n");
+}
+#endif
+
+#endif
+
+#if defined(_M_ARM64) || defined(__arm__) || defined (__arm64__) || defined (__aarch64__)
+/* dummy implementation that should never be called */
+void aes_hw_cpu_decrypt(const byte* ks, byte* data)
+{
+ ks = ks;
+ data = data;
+}
+
+void aes_hw_cpu_decrypt_32_blocks(const byte* ks, byte* data)
+{
+ ks = ks;
+ data = data;
+}
+
+void aes_hw_cpu_encrypt(const byte* ks, byte* data)
+{
+ ks = ks;
+ data = data;
+}
+
+void aes_hw_cpu_encrypt_32_blocks(const byte* ks, byte* data)
+{
+ ks = ks;
+ data = data;
+}
+#endif