"Fossies" - the Fresh Open Source Software Archive

Member "src/Common/Volumes.c" (10 Oct 2018, 40862 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Volumes.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.21_Source_vs_1.22_Source.

    1 /*
    2  Legal Notice: Some portions of the source code contained in this file were
    3  derived from the source code of TrueCrypt 7.1a, which is
    4  Copyright (c) 2003-2012 TrueCrypt Developers Association and which is
    5  governed by the TrueCrypt License 3.0, also from the source code of
    6  Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux
    7  and which is governed by the 'License Agreement for Encryption for the Masses'
    8  Modifications and additions to the original source code (contained in this file)
    9  and all other portions of this file are Copyright (c) 2013-2017 IDRIX
   10  and are governed by the Apache License 2.0 the full text of which is
   11  contained in the file License.txt included in VeraCrypt binary and source
   12  code distribution packages. */
   13 
   14 #include "Tcdefs.h"
   15 #if !defined(_UEFI)
   16 #if !defined(TC_WINDOWS_BOOT) 
   17 #include <fcntl.h>
   18 #include <sys/types.h>
   19 #include <sys/stat.h>
   20 #include <time.h>
   21 #include "EncryptionThreadPool.h"
   22 #endif
   23 
   24 #include <stddef.h>
   25 #include <string.h>
   26 #include <io.h>
   27 
   28 #ifndef DEVICE_DRIVER
   29 #include "Random.h"
   30 #endif
   31 #endif // !defined(_UEFI)
   32 
   33 #include "Crc.h"
   34 #include "Crypto.h"
   35 #include "Endian.h"
   36 #include "Volumes.h"
   37 #include "Pkcs5.h"
   38 
   39 #if defined(_WIN32) && !defined(_UEFI)
   40 #include <Strsafe.h>
   41 #include "../Boot/Windows/BootCommon.h"
   42 #endif
   43 
   44 /* Volume header v5 structure (used since TrueCrypt 7.0): */
   45 //
   46 // Offset   Length  Description
   47 // ------------------------------------------
   48 // Unencrypted:
   49 // 0        64      Salt
   50 // Encrypted:
   51 // 64       4       ASCII string 'VERA'
   52 // 68       2       Header version
   53 // 70       2       Required program version
   54 // 72       4       CRC-32 checksum of the (decrypted) bytes 256-511
   55 // 76       16      Reserved (must contain zeroes)
   56 // 92       8       Size of hidden volume in bytes (0 = normal volume)
   57 // 100      8       Size of the volume in bytes (identical with field 92 for hidden volumes, valid if field 70 >= 0x600 or flag bit 0 == 1)
   58 // 108      8       Byte offset of the start of the master key scope (valid if field 70 >= 0x600 or flag bit 0 == 1)
   59 // 116      8       Size of the encrypted area within the master key scope (valid if field 70 >= 0x600 or flag bit 0 == 1)
   60 // 124      4       Flags: bit 0 set = system encryption; bit 1 set = non-system in-place encryption, bits 2-31 are reserved (set to zero)
   61 // 128      4       Sector size in bytes
   62 // 132      120     Reserved (must contain zeroes)
   63 // 252      4       CRC-32 checksum of the (decrypted) bytes 64-251
   64 // 256      256     Concatenated primary master key(s) and secondary master key(s) (XTS mode)
   65 
   66 
   67 /* Deprecated/legacy volume header v4 structure (used by TrueCrypt 6.x): */
   68 //
   69 // Offset   Length  Description
   70 // ------------------------------------------
   71 // Unencrypted:
   72 // 0        64      Salt
   73 // Encrypted:
   74 // 64       4       ASCII string 'VERA'
   75 // 68       2       Header version
   76 // 70       2       Required program version
   77 // 72       4       CRC-32 checksum of the (decrypted) bytes 256-511
   78 // 76       16      Reserved (must contain zeroes)
   79 // 92       8       Size of hidden volume in bytes (0 = normal volume)
   80 // 100      8       Size of the volume in bytes (identical with field 92 for hidden volumes, valid if field 70 >= 0x600 or flag bit 0 == 1)
   81 // 108      8       Byte offset of the start of the master key scope (valid if field 70 >= 0x600 or flag bit 0 == 1)
   82 // 116      8       Size of the encrypted area within the master key scope (valid if field 70 >= 0x600 or flag bit 0 == 1)
   83 // 124      4       Flags: bit 0 set = system encryption; bit 1 set = non-system in-place encryption, bits 2-31 are reserved
   84 // 128      124     Reserved (must contain zeroes)
   85 // 252      4       CRC-32 checksum of the (decrypted) bytes 64-251
   86 // 256      256     Concatenated primary master key(s) and secondary master key(s) (XTS mode)
   87 
   88 
   89 /* Deprecated/legacy volume header v3 structure (used by TrueCrypt 5.x): */
   90 //
   91 // Offset   Length  Description
   92 // ------------------------------------------
   93 // Unencrypted:
   94 // 0        64      Salt
   95 // Encrypted:
   96 // 64       4       ASCII string 'VERA'
   97 // 68       2       Header version
   98 // 70       2       Required program version
   99 // 72       4       CRC-32 checksum of the (decrypted) bytes 256-511
  100 // 76       8       Volume creation time
  101 // 84       8       Header creation time
  102 // 92       8       Size of hidden volume in bytes (0 = normal volume)
  103 // 100      8       Size of the volume in bytes (identical with field 92 for hidden volumes)
  104 // 108      8       Start byte offset of the encrypted area of the volume
  105 // 116      8       Size of the encrypted area of the volume in bytes
  106 // 124      132     Reserved (must contain zeroes)
  107 // 256      256     Concatenated primary master key(s) and secondary master key(s) (XTS mode)
  108 
  109 
  110 /* Deprecated/legacy volume header v2 structure (used before TrueCrypt 5.0): */
  111 //
  112 // Offset   Length  Description
  113 // ------------------------------------------
  114 // Unencrypted:
  115 // 0        64      Salt
  116 // Encrypted:
  117 // 64       4       ASCII string 'VERA'
  118 // 68       2       Header version
  119 // 70       2       Required program version
  120 // 72       4       CRC-32 checksum of the (decrypted) bytes 256-511
  121 // 76       8       Volume creation time
  122 // 84       8       Header creation time
  123 // 92       8       Size of hidden volume in bytes (0 = normal volume)
  124 // 100      156     Reserved (must contain zeroes)
  125 // 256      32      For LRW (deprecated/legacy), secondary key
  126 //                  For CBC (deprecated/legacy), data used to generate IV and whitening values
  127 // 288      224     Master key(s)
  128 
  129 
  130 
  131 uint16 GetHeaderField16 (byte *header, int offset)
  132 {
  133     return BE16 (*(uint16 *) (header + offset));
  134 }
  135 
  136 
  137 uint32 GetHeaderField32 (byte *header, int offset)
  138 {
  139     return BE32 (*(uint32 *) (header + offset));
  140 }
  141 
  142 
  143 UINT64_STRUCT GetHeaderField64 (byte *header, int offset)
  144 {
  145     UINT64_STRUCT uint64Struct;
  146 
  147 #ifndef TC_NO_COMPILER_INT64
  148     uint64Struct.Value = BE64 (*(uint64 *) (header + offset));
  149 #else
  150     uint64Struct.HighPart = BE32 (*(uint32 *) (header + offset));
  151     uint64Struct.LowPart = BE32 (*(uint32 *) (header + offset + 4));
  152 #endif
  153     return uint64Struct;
  154 }
  155 
  156 
  157 #ifndef TC_WINDOWS_BOOT
  158 
  159 typedef struct
  160 {
  161     char DerivedKey[MASTER_KEYDATA_SIZE];
  162     BOOL Free;
  163     LONG KeyReady;
  164     int Pkcs5Prf;
  165 } KeyDerivationWorkItem;
  166 
  167 
  168 BOOL ReadVolumeHeaderRecoveryMode = FALSE;
  169 
  170 int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int selected_pkcs5_prf, int pim, BOOL truecryptMode, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
  171 {
  172     char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
  173     CRYPTOPP_ALIGN_DATA(16) KEY_INFO keyInfo;
  174     PCRYPTO_INFO cryptoInfo;
  175     CRYPTOPP_ALIGN_DATA(16) char dk[MASTER_KEYDATA_SIZE];
  176     int enqPkcs5Prf, pkcs5_prf;
  177     uint16 headerVersion;
  178     int status = ERR_PARAMETER_INCORRECT;
  179     int primaryKeyOffset;
  180     int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1;
  181 #if !defined(_UEFI)
  182     TC_EVENT keyDerivationCompletedEvent;
  183     TC_EVENT noOutstandingWorkItemEvent;
  184     KeyDerivationWorkItem *keyDerivationWorkItems;
  185     KeyDerivationWorkItem *item;
  186     size_t encryptionThreadCount = GetEncryptionThreadCount();
  187     LONG outstandingWorkItemCount = 0;
  188     int i;
  189 #endif
  190     size_t queuedWorkItems = 0;
  191 
  192     // if no PIM specified, use default value
  193     if (pim < 0)
  194         pim = 0;
  195 
  196     if (truecryptMode)
  197     {
  198         // SHA-256 not supported in TrueCrypt mode
  199         if (selected_pkcs5_prf == SHA256)
  200             return ERR_PARAMETER_INCORRECT;
  201         pkcs5PrfCount--; // don't count SHA-256 in case of TrueCrypt mode
  202     }
  203 
  204     if (retHeaderCryptoInfo != NULL)
  205     {
  206         cryptoInfo = retHeaderCryptoInfo;
  207     }
  208     else
  209     {
  210       if (!retInfo)
  211          return ERR_PARAMETER_INCORRECT;
  212 
  213         cryptoInfo = *retInfo = crypto_open ();
  214         if (cryptoInfo == NULL)
  215             return ERR_OUTOFMEMORY;
  216     }
  217 #if !defined(_UEFI)
  218     /* use thread pool only if no PRF was specified */
  219     if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
  220     {
  221         keyDerivationWorkItems = TCalloc (sizeof (KeyDerivationWorkItem) * pkcs5PrfCount);
  222         if (!keyDerivationWorkItems)
  223             return ERR_OUTOFMEMORY;
  224 
  225         for (i = 0; i < pkcs5PrfCount; ++i)
  226             keyDerivationWorkItems[i].Free = TRUE;
  227 
  228 #ifdef DEVICE_DRIVER
  229         KeInitializeEvent (&keyDerivationCompletedEvent, SynchronizationEvent, FALSE);
  230         KeInitializeEvent (&noOutstandingWorkItemEvent, SynchronizationEvent, TRUE);
  231 #else
  232         keyDerivationCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
  233         if (!keyDerivationCompletedEvent)
  234         {
  235             TCfree (keyDerivationWorkItems);
  236             return ERR_OUTOFMEMORY;
  237         }
  238 
  239         noOutstandingWorkItemEvent = CreateEvent (NULL, FALSE, TRUE, NULL);
  240         if (!noOutstandingWorkItemEvent)
  241         {
  242             CloseHandle (keyDerivationCompletedEvent);
  243             TCfree (keyDerivationWorkItems);
  244             return ERR_OUTOFMEMORY;
  245         }
  246 #endif
  247     }
  248 
  249 #if !defined(DEVICE_DRIVER) 
  250     VirtualLock (&keyInfo, sizeof (keyInfo));
  251     VirtualLock (&dk, sizeof (dk));
  252     VirtualLock (&header, sizeof (header));
  253 #endif
  254 #endif //  !defined(_UEFI)
  255 
  256     crypto_loadkey (&keyInfo, password->Text, (int) password->Length);
  257 
  258     // PKCS5 is used to derive the primary header key(s) and secondary header key(s) (XTS mode) from the password
  259     memcpy (keyInfo.salt, encryptedHeader + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE);
  260 
  261     // Test all available PKCS5 PRFs
  262     for (enqPkcs5Prf = FIRST_PRF_ID; enqPkcs5Prf <= LAST_PRF_ID || queuedWorkItems > 0; ++enqPkcs5Prf)
  263     {
  264         // if a PRF is specified, we skip all other PRFs
  265         if (selected_pkcs5_prf != 0 && enqPkcs5Prf != selected_pkcs5_prf)
  266             continue;
  267 
  268         // skip SHA-256 in case of TrueCrypt mode
  269         if (truecryptMode && (enqPkcs5Prf == SHA256))
  270             continue;
  271 #if !defined(_UEFI)
  272         if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
  273         {
  274             // Enqueue key derivation on thread pool
  275             if (queuedWorkItems < encryptionThreadCount && enqPkcs5Prf <= LAST_PRF_ID)
  276             {
  277                 for (i = 0; i < pkcs5PrfCount; ++i)
  278                 {
  279                     item = &keyDerivationWorkItems[i];
  280                     if (item->Free)
  281                     {
  282                         item->Free = FALSE;
  283                         item->KeyReady = FALSE;
  284                         item->Pkcs5Prf = enqPkcs5Prf;
  285 
  286                         EncryptionThreadPoolBeginKeyDerivation (&keyDerivationCompletedEvent, &noOutstandingWorkItemEvent,
  287                             &item->KeyReady, &outstandingWorkItemCount, enqPkcs5Prf, keyInfo.userKey,
  288                             keyInfo.keyLength, keyInfo.salt, get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot), item->DerivedKey);
  289 
  290                         ++queuedWorkItems;
  291                         break;
  292                     }
  293                 }
  294 
  295                 if (enqPkcs5Prf < LAST_PRF_ID)
  296                     continue;
  297             }
  298             else
  299                 --enqPkcs5Prf;
  300 
  301             // Wait for completion of a key derivation
  302             while (queuedWorkItems > 0)
  303             {
  304                 for (i = 0; i < pkcs5PrfCount; ++i)
  305                 {
  306                     item = &keyDerivationWorkItems[i];
  307                     if (!item->Free && InterlockedExchangeAdd (&item->KeyReady, 0) == TRUE)
  308                     {
  309                         pkcs5_prf = item->Pkcs5Prf;
  310                         keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, truecryptMode, bBoot);
  311                         memcpy (dk, item->DerivedKey, sizeof (dk));
  312 
  313                         item->Free = TRUE;
  314                         --queuedWorkItems;
  315                         goto KeyReady;
  316                     }
  317                 }
  318 
  319                 if (queuedWorkItems > 0)
  320                     TC_WAIT_EVENT (keyDerivationCompletedEvent);
  321             }
  322             continue;
  323 KeyReady:   ;
  324         }
  325         else
  326 #endif // !defined(_UEFI)
  327         {
  328             pkcs5_prf = enqPkcs5Prf;
  329             keyInfo.noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot);
  330 
  331             switch (pkcs5_prf)
  332             {
  333             case RIPEMD160:
  334                 derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
  335                     PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
  336                 break;
  337 
  338             case SHA512:
  339                 derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
  340                     PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
  341                 break;
  342 
  343             case WHIRLPOOL:
  344                 derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
  345                     PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
  346                 break;
  347 
  348             case SHA256:
  349                 derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
  350                     PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
  351                 break;
  352 
  353             case STREEBOG:
  354                 derive_key_streebog(keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
  355                     PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
  356                 break;
  357             default:
  358                 // Unknown/wrong ID
  359                 TC_THROW_FATAL_EXCEPTION;
  360             }
  361         }
  362 
  363         // Test all available modes of operation
  364         for (cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
  365             cryptoInfo->mode <= LAST_MODE_OF_OPERATION;
  366             cryptoInfo->mode++)
  367         {
  368             switch (cryptoInfo->mode)
  369             {
  370 
  371             default:
  372                 primaryKeyOffset = 0;
  373             }
  374 
  375             // Test all available encryption algorithms
  376             for (cryptoInfo->ea = EAGetFirst ();
  377                 cryptoInfo->ea != 0;
  378                 cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
  379             {
  380                 int blockSize;
  381 
  382                 if (!EAIsModeSupported (cryptoInfo->ea, cryptoInfo->mode))
  383                     continue;   // This encryption algorithm has never been available with this mode of operation
  384 
  385                 blockSize = CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea));
  386 
  387                 status = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
  388                 if (status == ERR_CIPHER_INIT_FAILURE)
  389                     goto err;
  390 
  391                 // Init objects related to the mode of operation
  392 
  393                 if (cryptoInfo->mode == XTS)
  394                 {
  395                     // Copy the secondary key (if cascade, multiple concatenated)
  396                     memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
  397 
  398                     // Secondary key schedule
  399                     if (!EAInitMode (cryptoInfo))
  400                     {
  401                         status = ERR_MODE_INIT_FAILED;
  402                         goto err;
  403                     }
  404                 }
  405                 else
  406                 {
  407                     continue;
  408                 }
  409 
  410                 // Copy the header for decryption
  411                 memcpy (header, encryptedHeader, sizeof (header));
  412 
  413                 // Try to decrypt header
  414 
  415                 DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
  416 
  417                 // Magic 'VERA' or 'TRUE' depending if we are in TrueCrypt mode or not
  418                 if ((truecryptMode && GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x54525545)
  419                     || (!truecryptMode && GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241)
  420                     )
  421                     continue;
  422 
  423                 // Header version
  424                 headerVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION);
  425 
  426                 if (headerVersion > VOLUME_HEADER_VERSION)
  427                 {
  428                     status = ERR_NEW_VERSION_REQUIRED;
  429                     goto err;
  430                 }
  431 
  432                 // Check CRC of the header fields
  433                 if (!ReadVolumeHeaderRecoveryMode
  434                     && headerVersion >= 4
  435                     && GetHeaderField32 (header, TC_HEADER_OFFSET_HEADER_CRC) != GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
  436                     continue;
  437 
  438                 // Required program version
  439                 cryptoInfo->RequiredProgramVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_REQUIRED_VERSION);
  440                 if (truecryptMode)
  441                 {
  442                     if (cryptoInfo->RequiredProgramVersion < 0x600 || cryptoInfo->RequiredProgramVersion > 0x71a)
  443                     {
  444                         status = ERR_UNSUPPORTED_TRUECRYPT_FORMAT | (((int)cryptoInfo->RequiredProgramVersion) << 16);
  445                         goto err;
  446                     }
  447                     cryptoInfo->LegacyVolume = FALSE;
  448                 }
  449                 else
  450                     cryptoInfo->LegacyVolume = cryptoInfo->RequiredProgramVersion < 0x10b;
  451 
  452                 // Check CRC of the key set
  453                 if (!ReadVolumeHeaderRecoveryMode
  454                     && GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
  455                     continue;
  456 
  457                 // Now we have the correct password, cipher, hash algorithm, and volume type
  458 
  459                 // Check the version required to handle this volume
  460                 if (!truecryptMode && (cryptoInfo->RequiredProgramVersion > VERSION_NUM))
  461                 {
  462                     status = ERR_NEW_VERSION_REQUIRED;
  463                     goto err;
  464                 }
  465 
  466                 // Header version
  467                 cryptoInfo->HeaderVersion = headerVersion;
  468 
  469                 // Volume creation time (legacy)
  470                 cryptoInfo->volume_creation_time = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_CREATION_TIME).Value;
  471 
  472                 // Header creation time (legacy)
  473                 cryptoInfo->header_creation_time = GetHeaderField64 (header, TC_HEADER_OFFSET_MODIFICATION_TIME).Value;
  474 
  475                 // Hidden volume size (if any)
  476                 cryptoInfo->hiddenVolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE).Value;
  477 
  478                 // Hidden volume status
  479                 cryptoInfo->hiddenVolume = (cryptoInfo->hiddenVolumeSize != 0);
  480 
  481                 // Volume size
  482                 cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);
  483 
  484                 // Encrypted area size and length
  485                 cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
  486                 cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);
  487 
  488                 // Flags
  489                 cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);
  490 
  491                 // Sector size
  492                 if (headerVersion >= 5)
  493                     cryptoInfo->SectorSize = GetHeaderField32 (header, TC_HEADER_OFFSET_SECTOR_SIZE);
  494                 else
  495                     cryptoInfo->SectorSize = TC_SECTOR_SIZE_LEGACY;
  496 
  497                 if (cryptoInfo->SectorSize < TC_MIN_VOLUME_SECTOR_SIZE
  498                     || cryptoInfo->SectorSize > TC_MAX_VOLUME_SECTOR_SIZE
  499                     || cryptoInfo->SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
  500                 {
  501                     status = ERR_PARAMETER_INCORRECT;
  502                     goto err;
  503                 }
  504 
  505                 // Preserve scheduled header keys if requested
  506                 if (retHeaderCryptoInfo)
  507                 {
  508                     if (retInfo == NULL)
  509                     {
  510                         cryptoInfo->pkcs5 = pkcs5_prf;
  511                         cryptoInfo->noIterations = keyInfo.noIterations;
  512                         cryptoInfo->bTrueCryptMode = truecryptMode;
  513                         cryptoInfo->volumePim = pim;
  514                         goto ret;
  515                     }
  516 
  517                     cryptoInfo = *retInfo = crypto_open ();
  518                     if (cryptoInfo == NULL)
  519                     {
  520                         status = ERR_OUTOFMEMORY;
  521                         goto err;
  522                     }
  523 
  524                     memcpy (cryptoInfo, retHeaderCryptoInfo, sizeof (*cryptoInfo));
  525                 }
  526 
  527                 // Master key data
  528                 memcpy (keyInfo.master_keydata, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE);
  529                 memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
  530 
  531                 // PKCS #5
  532                 memcpy (cryptoInfo->salt, keyInfo.salt, PKCS5_SALT_SIZE);
  533                 cryptoInfo->pkcs5 = pkcs5_prf;
  534                 cryptoInfo->noIterations = keyInfo.noIterations;
  535                 cryptoInfo->bTrueCryptMode = truecryptMode;
  536                 cryptoInfo->volumePim = pim;
  537 
  538                 // Init the cipher with the decrypted master key
  539                 status = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
  540                 if (status == ERR_CIPHER_INIT_FAILURE)
  541                     goto err;
  542 
  543                 switch (cryptoInfo->mode)
  544                 {
  545 
  546                 default:
  547                     // The secondary master key (if cascade, multiple concatenated)
  548                     memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
  549 
  550                 }
  551 
  552                 if (!EAInitMode (cryptoInfo))
  553                 {
  554                     status = ERR_MODE_INIT_FAILED;
  555                     goto err;
  556                 }
  557 
  558                 status = ERR_SUCCESS;
  559                 goto ret;
  560             }
  561         }
  562     }
  563     status = ERR_PASSWORD_WRONG;
  564 
  565 err:
  566     if (cryptoInfo != retHeaderCryptoInfo)
  567     {
  568         crypto_close(cryptoInfo);
  569         *retInfo = NULL;
  570     }
  571 
  572 ret:
  573     burn (&keyInfo, sizeof (keyInfo));
  574     burn (dk, sizeof(dk));
  575     burn (header, sizeof(header));
  576 
  577 #if !defined(DEVICE_DRIVER) && !defined(_UEFI)
  578     VirtualUnlock (&keyInfo, sizeof (keyInfo));
  579     VirtualUnlock (&dk, sizeof (dk));
  580     VirtualUnlock (&header, sizeof (header));
  581 #endif
  582 
  583 #if !defined(_UEFI)
  584     if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1))
  585     {
  586         TC_WAIT_EVENT (noOutstandingWorkItemEvent);
  587 
  588         burn (keyDerivationWorkItems, sizeof (KeyDerivationWorkItem) * pkcs5PrfCount);
  589         TCfree (keyDerivationWorkItems);
  590 
  591 #if !defined(DEVICE_DRIVER) 
  592         CloseHandle (keyDerivationCompletedEvent);
  593         CloseHandle (noOutstandingWorkItemEvent);
  594 #endif
  595     }
  596 #endif
  597     return status;
  598 }
  599 
  600 #if defined(_WIN32) && !defined(_UEFI)
  601 void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderSize, byte* fingerprint)
  602 {
  603     // compute Whirlpool+SHA512 fingerprint of bootloader including MBR
  604     // we skip user configuration fields:
  605     // TC_BOOT_SECTOR_PIM_VALUE_OFFSET = 400
  606     // TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET = 402
  607     //  => TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE = 4
  608     // TC_BOOT_SECTOR_USER_MESSAGE_OFFSET     = 406
  609     //  => TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH = 24
  610     // TC_BOOT_SECTOR_USER_CONFIG_OFFSET      = 438
  611     //
  612     // 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
  613 
  614     WHIRLPOOL_CTX whirlpool;
  615     sha512_ctx sha2;
  616 
  617     WHIRLPOOL_init (&whirlpool);
  618     sha512_begin (&sha2);
  619 
  620     WHIRLPOOL_add (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &whirlpool);
  621     sha512_hash (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &sha2);
  622 
  623     WHIRLPOOL_add (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)), &whirlpool);
  624     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);
  625 
  626     WHIRLPOOL_add (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &whirlpool);
  627     sha512_hash (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &sha2);
  628 
  629     WHIRLPOOL_finalize (&whirlpool, fingerprint);
  630     sha512_end (&fingerprint [WHIRLPOOL_DIGESTSIZE], &sha2);
  631 }
  632 #endif
  633 
  634 #else // TC_WINDOWS_BOOT
  635 
  636 int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
  637 {
  638 #ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
  639     char dk[32 * 2];            // 2 * 256-bit key
  640 #else
  641     char dk[32 * 2 * 3];        // 6 * 256-bit key
  642 #endif
  643 
  644     PCRYPTO_INFO cryptoInfo;
  645     int status = ERR_SUCCESS;
  646     uint32 iterations = pim;
  647     iterations <<= 16;
  648     iterations |= bBoot;
  649 
  650     if (retHeaderCryptoInfo != NULL)
  651         cryptoInfo = retHeaderCryptoInfo;
  652     else
  653         cryptoInfo = *retInfo = crypto_open ();
  654 
  655     // PKCS5 PRF
  656 #ifdef TC_WINDOWS_BOOT_SHA2
  657     derive_key_sha256 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
  658         PKCS5_SALT_SIZE, iterations, dk, sizeof (dk));
  659 #else
  660     derive_key_ripemd160 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
  661         PKCS5_SALT_SIZE, iterations, dk, sizeof (dk));
  662 #endif
  663 
  664     // Mode of operation
  665     cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
  666 
  667 #ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
  668     cryptoInfo->ea = 1;
  669 #else
  670     // Test all available encryption algorithms
  671     for (cryptoInfo->ea = EAGetFirst (); cryptoInfo->ea != 0; cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
  672 #endif
  673     {
  674 #ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
  675     #if defined (TC_WINDOWS_BOOT_SERPENT)
  676         serpent_set_key (dk, cryptoInfo->ks);
  677     #elif defined (TC_WINDOWS_BOOT_TWOFISH)
  678         twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk);
  679     #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
  680         camellia_set_key (dk, cryptoInfo->ks);
  681     #else
  682         status = EAInit (dk, cryptoInfo->ks);
  683         if (status == ERR_CIPHER_INIT_FAILURE)
  684             goto err;
  685     #endif
  686 #else
  687         status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks);
  688         if (status == ERR_CIPHER_INIT_FAILURE)
  689             goto err;
  690 #endif
  691         // Secondary key schedule
  692 #ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
  693     #if defined (TC_WINDOWS_BOOT_SERPENT)
  694         serpent_set_key (dk + 32, cryptoInfo->ks2);
  695     #elif defined (TC_WINDOWS_BOOT_TWOFISH)
  696         twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32));
  697     #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
  698         camellia_set_key (dk + 32, cryptoInfo->ks2);
  699     #else
  700         EAInit (dk + 32, cryptoInfo->ks2);
  701     #endif
  702 #else
  703         EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
  704 #endif
  705 
  706         // Try to decrypt header
  707         DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
  708 
  709         // Check magic 'VERA' and CRC-32 of header fields and master keydata
  710         if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241
  711             || (GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION) >= 4 && GetHeaderField32 (header, TC_HEADER_OFFSET_HEADER_CRC) != GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
  712             || GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
  713         {
  714             EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
  715 #ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
  716             status = ERR_PASSWORD_WRONG;
  717             goto err;
  718 #else
  719             continue;
  720 #endif
  721         }
  722 
  723         // Header decrypted
  724         status = 0;
  725 
  726         // Hidden volume status
  727         cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE);
  728         cryptoInfo->hiddenVolume = (cryptoInfo->VolumeSize.LowPart != 0 || cryptoInfo->VolumeSize.HighPart != 0);
  729 
  730         // Volume size
  731         cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);
  732 
  733         // Encrypted area size and length
  734         cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
  735         cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);
  736 
  737         // Flags
  738         cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);
  739 
  740 #ifdef TC_WINDOWS_BOOT_SHA2
  741         cryptoInfo->pkcs5 = SHA256;
  742 #else
  743         cryptoInfo->pkcs5 = RIPEMD160;
  744 #endif
  745 
  746         memcpy (dk, header + HEADER_MASTER_KEYDATA_OFFSET, sizeof (dk));
  747         EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
  748 
  749         if (retHeaderCryptoInfo)
  750             goto ret;
  751 
  752         // Init the encryption algorithm with the decrypted master key
  753 #ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
  754     #if defined (TC_WINDOWS_BOOT_SERPENT)
  755         serpent_set_key (dk, cryptoInfo->ks);
  756     #elif defined (TC_WINDOWS_BOOT_TWOFISH)
  757         twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk);
  758     #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
  759         camellia_set_key (dk, cryptoInfo->ks);
  760     #else
  761         status = EAInit (dk, cryptoInfo->ks);
  762         if (status == ERR_CIPHER_INIT_FAILURE)
  763             goto err;
  764     #endif
  765 #else
  766         status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks);
  767         if (status == ERR_CIPHER_INIT_FAILURE)
  768             goto err;
  769 #endif
  770 
  771         // The secondary master key (if cascade, multiple concatenated)
  772 #ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
  773     #if defined (TC_WINDOWS_BOOT_SERPENT)
  774         serpent_set_key (dk + 32, cryptoInfo->ks2);
  775     #elif defined (TC_WINDOWS_BOOT_TWOFISH)
  776         twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32));
  777     #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
  778         camellia_set_key (dk + 32, cryptoInfo->ks2);
  779     #else
  780         EAInit (dk + 32, cryptoInfo->ks2);
  781     #endif
  782 #else
  783         EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
  784 #endif
  785         goto ret;
  786     }
  787 
  788     status = ERR_PASSWORD_WRONG;
  789 
  790 err:
  791     if (cryptoInfo != retHeaderCryptoInfo)
  792     {
  793         crypto_close(cryptoInfo);
  794         *retInfo = NULL;
  795     }
  796 
  797 ret:
  798     burn (dk, sizeof(dk));
  799     return status;
  800 }
  801 
  802 #endif // TC_WINDOWS_BOOT
  803 
  804 
  805 #if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT)
  806 
  807 #ifdef VOLFORMAT
  808 #   include "../Format/TcFormat.h"
  809 #   include "Dlgcode.h"
  810 #endif
  811 
  812 // Creates a volume header in memory
  813 #if defined(_UEFI)
  814 int CreateVolumeHeaderInMemory(BOOL bBoot, char *header, int ea, int mode, Password *password,
  815     int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo,
  816     unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize,
  817     unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode)
  818 #else
  819 int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, int mode, Password *password,
  820            int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo,
  821            unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize,
  822            unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode)
  823 #endif // !defined(_UEFI)
  824 {
  825     unsigned char *p = (unsigned char *) header;
  826     static CRYPTOPP_ALIGN_DATA(16) KEY_INFO keyInfo;
  827 
  828     int nUserKeyLen = password? password->Length : 0;
  829     PCRYPTO_INFO cryptoInfo = crypto_open ();
  830     static char dk[MASTER_KEYDATA_SIZE];
  831     int x;
  832     int retVal = 0;
  833     int primaryKeyOffset;
  834 
  835     if (cryptoInfo == NULL)
  836         return ERR_OUTOFMEMORY;
  837 
  838     // if no PIM specified, use default value
  839     if (pim < 0)
  840         pim = 0;
  841 
  842     memset (header, 0, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
  843 #if !defined(_UEFI)
  844     VirtualLock (&keyInfo, sizeof (keyInfo));
  845     VirtualLock (&dk, sizeof (dk));
  846 #endif // !defined(_UEFI)
  847 
  848     /* Encryption setup */
  849 
  850     if (masterKeydata == NULL)
  851     {
  852         // We have no master key data (creating a new volume) so we'll use the TrueCrypt RNG to generate them
  853 
  854         int bytesNeeded;
  855 
  856         switch (mode)
  857         {
  858 
  859         default:
  860             bytesNeeded = EAGetKeySize (ea) * 2;    // Size of primary + secondary key(s)
  861         }
  862 
  863 #if !defined(_UEFI)
  864         if (!RandgetBytes (hwndDlg, keyInfo.master_keydata, bytesNeeded, TRUE))
  865 #else
  866         if (!RandgetBytes(keyInfo.master_keydata, bytesNeeded, TRUE))
  867 #endif
  868         {
  869             crypto_close (cryptoInfo);
  870             retVal = ERR_CIPHER_INIT_WEAK_KEY;
  871             goto err;
  872         }
  873     }
  874     else
  875     {
  876         // We already have existing master key data (the header is being re-encrypted)
  877         memcpy (keyInfo.master_keydata, masterKeydata, MASTER_KEYDATA_SIZE);
  878     }
  879 
  880     // User key
  881     if (password)
  882     {
  883         memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
  884         keyInfo.keyLength = nUserKeyLen;
  885         keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, pim, FALSE, bBoot);
  886     }
  887     else
  888     {
  889         keyInfo.keyLength = 0;
  890         keyInfo.noIterations = 0;
  891     }
  892 
  893     // User selected encryption algorithm
  894     cryptoInfo->ea = ea;
  895 
  896     // User selected PRF
  897     cryptoInfo->pkcs5 = pkcs5_prf;
  898     cryptoInfo->bTrueCryptMode = FALSE;
  899     cryptoInfo->noIterations = keyInfo.noIterations;
  900     cryptoInfo->volumePim = pim;
  901 
  902     // Mode of operation
  903     cryptoInfo->mode = mode;
  904 
  905     // Salt for header key derivation
  906 #if !defined(_UEFI)
  907     if (!RandgetBytes(hwndDlg, keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
  908 #else
  909     if (!RandgetBytes(keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
  910 #endif
  911     {
  912         crypto_close (cryptoInfo);
  913         retVal = ERR_CIPHER_INIT_WEAK_KEY; 
  914         goto err;
  915     }
  916 
  917     if (password)
  918     {
  919         // PBKDF2 (PKCS5) is used to derive primary header key(s) and secondary header key(s) (XTS) from the password/keyfiles
  920         switch (pkcs5_prf)
  921         {
  922         case SHA512:
  923             derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
  924                 PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
  925             break;
  926 
  927         case SHA256:
  928             derive_key_sha256 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
  929                 PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
  930             break;
  931 
  932         case RIPEMD160:
  933             derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
  934                 PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
  935             break;
  936 
  937         case WHIRLPOOL:
  938             derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
  939                 PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
  940             break;
  941 
  942         case STREEBOG:
  943             derive_key_streebog(keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
  944                 PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
  945             break;
  946 
  947         default:
  948             // Unknown/wrong ID
  949             crypto_close (cryptoInfo);
  950             TC_THROW_FATAL_EXCEPTION;
  951         }
  952     }
  953     else
  954     {
  955         // generate a random key
  956 #if !defined(_UEFI)
  957         if (!RandgetBytes(hwndDlg, dk, GetMaxPkcs5OutSize(), !bWipeMode))
  958 #else
  959         if (!RandgetBytes(dk, GetMaxPkcs5OutSize(), !bWipeMode))
  960 #endif
  961         {
  962             crypto_close (cryptoInfo);
  963             retVal = ERR_CIPHER_INIT_WEAK_KEY; 
  964             goto err;
  965         }
  966     }
  967 
  968     /* Header setup */
  969 
  970     // Salt
  971     mputBytes (p, keyInfo.salt, PKCS5_SALT_SIZE);
  972 
  973     // Magic
  974     mputLong (p, 0x56455241);
  975 
  976     // Header version
  977     mputWord (p, VOLUME_HEADER_VERSION);
  978     cryptoInfo->HeaderVersion = VOLUME_HEADER_VERSION;
  979 
  980     // Required program version to handle this volume
  981     mputWord (p, requiredProgramVersion != 0 ? requiredProgramVersion : TC_VOLUME_MIN_REQUIRED_PROGRAM_VERSION);
  982 
  983     // CRC of the master key data
  984     x = GetCrc32(keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
  985     mputLong (p, x);
  986 
  987     // Reserved fields
  988     p += 2 * 8;
  989 
  990     // Size of hidden volume (if any)
  991     cryptoInfo->hiddenVolumeSize = hiddenVolumeSize;
  992     mputInt64 (p, cryptoInfo->hiddenVolumeSize);
  993 
  994     cryptoInfo->hiddenVolume = cryptoInfo->hiddenVolumeSize != 0;
  995 
  996     // Volume size
  997     cryptoInfo->VolumeSize.Value = volumeSize;
  998     mputInt64 (p, volumeSize);
  999 
 1000     // Encrypted area start
 1001     cryptoInfo->EncryptedAreaStart.Value = encryptedAreaStart;
 1002     mputInt64 (p, encryptedAreaStart);
 1003 
 1004     // Encrypted area size
 1005     cryptoInfo->EncryptedAreaLength.Value = encryptedAreaLength;
 1006     mputInt64 (p, encryptedAreaLength);
 1007 
 1008     // Flags
 1009     cryptoInfo->HeaderFlags = headerFlags;
 1010     mputLong (p, headerFlags);
 1011 
 1012     // Sector size
 1013     if (sectorSize < TC_MIN_VOLUME_SECTOR_SIZE
 1014         || sectorSize > TC_MAX_VOLUME_SECTOR_SIZE
 1015         || sectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
 1016     {
 1017         crypto_close (cryptoInfo);
 1018         TC_THROW_FATAL_EXCEPTION;
 1019     }
 1020 
 1021     cryptoInfo->SectorSize = sectorSize;
 1022     mputLong (p, sectorSize);
 1023 
 1024     // CRC of the header fields
 1025     x = GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
 1026     p = header + TC_HEADER_OFFSET_HEADER_CRC;
 1027     mputLong (p, x);
 1028 
 1029     // The master key data
 1030     memcpy (header + HEADER_MASTER_KEYDATA_OFFSET, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
 1031 
 1032 
 1033     /* Header encryption */
 1034 
 1035     switch (mode)
 1036     {
 1037 
 1038     default:
 1039         // The secondary key (if cascade, multiple concatenated)
 1040         memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
 1041         primaryKeyOffset = 0;
 1042     }
 1043 
 1044     retVal = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
 1045     if (retVal != ERR_SUCCESS)
 1046     {
 1047         crypto_close (cryptoInfo);
 1048         goto err;
 1049     }
 1050 
 1051     // Mode of operation
 1052     if (!EAInitMode (cryptoInfo))
 1053     {
 1054         crypto_close (cryptoInfo);
 1055         retVal = ERR_OUTOFMEMORY;
 1056         goto err;
 1057     }
 1058 
 1059 
 1060     // Encrypt the entire header (except the salt)
 1061     EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET,
 1062         HEADER_ENCRYPTED_DATA_SIZE,
 1063         cryptoInfo);
 1064 
 1065 
 1066     /* cryptoInfo setup for further use (disk format) */
 1067 
 1068     // Init with the master key(s)
 1069     retVal = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
 1070     if (retVal != ERR_SUCCESS)
 1071     {
 1072         crypto_close (cryptoInfo);
 1073         goto err;
 1074     }
 1075 
 1076     memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
 1077 
 1078     switch (cryptoInfo->mode)
 1079     {
 1080 
 1081     default:
 1082         // The secondary master key (if cascade, multiple concatenated)
 1083         memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
 1084     }
 1085 
 1086     // Mode of operation
 1087     if (!EAInitMode (cryptoInfo))
 1088     {
 1089         crypto_close (cryptoInfo);
 1090         retVal = ERR_OUTOFMEMORY;
 1091         goto err;
 1092     }
 1093 
 1094 
 1095 #ifdef VOLFORMAT
 1096     if (!bInPlaceEncNonSys && (showKeys || (bBoot && !masterKeydata)))
 1097     {
 1098         BOOL dots3 = FALSE;
 1099         int i, j;
 1100 
 1101         j = EAGetKeySize (ea);
 1102 
 1103         if (j > NBR_KEY_BYTES_TO_DISPLAY)
 1104         {
 1105             dots3 = TRUE;
 1106             j = NBR_KEY_BYTES_TO_DISPLAY;
 1107         }
 1108 
 1109         MasterKeyGUIView[0] = 0;
 1110         for (i = 0; i < j; i++)
 1111         {
 1112             wchar_t tmp2[8] = {0};
 1113             StringCchPrintfW (tmp2, ARRAYSIZE(tmp2), L"%02X", (int) (unsigned char) keyInfo.master_keydata[i + primaryKeyOffset]);
 1114             StringCchCatW (MasterKeyGUIView, ARRAYSIZE(MasterKeyGUIView), tmp2);
 1115         }
 1116 
 1117         HeaderKeyGUIView[0] = 0;
 1118         for (i = 0; i < NBR_KEY_BYTES_TO_DISPLAY; i++)
 1119         {
 1120             wchar_t tmp2[8];
 1121             StringCchPrintfW (tmp2, ARRAYSIZE(tmp2), L"%02X", (int) (unsigned char) dk[primaryKeyOffset + i]);
 1122             StringCchCatW (HeaderKeyGUIView, ARRAYSIZE(HeaderKeyGUIView), tmp2);
 1123         }
 1124 
 1125         if (dots3)
 1126         {
 1127             DisplayPortionsOfKeys (hHeaderKey, hMasterKey, HeaderKeyGUIView, MasterKeyGUIView, !showKeys);
 1128         }
 1129         else
 1130         {
 1131             SendMessage (hMasterKey, WM_SETTEXT, 0, (LPARAM) MasterKeyGUIView);
 1132             SendMessage (hHeaderKey, WM_SETTEXT, 0, (LPARAM) HeaderKeyGUIView);
 1133         }
 1134     }
 1135 #endif  // #ifdef VOLFORMAT
 1136 
 1137     *retInfo = cryptoInfo;
 1138 
 1139 err:
 1140     burn (dk, sizeof(dk));
 1141     burn (&keyInfo, sizeof (keyInfo));
 1142 #if !defined(_UEFI)
 1143     VirtualUnlock (&keyInfo, sizeof (keyInfo));
 1144     VirtualUnlock (&dk, sizeof (dk));
 1145 #endif // !defined(_UEFI)
 1146 
 1147     return 0;
 1148 }
 1149 
 1150 #if !defined(_UEFI)
 1151 BOOL ReadEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header, DWORD *bytesRead)
 1152 {
 1153 #if TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
 1154 #error TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
 1155 #endif
 1156 
 1157     byte sectorBuffer[TC_MAX_VOLUME_SECTOR_SIZE];
 1158     DISK_GEOMETRY geometry;
 1159 
 1160     if (!device)
 1161         return ReadFile (fileHandle, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE, bytesRead, NULL);
 1162 
 1163     if (!DeviceIoControl (fileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof (geometry), bytesRead, NULL))
 1164         return FALSE;
 1165 
 1166     if (geometry.BytesPerSector > sizeof (sectorBuffer) || geometry.BytesPerSector < TC_MIN_VOLUME_SECTOR_SIZE)
 1167     {
 1168         SetLastError (ERROR_INVALID_PARAMETER);
 1169         return FALSE;
 1170     }
 1171 
 1172     if (!ReadFile (fileHandle, sectorBuffer, max (TC_VOLUME_HEADER_EFFECTIVE_SIZE, geometry.BytesPerSector), bytesRead, NULL))
 1173         return FALSE;
 1174 
 1175     memcpy (header, sectorBuffer, min (*bytesRead, TC_VOLUME_HEADER_EFFECTIVE_SIZE));
 1176 
 1177     if (*bytesRead > TC_VOLUME_HEADER_EFFECTIVE_SIZE)
 1178         *bytesRead = TC_VOLUME_HEADER_EFFECTIVE_SIZE;
 1179 
 1180     return TRUE;
 1181 }
 1182 
 1183 
 1184 BOOL WriteEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header)
 1185 {
 1186 #if TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
 1187 #error TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
 1188 #endif
 1189 
 1190     byte sectorBuffer[TC_MAX_VOLUME_SECTOR_SIZE];
 1191     DWORD bytesDone;
 1192     DISK_GEOMETRY geometry;
 1193 
 1194     if (!device)
 1195     {
 1196         if (!WriteFile (fileHandle, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE, &bytesDone, NULL))
 1197             return FALSE;
 1198 
 1199         if (bytesDone != TC_VOLUME_HEADER_EFFECTIVE_SIZE)
 1200         {
 1201             SetLastError (ERROR_INVALID_PARAMETER);
 1202             return FALSE;
 1203         }
 1204 
 1205         return TRUE;
 1206     }
 1207 
 1208 
 1209     if (!DeviceIoControl (fileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof (geometry), &bytesDone, NULL))
 1210         return FALSE;
 1211 
 1212     if (geometry.BytesPerSector > sizeof (sectorBuffer) || geometry.BytesPerSector < TC_MIN_VOLUME_SECTOR_SIZE)
 1213     {
 1214         SetLastError (ERROR_INVALID_PARAMETER);
 1215         return FALSE;
 1216     }
 1217 
 1218     if (geometry.BytesPerSector != TC_VOLUME_HEADER_EFFECTIVE_SIZE)
 1219     {
 1220         LARGE_INTEGER seekOffset;
 1221 
 1222         if (!ReadFile (fileHandle, sectorBuffer, geometry.BytesPerSector, &bytesDone, NULL))
 1223             return FALSE;
 1224 
 1225         if (bytesDone != geometry.BytesPerSector)
 1226         {
 1227             SetLastError (ERROR_INVALID_PARAMETER);
 1228             return FALSE;
 1229         }
 1230 
 1231         seekOffset.QuadPart = -(int) bytesDone;
 1232         if (!SetFilePointerEx (fileHandle, seekOffset, NULL, FILE_CURRENT))
 1233             return FALSE;
 1234     }
 1235 
 1236     memcpy (sectorBuffer, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
 1237 
 1238     if (!WriteFile (fileHandle, sectorBuffer, geometry.BytesPerSector, &bytesDone, NULL))
 1239         return FALSE;
 1240 
 1241     if (bytesDone != geometry.BytesPerSector)
 1242     {
 1243         SetLastError (ERROR_INVALID_PARAMETER);
 1244         return FALSE;
 1245     }
 1246 
 1247     return TRUE;
 1248 }
 1249 
 1250 
 1251 // Writes randomly generated data to unused/reserved header areas.
 1252 // When bPrimaryOnly is TRUE, then only the primary header area (not the backup header area) is filled with random data.
 1253 // When bBackupOnly is TRUE, only the backup header area (not the primary header area) is filled with random data.
 1254 int WriteRandomDataToReservedHeaderAreas (HWND hwndDlg, HANDLE dev, CRYPTO_INFO *cryptoInfo, uint64 dataAreaSize, BOOL bPrimaryOnly, BOOL bBackupOnly)
 1255 {
 1256     char temporaryKey[MASTER_KEYDATA_SIZE];
 1257     char originalK2[MASTER_KEYDATA_SIZE];
 1258 
 1259     byte buf[TC_VOLUME_HEADER_GROUP_SIZE];
 1260 
 1261     LARGE_INTEGER offset;
 1262     int nStatus = ERR_SUCCESS;
 1263     DWORD dwError;
 1264     DWORD bytesDone;
 1265     BOOL backupHeaders = bBackupOnly;
 1266 
 1267     if (bPrimaryOnly && bBackupOnly)
 1268         TC_THROW_FATAL_EXCEPTION;
 1269 
 1270     memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2));
 1271 
 1272     while (TRUE)
 1273     {
 1274         // Temporary keys
 1275         if (!RandgetBytes (hwndDlg, temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE)
 1276             || !RandgetBytes (hwndDlg, cryptoInfo->k2, sizeof (cryptoInfo->k2), FALSE))
 1277         {
 1278             nStatus = ERR_PARAMETER_INCORRECT;
 1279             goto final_seq;
 1280         }
 1281 
 1282         nStatus = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks);
 1283         if (nStatus != ERR_SUCCESS)
 1284             goto final_seq;
 1285 
 1286         if (!EAInitMode (cryptoInfo))
 1287         {
 1288             nStatus = ERR_MODE_INIT_FAILED;
 1289             goto final_seq;
 1290         }
 1291 
 1292         offset.QuadPart = backupHeaders ? dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE : TC_VOLUME_HEADER_OFFSET;
 1293 
 1294         if (!SetFilePointerEx (dev, offset, NULL, FILE_BEGIN))
 1295         {
 1296             nStatus = ERR_OS_ERROR;
 1297             goto final_seq;
 1298         }
 1299 
 1300         if (!ReadFile (dev, buf, sizeof (buf), &bytesDone, NULL))
 1301         {
 1302             nStatus = ERR_OS_ERROR;
 1303             goto final_seq;
 1304         }
 1305 
 1306         if (bytesDone < TC_VOLUME_HEADER_EFFECTIVE_SIZE)
 1307         {
 1308             SetLastError (ERROR_INVALID_PARAMETER);
 1309             nStatus = ERR_OS_ERROR;
 1310             goto final_seq;
 1311         }
 1312 
 1313         // encrypt random data instead of existing data for better entropy
 1314         RandgetBytesFull (hwndDlg, buf + TC_VOLUME_HEADER_EFFECTIVE_SIZE, sizeof (buf) - TC_VOLUME_HEADER_EFFECTIVE_SIZE, FALSE, TRUE);
 1315 
 1316         EncryptBuffer (buf + TC_VOLUME_HEADER_EFFECTIVE_SIZE, sizeof (buf) - TC_VOLUME_HEADER_EFFECTIVE_SIZE, cryptoInfo);
 1317 
 1318         if (!SetFilePointerEx (dev, offset, NULL, FILE_BEGIN))
 1319         {
 1320             nStatus = ERR_OS_ERROR;
 1321             goto final_seq;
 1322         }
 1323 
 1324         if (!WriteFile (dev, buf, sizeof (buf), &bytesDone, NULL))
 1325         {
 1326             nStatus = ERR_OS_ERROR;
 1327             goto final_seq;
 1328         }
 1329 
 1330         if (bytesDone != sizeof (buf))
 1331         {
 1332             nStatus = ERR_PARAMETER_INCORRECT;
 1333             goto final_seq;
 1334         }
 1335 
 1336         if (backupHeaders || bPrimaryOnly)
 1337             break;
 1338 
 1339         backupHeaders = TRUE;
 1340     }
 1341 
 1342     memcpy (cryptoInfo->k2, originalK2, sizeof (cryptoInfo->k2));
 1343 
 1344     nStatus = EAInit (cryptoInfo->ea, cryptoInfo->master_keydata, cryptoInfo->ks);
 1345     if (nStatus != ERR_SUCCESS)
 1346         goto final_seq;
 1347 
 1348     if (!EAInitMode (cryptoInfo))
 1349     {
 1350         nStatus = ERR_MODE_INIT_FAILED;
 1351         goto final_seq;
 1352     }
 1353 
 1354 final_seq:
 1355 
 1356     dwError = GetLastError();
 1357 
 1358     burn (temporaryKey, sizeof (temporaryKey));
 1359     burn (originalK2, sizeof (originalK2));
 1360 
 1361     if (nStatus != ERR_SUCCESS)
 1362         SetLastError (dwError);
 1363 
 1364     return nStatus;
 1365 }
 1366 
 1367 #endif // !defined(_UEFI)
 1368 #endif // !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT)