|
|
1.1.1.6 root 1: /* Legal Notice: The source code contained in this file has been derived from
2: the source code of Encryption for the Masses 2.02a, which is Copyright (c)
3: 1998-99 Paul Le Roux and which is covered by the 'License Agreement for
4: Encryption for the Masses'. Modifications and additions to that source code
5: contained in this file are Copyright (c) 2004-2005 TrueCrypt Foundation and
6: Copyright (c) 2004 TrueCrypt Team, and are covered by TrueCrypt License 2.0
7: the full text of which is contained in the file License.txt included in
8: TrueCrypt binary and source code distribution archives. */
1.1 root 9:
1.1.1.6 root 10: #include "Tcdefs.h"
1.1 root 11:
12: #include <fcntl.h>
13: #include <sys/types.h>
14: #include <sys/stat.h>
15: #include <time.h>
16:
1.1.1.6 root 17: #ifdef _WIN32
18: #include <io.h>
19: #include "Random.h"
20: #endif
21:
22: #include "Crypto.h"
23: #include "Endian.h"
24: #include "Volumes.h"
25:
26: #include "Pkcs5.h"
27: #include "Crc.h"
1.1 root 28:
29:
1.1.1.6 root 30: #define NBR_KEY_BYTES_TO_DISPLAY 16
1.1 root 31:
32:
33: // Volume header structure:
34: //
35: // Offset Length Description
36: // ------------------------------------------
37: // Unencrypted:
1.1.1.6 root 38: // 0 64 Salt
1.1 root 39: // Encrypted:
1.1.1.4 root 40: // 64 4 ASCII string 'TRUE'
1.1 root 41: // 68 2 Header version
42: // 70 2 Required program version
1.1.1.7 ! root 43: // 72 4 CRC-32 checksum of the (decrypted) bytes 256-511
1.1 root 44: // 76 8 Volume creation time
45: // 84 8 Header creation time
1.1.1.4 root 46: // 92 8 Size of hidden volume in bytes (0 = normal volume)
1.1.1.7 ! root 47: // 100 156 Reserved (set to zero)
! 48: // 256 32 Secondary key (LRW mode)
! 49: // 288 224 Master key(s)
1.1 root 50:
51: int
1.1.1.6 root 52: VolumeReadHeader (char *encryptedHeader, Password *password, PCRYPTO_INFO *retInfo)
1.1 root 53: {
1.1.1.6 root 54: char header[HEADER_SIZE];
1.1 root 55: unsigned char *input = (unsigned char *) header;
56: KEY_INFO keyInfo;
57: PCRYPTO_INFO cryptoInfo;
1.1.1.6 root 58: int nKeyLen;
1.1 root 59: char dk[DISKKEY_SIZE];
60: int pkcs5;
61: int headerVersion, requiredVersion;
1.1.1.6 root 62: int status;
63:
1.1.1.7 ! root 64:
1.1 root 65: cryptoInfo = *retInfo = crypto_open ();
66: if (cryptoInfo == NULL)
67: return ERR_OUTOFMEMORY;
68:
1.1.1.6 root 69: crypto_loadkey (&keyInfo, password->Text, password->Length);
1.1 root 70:
1.1.1.7 ! root 71: // PKCS5 is used to derive the header key and the secondary header key (LRW mode) from the user password
1.1.1.6 root 72: memcpy (keyInfo.key_salt, encryptedHeader + HEADER_USERKEY_SALT, PKCS5_SALT_SIZE);
1.1 root 73:
1.1.1.3 root 74: // Test all available PKCS5 PRFs
75: for (pkcs5 = 1; pkcs5 <= LAST_PRF_ID; pkcs5++)
1.1 root 76: {
1.1.1.7 ! root 77: BOOL lrw64InitDone = FALSE;
! 78: BOOL lrw128InitDone = FALSE;
! 79:
1.1.1.6 root 80: keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5);
81:
82: switch (pkcs5)
1.1.1.3 root 83: {
1.1.1.6 root 84: case SHA1:
85: derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
86: PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
87: break;
88:
89: case RIPEMD160:
90: derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
91: PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
92: break;
93:
94: case WHIRLPOOL:
95: derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
96: PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
97: break;
1.1.1.4 root 98: }
1.1 root 99:
1.1.1.4 root 100: // Test all available encryption algorithms
1.1.1.7 ! root 101: for (cryptoInfo->ea = EAGetFirst ();
! 102: cryptoInfo->ea != 0;
! 103: cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
1.1.1.3 root 104: {
1.1.1.7 ! root 105: int blockSize = CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea));
1.1.1.6 root 106:
107: status = EAInit (cryptoInfo->ea, dk + DISK_IV_SIZE, cryptoInfo->ks);
108: if (status == ERR_CIPHER_INIT_FAILURE)
109: goto err;
110:
1.1.1.7 ! root 111: // Test all available modes of operation
! 112: for (cryptoInfo->mode = EAGetFirstMode (cryptoInfo->ea);
! 113: cryptoInfo->mode != 0;
! 114: cryptoInfo->mode = EAGetNextMode (cryptoInfo->ea, cryptoInfo->mode))
1.1.1.6 root 115: {
1.1.1.7 ! root 116: // Copy header for decryption and init an encryption algorithm
! 117: memcpy (header, encryptedHeader, SECTOR_SIZE);
! 118: memcpy (cryptoInfo->iv, dk, DISK_IV_SIZE);
! 119:
! 120: if (cryptoInfo->mode == LRW
! 121: && (blockSize == 8 && !lrw64InitDone || blockSize == 16 && !lrw128InitDone))
! 122: {
! 123: if (!EAInitMode (cryptoInfo))
! 124: {
! 125: status = ERR_MODE_INIT_FAILED;
! 126: goto err;
! 127: }
! 128:
! 129: if (blockSize == 8)
! 130: lrw64InitDone = TRUE;
! 131: else if (blockSize == 16)
! 132: lrw128InitDone = TRUE;
! 133: }
! 134:
! 135: input = header;
! 136:
! 137: // Try to decrypt header
! 138:
! 139: DecryptBuffer ((unsigned __int32 *) (header + HEADER_ENCRYPTEDDATA), HEADER_ENCRYPTEDDATASIZE,
! 140: cryptoInfo);
! 141:
! 142: input += HEADER_ENCRYPTEDDATA;
! 143:
! 144: // Magic 'TRUE'
! 145: if (mgetLong (input) != 0x54525545)
! 146: continue;
! 147:
! 148: // Header version
! 149: headerVersion = mgetWord (input);
! 150:
! 151: // Required program version
! 152: requiredVersion = mgetWord (input);
! 153:
! 154: // Check CRC of the key set
! 155: if (mgetLong (input) != crc32 (header + HEADER_DISKKEY, DISKKEY_SIZE))
! 156: continue;
! 157:
! 158: // Now we have the correct password, cipher, hash algorithm, and volume type
! 159:
! 160: // Check the version required to handle this volume
! 161: if (requiredVersion > VERSION_NUM)
! 162: {
! 163: status = ERR_NEW_VERSION_REQUIRED;
! 164: goto err;
! 165: }
! 166:
! 167: // Volume creation time
! 168: cryptoInfo->volume_creation_time = mgetInt64 (input);
! 169:
! 170: // Header creation time
! 171: cryptoInfo->header_creation_time = mgetInt64 (input);
! 172:
! 173: // Hidden volume size (if any)
! 174: cryptoInfo->hiddenVolumeSize = mgetInt64 (input);
! 175:
! 176: // Disk key
! 177: nKeyLen = DISKKEY_SIZE;
! 178: memcpy (keyInfo.key, header + HEADER_DISKKEY, nKeyLen);
! 179:
! 180: memcpy (cryptoInfo->master_key, keyInfo.key, nKeyLen);
! 181: memcpy (cryptoInfo->key_salt, keyInfo.key_salt, PKCS5_SALT_SIZE);
! 182: cryptoInfo->pkcs5 = pkcs5;
! 183: cryptoInfo->noIterations = keyInfo.noIterations;
! 184:
! 185: // Init the encryption algorithm with the decrypted master key
! 186: status = EAInit (cryptoInfo->ea, keyInfo.key + DISK_IV_SIZE, cryptoInfo->ks);
! 187: if (status == ERR_CIPHER_INIT_FAILURE)
! 188: goto err;
! 189:
! 190: // The secondary key (LRW mode) for the data area
! 191: memcpy (cryptoInfo->iv, keyInfo.key, DISK_IV_SIZE);
! 192:
! 193: // Mode of operation
! 194: if (!EAInitMode (cryptoInfo))
! 195: {
! 196: status = ERR_MODE_INIT_FAILED;
! 197: goto err;
! 198: }
1.1.1.6 root 199:
1.1.1.7 ! root 200: // Clear out the temp. key buffers
! 201: burn (dk, sizeof(dk));
1.1.1.6 root 202:
1.1.1.7 ! root 203: return 0;
1.1.1.6 root 204:
1.1.1.7 ! root 205: }
1.1.1.2 root 206: }
1.1 root 207: }
1.1.1.6 root 208: status = ERR_PASSWORD_WRONG;
1.1 root 209:
1.1.1.6 root 210: err:
1.1 root 211: crypto_close(cryptoInfo);
1.1.1.7 ! root 212: *retInfo = NULL;
1.1 root 213: burn (&keyInfo, sizeof (keyInfo));
1.1.1.6 root 214: return status;
1.1 root 215: }
216:
217: #ifndef DEVICE_DRIVER
218:
219: #ifdef VOLFORMAT
1.1.1.3 root 220: extern BOOL showKeys;
1.1 root 221: extern HWND hDiskKey;
1.1.1.3 root 222: extern HWND hHeaderKey;
1.1 root 223: #endif
224:
1.1.1.6 root 225: #ifdef _WIN32
226:
1.1 root 227: // VolumeWriteHeader:
228: // Creates volume header in memory
229: int
1.1.1.7 ! root 230: VolumeWriteHeader (char *header, int ea, int mode, Password *password,
1.1.1.4 root 231: int pkcs5, char *masterKey, unsigned __int64 volumeCreationTime, PCRYPTO_INFO * retInfo,
1.1.1.6 root 232: unsigned __int64 hiddenVolumeSize, BOOL bWipeMode)
1.1 root 233: {
234: unsigned char *p = (unsigned char *) header;
1.1.1.6 root 235: static KEY_INFO keyInfo;
1.1 root 236:
1.1.1.6 root 237: int nUserKeyLen = password->Length;
1.1 root 238: PCRYPTO_INFO cryptoInfo = crypto_open ();
1.1.1.6 root 239: static char dk[DISKKEY_SIZE];
1.1 root 240: int x;
1.1.1.6 root 241: int retVal = 0;
1.1 root 242:
243: if (cryptoInfo == NULL)
244: return ERR_OUTOFMEMORY;
245:
246: memset (header, 0, SECTOR_SIZE);
1.1.1.2 root 247: VirtualLock (&keyInfo, sizeof (keyInfo));
1.1.1.6 root 248: VirtualLock (&dk, sizeof (dk));
1.1 root 249:
1.1.1.6 root 250: /* Encryption setup */
1.1 root 251:
1.1.1.7 ! root 252: // If necessary, generate the master key and the secondary key (LRW mode)
1.1.1.2 root 253: if(masterKey == 0)
1.1.1.7 ! root 254: {
1.1.1.2 root 255: RandgetBytes (keyInfo.key, DISKKEY_SIZE, TRUE);
1.1.1.7 ! root 256:
! 257: // Verify that the secondary key is not weak
! 258: if (DetectWeakSecondaryKey (keyInfo.key, CipherGetBlockSize (EAGetFirstCipher (ea))))
! 259: return ERR_CIPHER_INIT_WEAK_KEY;
! 260: }
1.1.1.2 root 261: else
262: memcpy (keyInfo.key, masterKey, DISKKEY_SIZE);
263:
1.1.1.6 root 264: // User key
265: memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
1.1 root 266: keyInfo.keyLength = nUserKeyLen;
1.1.1.6 root 267: keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5);
1.1 root 268:
269: // User selected encryption algorithm
1.1.1.4 root 270: cryptoInfo->ea = ea;
1.1 root 271:
1.1.1.7 ! root 272: // Mode of operation
! 273: cryptoInfo->mode = mode;
! 274:
1.1 root 275: // Salt for header key derivation
1.1.1.6 root 276: RandgetBytes (keyInfo.key_salt, PKCS5_SALT_SIZE, !bWipeMode);
1.1 root 277:
1.1.1.7 ! root 278: // PKCS5 is used to derive the header key and the secondary header key (LRW mode) from the password
1.1.1.6 root 279: switch (pkcs5)
1.1 root 280: {
1.1.1.6 root 281: case SHA1:
282: derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
283: PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
284: break;
285:
286: case RIPEMD160:
287: derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
288: PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
289: break;
290:
291: case WHIRLPOOL:
292: derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
293: PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
294: break;
295: }
1.1.1.7 ! root 296: // Verify that the secondary key is not weak
! 297: if (DetectWeakSecondaryKey (dk, CipherGetBlockSize (EAGetFirstCipher (ea))))
! 298: return ERR_CIPHER_INIT_WEAK_KEY;
! 299:
1.1 root 300:
1.1.1.6 root 301: /* Header setup */
1.1 root 302:
303: // Salt
1.1.1.6 root 304: mputBytes (p, keyInfo.key_salt, PKCS5_SALT_SIZE);
1.1 root 305:
306: // Magic
307: mputLong (p, 'TRUE');
308:
309: // Header version
1.1.1.4 root 310: mputWord (p, VOLUME_HEADER_VERSION);
1.1 root 311:
312: // Required program version to handle this volume
1.1.1.4 root 313: mputWord (p, VOL_REQ_PROG_VERSION);
1.1 root 314:
1.1.1.7 ! root 315: // CRC of the key set
1.1 root 316: x = crc32(keyInfo.key, DISKKEY_SIZE);
317: mputLong (p, x);
318:
319: // Time
320: {
321: SYSTEMTIME st;
322: FILETIME ft;
323:
324: // Volume creation time
325: if (volumeCreationTime == 0)
326: {
327: GetLocalTime (&st);
328: SystemTimeToFileTime (&st, &ft);
329: }
330: else
331: {
332: ft.dwHighDateTime = (DWORD)(volumeCreationTime >> 32);
333: ft.dwLowDateTime = (DWORD)volumeCreationTime;
334: }
335: mputLong (p, ft.dwHighDateTime);
336: mputLong (p, ft.dwLowDateTime);
337:
1.1.1.6 root 338: // Header modification time/date
1.1 root 339: GetLocalTime (&st);
340: SystemTimeToFileTime (&st, &ft);
341: mputLong (p, ft.dwHighDateTime);
342: mputLong (p, ft.dwLowDateTime);
343: }
344:
1.1.1.4 root 345: // Hidden volume size
346: cryptoInfo->hiddenVolumeSize = hiddenVolumeSize;
347: mputInt64 (p, cryptoInfo->hiddenVolumeSize);
1.1.1.7 ! root 348: cryptoInfo->hiddenVolume = cryptoInfo->hiddenVolumeSize != 0;
1.1.1.4 root 349:
1.1.1.7 ! root 350: // The key set
1.1 root 351: memcpy (header + HEADER_DISKKEY, keyInfo.key, DISKKEY_SIZE);
352:
353:
1.1.1.6 root 354: /* Header encryption */
1.1 root 355:
356: memcpy (cryptoInfo->iv, dk, DISK_IV_SIZE);
1.1.1.6 root 357: retVal = EAInit (cryptoInfo->ea, dk + DISK_IV_SIZE, cryptoInfo->ks);
358: if (retVal != 0)
359: return retVal;
1.1 root 360:
1.1.1.7 ! root 361: // Mode of operation
! 362: if (!EAInitMode (cryptoInfo))
! 363: return ERR_OUTOFMEMORY;
! 364:
! 365: EncryptBuffer ((unsigned __int32 *) (header + HEADER_ENCRYPTEDDATA),
! 366: HEADER_ENCRYPTEDDATASIZE,
! 367: cryptoInfo);
1.1 root 368:
369:
1.1.1.6 root 370: /* cryptoInfo setup for further use (disk format) */
1.1 root 371:
1.1.1.6 root 372: // Init with the master key
373: retVal = EAInit (cryptoInfo->ea, keyInfo.key + DISK_IV_SIZE, cryptoInfo->ks);
374: if (retVal != 0)
375: return retVal;
1.1 root 376:
1.1.1.7 ! root 377: // The secondary key (LRW mode)
1.1 root 378: memcpy (cryptoInfo->iv, keyInfo.key, DISK_IV_SIZE);
379:
1.1.1.7 ! root 380: // Mode of operation
! 381: if (!EAInitMode (cryptoInfo))
! 382: return ERR_OUTOFMEMORY;
! 383:
1.1.1.2 root 384:
1.1 root 385: #ifdef VOLFORMAT
1.1.1.3 root 386: if (showKeys)
1.1 root 387: {
388: char tmp[64];
389: BOOL dots3 = FALSE;
390: int i, j;
391:
1.1.1.4 root 392: j = EAGetKeySize (ea);
1.1 root 393:
1.1.1.6 root 394: if (j > NBR_KEY_BYTES_TO_DISPLAY)
1.1 root 395: {
396: dots3 = TRUE;
1.1.1.6 root 397: j = NBR_KEY_BYTES_TO_DISPLAY;
1.1 root 398: }
399:
400: tmp[0] = 0;
401: for (i = 0; i < j; i++)
402: {
403: char tmp2[8] =
404: {0};
405: sprintf (tmp2, "%02X", (int) (unsigned char) keyInfo.key[i + DISK_IV_SIZE]);
406: strcat (tmp, tmp2);
407: }
408:
1.1.1.6 root 409: if (dots3)
1.1 root 410: {
411: strcat (tmp, "...");
412: }
413:
414:
415: SetWindowText (hDiskKey, tmp);
416:
417: tmp[0] = 0;
1.1.1.6 root 418: for (i = 0; i < NBR_KEY_BYTES_TO_DISPLAY; i++)
1.1 root 419: {
420: char tmp2[8];
1.1.1.3 root 421: sprintf (tmp2, "%02X", (int) (unsigned char) dk[DISK_IV_SIZE + i]);
1.1 root 422: strcat (tmp, tmp2);
423: }
424:
1.1.1.6 root 425: if (dots3)
1.1.1.3 root 426: {
427: strcat (tmp, "...");
428: }
429:
430: SetWindowText (hHeaderKey, tmp);
1.1 root 431: }
432: #endif
433:
1.1.1.3 root 434: burn (dk, sizeof(dk));
1.1 root 435: burn (&keyInfo, sizeof (keyInfo));
436:
437: *retInfo = cryptoInfo;
438: return 0;
439: }
440:
1.1.1.6 root 441: #endif /* WIN32 */
442:
1.1 root 443: #endif /* !NT4_DRIVER */
1.1.1.4 root 444:
1.1.1.7 ! root 445:
! 446: BOOL DetectWeakSecondaryKey (unsigned char *key, int len)
! 447: {
! 448: int i;
! 449:
! 450: for (i = 0; i < len; i++)
! 451: {
! 452: if (key[i] != 0)
! 453: return FALSE;
! 454: }
! 455: return TRUE;
! 456: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.