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