diff options
Diffstat (limited to 'src/Common/Volumes.c')
-rw-r--r-- | src/Common/Volumes.c | 292 |
1 files changed, 180 insertions, 112 deletions
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c index 53734abb..989b2d14 100644 --- a/src/Common/Volumes.c +++ b/src/Common/Volumes.c @@ -27,6 +27,8 @@ #ifndef DEVICE_DRIVER #include "Random.h" +#else +#include "cpu.h" #endif #endif // !defined(_UEFI) @@ -167,10 +169,13 @@ typedef struct BOOL ReadVolumeHeaderRecoveryMode = FALSE; -int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int selected_pkcs5_prf, int pim, BOOL truecryptMode, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo) +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]; - CRYPTOPP_ALIGN_DATA(16) KEY_INFO keyInfo; + unsigned char* keyInfoBuffer = NULL; + int keyInfoBufferSize = sizeof (KEY_INFO) + 16; + size_t keyInfoBufferOffset; + PKEY_INFO keyInfo; PCRYPTO_INFO cryptoInfo; CRYPTOPP_ALIGN_DATA(16) char dk[MASTER_KEYDATA_SIZE]; int enqPkcs5Prf, pkcs5_prf; @@ -179,28 +184,32 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int int primaryKeyOffset; int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1; #if !defined(_UEFI) - TC_EVENT keyDerivationCompletedEvent; - TC_EVENT noOutstandingWorkItemEvent; - KeyDerivationWorkItem *keyDerivationWorkItems; + TC_EVENT *keyDerivationCompletedEvent = NULL; + TC_EVENT *noOutstandingWorkItemEvent = NULL; + KeyDerivationWorkItem *keyDerivationWorkItems = NULL; + int keyDerivationWorkItemsSize = 0; KeyDerivationWorkItem *item; size_t encryptionThreadCount = GetEncryptionThreadCount(); - LONG outstandingWorkItemCount = 0; + LONG *outstandingWorkItemCount = NULL; int i; #endif size_t queuedWorkItems = 0; + // allocate 16-bytes aligned buffer to hold KEY_INFO in a portable way + keyInfoBuffer = TCalloc(keyInfoBufferSize); + if (!keyInfoBuffer) + return ERR_OUTOFMEMORY; + keyInfoBufferOffset = 16 - (((uint64) keyInfoBuffer) % 16); + keyInfo = (PKEY_INFO) (keyInfoBuffer + keyInfoBufferOffset); + +#if !defined(DEVICE_DRIVER) && !defined(_UEFI) + VirtualLock (keyInfoBuffer, keyInfoBufferSize); +#endif + // if no PIM specified, use default value if (pim < 0) pim = 0; - if (truecryptMode) - { - // SHA-256 not supported in TrueCrypt mode - if (selected_pkcs5_prf == SHA256) - return ERR_PARAMETER_INCORRECT; - pkcs5PrfCount--; // don't count SHA-256 in case of TrueCrypt mode - } - if (retHeaderCryptoInfo != NULL) { cryptoInfo = retHeaderCryptoInfo; @@ -218,45 +227,78 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int /* use thread pool only if no PRF was specified */ if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1)) { - keyDerivationWorkItems = TCalloc (sizeof (KeyDerivationWorkItem) * pkcs5PrfCount); + keyDerivationCompletedEvent = TCalloc (sizeof (TC_EVENT)); + if (!keyDerivationCompletedEvent) + return ERR_OUTOFMEMORY; + + noOutstandingWorkItemEvent = TCalloc (sizeof (TC_EVENT)); + if (!noOutstandingWorkItemEvent) + { + TCfree(keyDerivationCompletedEvent); + return ERR_OUTOFMEMORY; + } + + outstandingWorkItemCount = TCalloc (sizeof (LONG)); + if (!outstandingWorkItemCount) + { + TCfree(keyDerivationCompletedEvent); + TCfree(noOutstandingWorkItemEvent); + return ERR_OUTOFMEMORY; + } + + keyDerivationWorkItemsSize = sizeof (KeyDerivationWorkItem) * pkcs5PrfCount; + keyDerivationWorkItems = TCalloc (keyDerivationWorkItemsSize); if (!keyDerivationWorkItems) + { + TCfree(keyDerivationCompletedEvent); + TCfree(noOutstandingWorkItemEvent); + TCfree(outstandingWorkItemCount); return ERR_OUTOFMEMORY; + } for (i = 0; i < pkcs5PrfCount; ++i) keyDerivationWorkItems[i].Free = TRUE; + *outstandingWorkItemCount = 0; #ifdef DEVICE_DRIVER - KeInitializeEvent (&keyDerivationCompletedEvent, SynchronizationEvent, FALSE); - KeInitializeEvent (&noOutstandingWorkItemEvent, SynchronizationEvent, TRUE); + KeInitializeEvent (keyDerivationCompletedEvent, SynchronizationEvent, FALSE); + KeInitializeEvent (noOutstandingWorkItemEvent, SynchronizationEvent, TRUE); #else - keyDerivationCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL); - if (!keyDerivationCompletedEvent) + *keyDerivationCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + if (!*keyDerivationCompletedEvent) { TCfree (keyDerivationWorkItems); + TCfree(keyDerivationCompletedEvent); + TCfree(noOutstandingWorkItemEvent); + TCfree(outstandingWorkItemCount); return ERR_OUTOFMEMORY; } - noOutstandingWorkItemEvent = CreateEvent (NULL, FALSE, TRUE, NULL); - if (!noOutstandingWorkItemEvent) + *noOutstandingWorkItemEvent = CreateEvent (NULL, FALSE, TRUE, NULL); + if (!*noOutstandingWorkItemEvent) { - CloseHandle (keyDerivationCompletedEvent); + CloseHandle (*keyDerivationCompletedEvent); TCfree (keyDerivationWorkItems); + TCfree(keyDerivationCompletedEvent); + TCfree(noOutstandingWorkItemEvent); + TCfree(outstandingWorkItemCount); return ERR_OUTOFMEMORY; } + + VirtualLock (keyDerivationWorkItems, keyDerivationWorkItemsSize); #endif } #if !defined(DEVICE_DRIVER) - VirtualLock (&keyInfo, sizeof (keyInfo)); VirtualLock (&dk, sizeof (dk)); VirtualLock (&header, sizeof (header)); #endif #endif // !defined(_UEFI) - crypto_loadkey (&keyInfo, password->Text, (int) password->Length); + 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); + 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) @@ -265,9 +307,6 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int if (selected_pkcs5_prf != 0 && enqPkcs5Prf != selected_pkcs5_prf) continue; - // skip SHA-256 in case of TrueCrypt mode - if (truecryptMode && (enqPkcs5Prf == SHA256)) - continue; #if !defined(_UEFI) if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1)) { @@ -283,9 +322,9 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int item->KeyReady = FALSE; item->Pkcs5Prf = enqPkcs5Prf; - EncryptionThreadPoolBeginKeyDerivation (&keyDerivationCompletedEvent, &noOutstandingWorkItemEvent, - &item->KeyReady, &outstandingWorkItemCount, enqPkcs5Prf, keyInfo.userKey, - keyInfo.keyLength, keyInfo.salt, get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot), item->DerivedKey); + EncryptionThreadPoolBeginKeyDerivation (keyDerivationCompletedEvent, noOutstandingWorkItemEvent, + &item->KeyReady, outstandingWorkItemCount, enqPkcs5Prf, keyInfo->userKey, + keyInfo->keyLength, keyInfo->salt, get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot), item->DerivedKey); ++queuedWorkItems; break; @@ -307,7 +346,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int if (!item->Free && InterlockedExchangeAdd (&item->KeyReady, 0) == TRUE) { pkcs5_prf = item->Pkcs5Prf; - keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, truecryptMode, bBoot); + keyInfo->noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, bBoot); memcpy (dk, item->DerivedKey, sizeof (dk)); item->Free = TRUE; @@ -317,7 +356,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int } if (queuedWorkItems > 0) - TC_WAIT_EVENT (keyDerivationCompletedEvent); + TC_WAIT_EVENT (*keyDerivationCompletedEvent); } continue; KeyReady: ; @@ -326,35 +365,38 @@ KeyReady: ; #endif // !defined(_UEFI) { pkcs5_prf = enqPkcs5Prf; - keyInfo.noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot); + keyInfo->noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot); switch (pkcs5_prf) { - case RIPEMD160: - derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt, - PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize()); + 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, - PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize()); + 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, - PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize()); + #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, - PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize()); + 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()); + + 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; } @@ -415,10 +457,8 @@ KeyReady: ; DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); - // Magic 'VERA' or 'TRUE' depending if we are in TrueCrypt mode or not - if ((truecryptMode && GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x54525545) - || (!truecryptMode && GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241) - ) + // Magic 'VERA' + if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241) continue; // Header version @@ -438,17 +478,7 @@ KeyReady: ; // Required program version cryptoInfo->RequiredProgramVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_REQUIRED_VERSION); - if (truecryptMode) - { - if (cryptoInfo->RequiredProgramVersion < 0x600 || cryptoInfo->RequiredProgramVersion > 0x71a) - { - status = ERR_UNSUPPORTED_TRUECRYPT_FORMAT | (((int)cryptoInfo->RequiredProgramVersion) << 16); - goto err; - } - cryptoInfo->LegacyVolume = FALSE; - } - else - cryptoInfo->LegacyVolume = cryptoInfo->RequiredProgramVersion < 0x10b; + cryptoInfo->LegacyVolume = cryptoInfo->RequiredProgramVersion < 0x10b; // Check CRC of the key set if (!ReadVolumeHeaderRecoveryMode @@ -458,7 +488,7 @@ KeyReady: ; // Now we have the correct password, cipher, hash algorithm, and volume type // Check the version required to handle this volume - if (!truecryptMode && (cryptoInfo->RequiredProgramVersion > VERSION_NUM)) + if (cryptoInfo->RequiredProgramVersion > VERSION_NUM) { status = ERR_NEW_VERSION_REQUIRED; goto err; @@ -509,8 +539,7 @@ KeyReady: ; if (retInfo == NULL) { cryptoInfo->pkcs5 = pkcs5_prf; - cryptoInfo->noIterations = keyInfo.noIterations; - cryptoInfo->bTrueCryptMode = truecryptMode; + cryptoInfo->noIterations = keyInfo->noIterations; cryptoInfo->volumePim = pim; goto ret; } @@ -526,34 +555,43 @@ KeyReady: ; } // Master key data - memcpy (keyInfo.master_keydata, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE); + memcpy (keyInfo->master_keydata, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE); #ifdef TC_WINDOWS_DRIVER { - RMD160_CTX ctx; - RMD160Init (&ctx); - RMD160Update (&ctx, keyInfo.master_keydata, MASTER_KEYDATA_SIZE); - RMD160Update (&ctx, header, sizeof(header)); - RMD160Final (cryptoInfo->master_keydata_hash, &ctx); + blake2s_state ctx; +#ifndef _WIN64 + NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; + KFLOATING_SAVE floatingPointState; + if (HasSSE2()) + saveStatus = KeSaveFloatingPointState (&floatingPointState); +#endif + blake2s_init (&ctx); + blake2s_update (&ctx, keyInfo->master_keydata, MASTER_KEYDATA_SIZE); + 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); + memcpy (cryptoInfo->master_keydata, keyInfo->master_keydata, MASTER_KEYDATA_SIZE); #endif // PKCS #5 cryptoInfo->pkcs5 = pkcs5_prf; - cryptoInfo->noIterations = keyInfo.noIterations; - cryptoInfo->bTrueCryptMode = truecryptMode; + 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); + 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)); + memcpy (cryptoInfo->k2, keyInfo->master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea)); #endif - if (!EAInitMode (cryptoInfo, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea))) + if (!EAInitMode (cryptoInfo, keyInfo->master_keydata + EAGetKeySize (cryptoInfo->ea))) { status = ERR_MODE_INIT_FAILED; goto err; @@ -573,13 +611,11 @@ err: *retInfo = NULL; } -ret: - burn (&keyInfo, sizeof (keyInfo)); +ret: burn (dk, sizeof(dk)); burn (header, sizeof(header)); #if !defined(DEVICE_DRIVER) && !defined(_UEFI) - VirtualUnlock (&keyInfo, sizeof (keyInfo)); VirtualUnlock (&dk, sizeof (dk)); VirtualUnlock (&header, sizeof (header)); #endif @@ -587,17 +623,19 @@ ret: #if !defined(_UEFI) if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1)) { - TC_WAIT_EVENT (noOutstandingWorkItemEvent); - - burn (keyDerivationWorkItems, sizeof (KeyDerivationWorkItem) * pkcs5PrfCount); - TCfree (keyDerivationWorkItems); - -#if !defined(DEVICE_DRIVER) - CloseHandle (keyDerivationCompletedEvent); - CloseHandle (noOutstandingWorkItemEvent); -#endif + 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; } @@ -615,7 +653,8 @@ void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderS // // 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); @@ -632,6 +671,26 @@ void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderS 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 @@ -661,7 +720,7 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR derive_key_sha256 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE, iterations, dk, sizeof (dk)); #else - derive_key_ripemd160 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET, + derive_key_blake2s (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE, iterations, dk, sizeof (dk)); #endif @@ -676,11 +735,11 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR #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); @@ -694,11 +753,11 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR #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); @@ -744,7 +803,7 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR #ifdef TC_WINDOWS_BOOT_SHA2 cryptoInfo->pkcs5 = SHA256; #else - cryptoInfo->pkcs5 = RIPEMD160; + cryptoInfo->pkcs5 = BLAKE2S; #endif memcpy (dk, header + HEADER_MASTER_KEYDATA_OFFSET, sizeof (dk)); @@ -755,11 +814,11 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR // 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); @@ -774,11 +833,11 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR // 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); @@ -874,6 +933,15 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, retVal = ERR_CIPHER_INIT_WEAK_KEY; goto err; } + + // check that first half of keyInfo.master_keydata is different from the second half. If they are the same return error + // cf CCSS,NSA comment at page 3: https://csrc.nist.gov/csrc/media/Projects/crypto-publication-review-project/documents/initial-comments/sp800-38e-initial-public-comments-2021.pdf + if (memcmp (keyInfo.master_keydata, &keyInfo.master_keydata[bytesNeeded/2], bytesNeeded/2) == 0) + { + crypto_close (cryptoInfo); + retVal = ERR_CIPHER_INIT_WEAK_KEY; + goto err; + } } else { @@ -886,7 +954,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, { memcpy (keyInfo.userKey, password->Text, nUserKeyLen); keyInfo.keyLength = nUserKeyLen; - keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, FALSE, bBoot); + keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, bBoot); } else { @@ -899,7 +967,6 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, // User selected PRF cryptoInfo->pkcs5 = pkcs5_prf; - cryptoInfo->bTrueCryptMode = FALSE; cryptoInfo->noIterations = keyInfo.noIterations; cryptoInfo->volumePim = pim; @@ -933,8 +1000,9 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize()); break; - case RIPEMD160: - derive_key_ripemd160 (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; @@ -947,7 +1015,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, 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); |