From 68f16dae244752e8bdf112e8feeb6a0839088a3e Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Tue, 14 Oct 2014 17:14:54 +0200 Subject: Implement support for creating and booting encrypted partition using SHA-256. Support SHA-256 for normal volumes as well. --- src/Common/Apidrvr.h | 1 + src/Common/BootEncryption.cpp | 76 +++++++++++++++++++++++++++++++++------ src/Common/BootEncryption.h | 1 + src/Common/Common.rc | 20 +++++++++++ src/Common/Dlgcode.c | 12 +++++++ src/Common/EncryptionThreadPool.c | 5 +++ src/Common/Random.c | 15 ++++++++ src/Common/Resource.h | 16 +++++++++ src/Driver/DriveFilter.c | 1 + 9 files changed, 137 insertions(+), 10 deletions(-) diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h index 1a28dec0..ac6f3fbb 100644 --- a/src/Common/Apidrvr.h +++ b/src/Common/Apidrvr.h @@ -241,6 +241,7 @@ typedef struct typedef struct { char BootEncryptionAlgorithmName[256]; + char BootPrfAlgorithmName[256]; } GetBootEncryptionAlgorithmNameRequest; typedef struct diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index 9f848fc7..be521fd6 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -375,6 +375,7 @@ namespace VeraCrypt RescueIsoImage (nullptr), RescueVolumeHeaderValid (false), SelectedEncryptionAlgorithmId (0), + SelectedPrfAlgorithmId (0), VolumeHeaderValid (false) { HiddenOSCandidatePartition.IsGPT = FALSE; @@ -975,11 +976,16 @@ namespace VeraCrypt ZeroMemory (buffer, bufferSize); int ea = 0; + int pkcs5_prf = 0; if (GetStatus().DriveMounted) { try { GetBootEncryptionAlgorithmNameRequest request; + // since we added new field to GetBootEncryptionAlgorithmNameRequest since version 1.0f + // we zero all the structure so that if we are talking to an older driver, the field + // BootPrfAlgorithmName will be an empty string + ZeroMemory(&request, sizeof(request)); CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME, NULL, 0, &request, sizeof (request)); if (_stricmp (request.BootEncryptionAlgorithmName, "AES") == 0) @@ -988,6 +994,13 @@ namespace VeraCrypt ea = SERPENT; else if (_stricmp (request.BootEncryptionAlgorithmName, "Twofish") == 0) ea = TWOFISH; + + if (_stricmp(request.BootPrfAlgorithmName, "SHA-256") == 0) + pkcs5_prf = SHA256; + else if (_stricmp(request.BootPrfAlgorithmName, "RIPEMD-160") == 0) + pkcs5_prf = RIPEMD160; + else if (strlen(request.BootPrfAlgorithmName) == 0) // case of version < 1.0f + pkcs5_prf = RIPEMD160; } catch (...) { @@ -996,36 +1009,77 @@ namespace VeraCrypt VOLUME_PROPERTIES_STRUCT properties; GetVolumeProperties (&properties); ea = properties.ea; + pkcs5_prf = properties.pkcs5; } catch (...) { } } } else { - if (SelectedEncryptionAlgorithmId == 0) + if (SelectedEncryptionAlgorithmId == 0 || SelectedPrfAlgorithmId == 0) throw ParameterIncorrect (SRC_POS); ea = SelectedEncryptionAlgorithmId; + pkcs5_prf = SelectedPrfAlgorithmId; } - int bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR : IDR_BOOT_SECTOR; - int bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER : IDR_BOOT_LOADER; + // Only RIPEMD160 and SHA-256 are supported for boot loader + if (pkcs5_prf != RIPEMD160 && pkcs5_prf != SHA256) + throw ParameterIncorrect (SRC_POS); + + int bootSectorId = 0; + int bootLoaderId = 0; + + if (pkcs5_prf == SHA256) + { + bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SHA2 : IDR_BOOT_SECTOR_SHA2; + bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SHA2 : IDR_BOOT_LOADER_SHA2; + } + else + { + bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR : IDR_BOOT_SECTOR; + bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER : IDR_BOOT_LOADER; + } switch (ea) { case AES: - bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_AES : IDR_BOOT_SECTOR_AES; - bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_AES : IDR_BOOT_LOADER_AES; + if (pkcs5_prf == SHA256) + { + bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_AES_SHA2 : IDR_BOOT_SECTOR_AES_SHA2; + bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_AES_SHA2 : IDR_BOOT_LOADER_AES_SHA2; + } + else + { + bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_AES : IDR_BOOT_SECTOR_AES; + bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_AES : IDR_BOOT_LOADER_AES; + } break; case SERPENT: - bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SERPENT : IDR_BOOT_SECTOR_SERPENT; - bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SERPENT : IDR_BOOT_LOADER_SERPENT; + if (pkcs5_prf == SHA256) + { + bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SERPENT_SHA2 : IDR_BOOT_SECTOR_SERPENT_SHA2; + bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SERPENT_SHA2 : IDR_BOOT_LOADER_SERPENT_SHA2; + } + else + { + bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SERPENT : IDR_BOOT_SECTOR_SERPENT; + bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SERPENT : IDR_BOOT_LOADER_SERPENT; + } break; case TWOFISH: - bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_TWOFISH : IDR_BOOT_SECTOR_TWOFISH; - bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_TWOFISH : IDR_BOOT_LOADER_TWOFISH; + if (pkcs5_prf == SHA256) + { + bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_TWOFISH_SHA2 : IDR_BOOT_SECTOR_TWOFISH_SHA2; + bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_TWOFISH_SHA2 : IDR_BOOT_LOADER_TWOFISH_SHA2; + } + else + { + bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_TWOFISH : IDR_BOOT_SECTOR_TWOFISH; + bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_TWOFISH : IDR_BOOT_LOADER_TWOFISH; + } break; } @@ -1084,7 +1138,7 @@ namespace VeraCrypt buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE; } - else if (!rescueDisk && bootLoaderId != IDR_BOOT_LOADER) + else if (!rescueDisk && bootLoaderId != IDR_BOOT_LOADER && bootLoaderId != IDR_BOOT_LOADER_SHA2) { throw ParameterIncorrect (SRC_POS); } @@ -2253,6 +2307,7 @@ namespace VeraCrypt BackupSystemLoader(); SelectedEncryptionAlgorithmId = ea; + SelectedPrfAlgorithmId = pkcs5; } @@ -2307,6 +2362,7 @@ namespace VeraCrypt } SelectedEncryptionAlgorithmId = ea; + SelectedPrfAlgorithmId = pkcs5; CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5); if (!rescueIsoImagePath.empty()) diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h index a52f286b..db1eb423 100644 --- a/src/Common/BootEncryption.h +++ b/src/Common/BootEncryption.h @@ -215,6 +215,7 @@ namespace VeraCrypt HWND ParentWindow; SystemDriveConfiguration DriveConfig; int SelectedEncryptionAlgorithmId; + int SelectedPrfAlgorithmId; Partition HiddenOSCandidatePartition; byte *RescueIsoImage; byte RescueVolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; diff --git a/src/Common/Common.rc b/src/Common/Common.rc index 34d4a7b7..5eff1b4d 100644 --- a/src/Common/Common.rc +++ b/src/Common/Common.rc @@ -449,6 +449,17 @@ IDR_BOOT_LOADER BIN "..\\Boot\\Windows\\Release\\Boo IDR_BOOT_LOADER_AES BIN "..\\Boot\\Windows\\Release_AES\\BootLoader.com.gz" IDR_BOOT_LOADER_SERPENT BIN "..\\Boot\\Windows\\Release_Serpent\\BootLoader.com.gz" IDR_BOOT_LOADER_TWOFISH BIN "..\\Boot\\Windows\\Release_Twofish\\BootLoader.com.gz" + +IDR_BOOT_SECTOR_SHA2 BIN "..\\Boot\\Windows\\Release_SHA2\\BootSector.bin" +IDR_BOOT_SECTOR_AES_SHA2 BIN "..\\Boot\\Windows\\Release_AES_SHA2\\BootSector.bin" +IDR_BOOT_SECTOR_SERPENT_SHA2 BIN "..\\Boot\\Windows\\Release_Serpent_SHA2\\BootSector.bin" +IDR_BOOT_SECTOR_TWOFISH_SHA2 BIN "..\\Boot\\Windows\\Release_Twofish_SHA2\\BootSector.bin" +IDR_BOOT_LOADER_SHA2 BIN "..\\Boot\\Windows\\Release_SHA2\\BootLoader.com.gz" +IDR_BOOT_LOADER_AES_SHA2 BIN "..\\Boot\\Windows\\Release_AES_SHA2\\BootLoader.com.gz" +IDR_BOOT_LOADER_SERPENT_SHA2 BIN "..\\Boot\\Windows\\Release_Serpent_SHA2\\BootLoader.com.gz" +IDR_BOOT_LOADER_TWOFISH_SHA2 BIN "..\\Boot\\Windows\\Release_Twofish_SHA2\\BootLoader.com.gz" + + IDR_RESCUE_BOOT_SECTOR BIN "..\\Boot\\Windows\\Rescue\\BootSector.bin" IDR_RESCUE_BOOT_SECTOR_AES BIN "..\\Boot\\Windows\\Rescue_AES\\BootSector.bin" IDR_RESCUE_BOOT_SECTOR_SERPENT BIN "..\\Boot\\Windows\\Rescue_Serpent\\BootSector.bin" @@ -458,6 +469,15 @@ IDR_RESCUE_LOADER_AES BIN "..\\Boot\\Windows\\Rescue_AES\\ IDR_RESCUE_LOADER_SERPENT BIN "..\\Boot\\Windows\\Rescue_Serpent\\BootLoader.com.gz" IDR_RESCUE_LOADER_TWOFISH BIN "..\\Boot\\Windows\\Rescue_Twofish\\BootLoader.com.gz" +IDR_RESCUE_BOOT_SECTOR_SHA2 BIN "..\\Boot\\Windows\\Rescue_SHA2\\BootSector.bin" +IDR_RESCUE_BOOT_SECTOR_AES_SHA2 BIN "..\\Boot\\Windows\\Rescue_AES_SHA2\\BootSector.bin" +IDR_RESCUE_BOOT_SECTOR_SERPENT_SHA2 BIN "..\\Boot\\Windows\\Rescue_Serpent_SHA2\\BootSector.bin" +IDR_RESCUE_BOOT_SECTOR_TWOFISH_SHA2 BIN "..\\Boot\\Windows\\Rescue_Twofish_SHA2\\BootSector.bin" +IDR_RESCUE_LOADER_SHA2 BIN "..\\Boot\\Windows\\Rescue_SHA2\\BootLoader.com.gz" +IDR_RESCUE_LOADER_AES_SHA2 BIN "..\\Boot\\Windows\\Rescue_AES_SHA2\\BootLoader.com.gz" +IDR_RESCUE_LOADER_SERPENT_SHA2 BIN "..\\Boot\\Windows\\Rescue_Serpent_SHA2\\BootLoader.com.gz" +IDR_RESCUE_LOADER_TWOFISH_SHA2 BIN "..\\Boot\\Windows\\Rescue_Twofish_SHA2\\BootLoader.com.gz" + ///////////////////////////////////////////////////////////////////////////// // // XML diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index ffb62ecb..c19e1992 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -4363,6 +4363,7 @@ static BOOL PerformBenchmark(HWND hwndDlg) WHIRLPOOL_CTX wctx; RMD160_CTX rctx; sha512_ctx s2ctx; + sha256_ctx s256ctx; int hid; for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++) @@ -4379,6 +4380,12 @@ static BOOL PerformBenchmark(HWND hwndDlg) sha512_end ((unsigned char *) digest, &s2ctx); break; + case SHA256: + sha256_begin (&s256ctx); + sha256_hash (lpTestBuffer, benchmarkBufferSize, &s256ctx); + sha256_end ((unsigned char *) digest, &s256ctx); + break; + case RIPEMD160: RMD160Init(&rctx); RMD160Update(&rctx, lpTestBuffer, benchmarkBufferSize); @@ -4433,6 +4440,11 @@ static BOOL PerformBenchmark(HWND hwndDlg) derive_key_sha512 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); break; + case SHA256: + /* PKCS-5 test with HMAC-SHA-256 used as the PRF */ + derive_key_sha256 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); + break; + case RIPEMD160: /* PKCS-5 test with HMAC-RIPEMD-160 used as the PRF */ derive_key_ripemd160 (FALSE, "passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); diff --git a/src/Common/EncryptionThreadPool.c b/src/Common/EncryptionThreadPool.c index f213ea34..1ec78139 100644 --- a/src/Common/EncryptionThreadPool.c +++ b/src/Common/EncryptionThreadPool.c @@ -173,6 +173,11 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg) workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize()); break; + case SHA256: + derive_key_sha256 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE, + workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize()); + break; + default: TC_THROW_FATAL_EXCEPTION; } diff --git a/src/Common/Random.c b/src/Common/Random.c index 445e8f24..54192cb2 100644 --- a/src/Common/Random.c +++ b/src/Common/Random.c @@ -210,6 +210,7 @@ BOOL Randmix () WHIRLPOOL_CTX wctx; RMD160_CTX rctx; sha512_ctx sctx; + sha256_ctx s256ctx; int poolIndex, digestIndex, digestSize; switch (HashFunction) @@ -222,6 +223,10 @@ BOOL Randmix () digestSize = SHA512_DIGESTSIZE; break; + case SHA256: + digestSize = SHA256_DIGESTSIZE; + break; + case WHIRLPOOL: digestSize = WHIRLPOOL_DIGESTSIZE; break; @@ -250,6 +255,12 @@ BOOL Randmix () sha512_end (hashOutputBuffer, &sctx); break; + case SHA256: + sha256_begin (&s256ctx); + sha256_hash (pRandPool, RNG_POOL_SIZE, &s256ctx); + sha256_end (hashOutputBuffer, &s256ctx); + break; + case WHIRLPOOL: WHIRLPOOL_init (&wctx); WHIRLPOOL_add (pRandPool, RNG_POOL_SIZE * 8, &wctx); @@ -280,6 +291,10 @@ BOOL Randmix () burn (&sctx, sizeof(sctx)); break; + case SHA256: + burn (&s256ctx, sizeof(s256ctx)); + break; + case WHIRLPOOL: burn (&wctx, sizeof(wctx)); break; diff --git a/src/Common/Resource.h b/src/Common/Resource.h index 72844e29..9d04e444 100644 --- a/src/Common/Resource.h +++ b/src/Common/Resource.h @@ -43,6 +43,22 @@ #define IDD_NEW_TOKEN_KEYFILE 539 #define IDD_RANDOM_POOL_ENRICHMENT 540 #define IDI_TRUECRYPT_MOUNTED_ICON 541 +#define IDR_BOOT_SECTOR_SHA2 542 +#define IDR_BOOT_SECTOR_AES_SHA2 543 +#define IDR_BOOT_SECTOR_SERPENT_SHA2 544 +#define IDR_BOOT_SECTOR_TWOFISH_SHA2 545 +#define IDR_BOOT_LOADER_SHA2 546 +#define IDR_BOOT_LOADER_AES_SHA2 547 +#define IDR_BOOT_LOADER_SERPENT_SHA2 548 +#define IDR_BOOT_LOADER_TWOFISH_SHA2 549 +#define IDR_RESCUE_BOOT_SECTOR_SHA2 550 +#define IDR_RESCUE_BOOT_SECTOR_AES_SHA2 551 +#define IDR_RESCUE_BOOT_SECTOR_SERPENT_SHA2 552 +#define IDR_RESCUE_BOOT_SECTOR_TWOFISH_SHA2 553 +#define IDR_RESCUE_LOADER_SHA2 554 +#define IDR_RESCUE_LOADER_AES_SHA2 555 +#define IDR_RESCUE_LOADER_SERPENT_SHA2 556 +#define IDR_RESCUE_LOADER_TWOFISH_SHA2 557 #define IDC_HW_AES_LABEL_LINK 5000 #define IDC_HW_AES 5001 #define IDC_PARALLELIZATION_LABEL_LINK 5002 diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c index 26fed73d..3d50d3d8 100644 --- a/src/Driver/DriveFilter.c +++ b/src/Driver/DriveFilter.c @@ -1621,6 +1621,7 @@ void GetBootEncryptionAlgorithmName (PIRP irp, PIO_STACK_LOCATION irpSp) { GetBootEncryptionAlgorithmNameRequest *request = (GetBootEncryptionAlgorithmNameRequest *) irp->AssociatedIrp.SystemBuffer; EAGetName (request->BootEncryptionAlgorithmName, BootDriveFilterExtension->Queue.CryptoInfo->ea); + HashGetName2 (request->BootPrfAlgorithmName, BootDriveFilterExtension->Queue.CryptoInfo->pkcs5); irp->IoStatus.Information = sizeof (GetBootEncryptionAlgorithmNameRequest); irp->IoStatus.Status = STATUS_SUCCESS; -- cgit v1.2.3