diff options
Diffstat (limited to 'src/Common/Volumes.c')
-rw-r--r-- | src/Common/Volumes.c | 229 |
1 files changed, 137 insertions, 92 deletions
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c index 37fa481c..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; @@ -182,6 +187,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int TC_EVENT *keyDerivationCompletedEvent = NULL; TC_EVENT *noOutstandingWorkItemEvent = NULL; KeyDerivationWorkItem *keyDerivationWorkItems = NULL; + int keyDerivationWorkItemsSize = 0; KeyDerivationWorkItem *item; size_t encryptionThreadCount = GetEncryptionThreadCount(); LONG *outstandingWorkItemCount = NULL; @@ -189,18 +195,21 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int #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; @@ -237,7 +246,8 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int return ERR_OUTOFMEMORY; } - keyDerivationWorkItems = TCalloc (sizeof (KeyDerivationWorkItem) * pkcs5PrfCount); + keyDerivationWorkItemsSize = sizeof (KeyDerivationWorkItem) * pkcs5PrfCount; + keyDerivationWorkItems = TCalloc (keyDerivationWorkItemsSize); if (!keyDerivationWorkItems) { TCfree(keyDerivationCompletedEvent); @@ -267,27 +277,28 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int *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) @@ -296,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)) { @@ -315,8 +323,8 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int 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); + &item->KeyReady, outstandingWorkItemCount, enqPkcs5Prf, keyInfo->userKey, + keyInfo->keyLength, keyInfo->salt, get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot), item->DerivedKey); ++queuedWorkItems; break; @@ -338,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; @@ -357,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; } @@ -446,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 @@ -469,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 @@ -489,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; @@ -540,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; } @@ -557,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; @@ -604,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 @@ -618,9 +623,19 @@ ret: #if !defined(_UEFI) if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1)) { - EncryptionThreadPoolBeginReadVolumeHeaderFinalization (keyDerivationCompletedEvent, noOutstandingWorkItemEvent, outstandingWorkItemCount, keyDerivationWorkItems, sizeof (KeyDerivationWorkItem) * pkcs5PrfCount); + 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; } @@ -638,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); @@ -655,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 @@ -684,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 @@ -699,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); @@ -717,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); @@ -767,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)); @@ -778,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); @@ -797,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); @@ -897,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 { @@ -909,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 { @@ -922,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; @@ -956,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; @@ -970,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); |