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