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