diff options
Diffstat (limited to 'src/Common/Volumes.c')
-rw-r--r-- | src/Common/Volumes.c | 126 |
1 files changed, 67 insertions, 59 deletions
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c index 9590715e..989b2d14 100644 --- a/src/Common/Volumes.c +++ b/src/Common/Volumes.c @@ -169,7 +169,7 @@ 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]; unsigned char* keyInfoBuffer = NULL; @@ -210,14 +210,6 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int 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; @@ -315,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)) { @@ -335,7 +324,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int EncryptionThreadPoolBeginKeyDerivation (keyDerivationCompletedEvent, noOutstandingWorkItemEvent, &item->KeyReady, outstandingWorkItemCount, enqPkcs5Prf, keyInfo->userKey, - keyInfo->keyLength, keyInfo->salt, get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot), item->DerivedKey); + keyInfo->keyLength, keyInfo->salt, get_pkcs5_iteration_count (enqPkcs5Prf, pim, bBoot), item->DerivedKey); ++queuedWorkItems; break; @@ -357,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; @@ -376,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 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; } @@ -465,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 @@ -488,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 @@ -508,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; @@ -560,7 +540,6 @@ KeyReady: ; { cryptoInfo->pkcs5 = pkcs5_prf; cryptoInfo->noIterations = keyInfo->noIterations; - cryptoInfo->bTrueCryptMode = truecryptMode; cryptoInfo->volumePim = pim; goto ret; } @@ -602,7 +581,6 @@ KeyReady: ; // PKCS #5 cryptoInfo->pkcs5 = pkcs5_prf; cryptoInfo->noIterations = keyInfo->noIterations; - cryptoInfo->bTrueCryptMode = truecryptMode; cryptoInfo->volumePim = pim; // Init the cipher with the decrypted master key @@ -675,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); @@ -692,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 @@ -736,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); @@ -754,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); @@ -815,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); @@ -834,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); @@ -934,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 { @@ -946,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 { @@ -959,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; @@ -993,6 +1000,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, 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()); @@ -1007,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); |