|
|
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
1.1.1.8 root 5: contained in this file are Copyright (c) 2004-2006 TrueCrypt Foundation and
1.1.1.9 ! root 6: Copyright (c) 2004 TrueCrypt Team, and are covered by TrueCrypt License 2.1
1.1.1.6 root 7: the full text of which is contained in the file License.txt included in
8: TrueCrypt binary and source code distribution archives. */
9:
10: #include "Tcdefs.h"
11:
12: #include "Crypto.h"
13: #include "Format.h"
14: #include "Fat.h"
15: #include "Progress.h"
1.1.1.8 root 16: #include "Random.h"
1.1 root 17:
18: #include <time.h>
19:
20: void
21: GetFatParams (fatparams * ft)
22: {
23: int fatsecs;
1.1.1.5 root 24: if(ft->cluster_size == 0) // 'Default' cluster size
1.1 root 25: {
1.1.1.8 root 26: if (ft->num_sectors * 512LL >= 256*BYTES_PER_GB)
1.1 root 27: ft->cluster_size = 128;
1.1.1.8 root 28: else if (ft->num_sectors * 512LL >= 64*BYTES_PER_GB)
1.1 root 29: ft->cluster_size = 64;
1.1.1.8 root 30: else if (ft->num_sectors * 512LL >= 16*BYTES_PER_GB)
1.1 root 31: ft->cluster_size = 32;
1.1.1.8 root 32: else if (ft->num_sectors * 512LL >= 8*BYTES_PER_GB)
1.1 root 33: ft->cluster_size = 16;
1.1.1.8 root 34: else if (ft->num_sectors * 512LL >= 128*BYTES_PER_MB)
1.1 root 35: ft->cluster_size = 8;
1.1.1.8 root 36: else if (ft->num_sectors * 512LL >= 64*BYTES_PER_MB)
1.1 root 37: ft->cluster_size = 4;
1.1.1.8 root 38: else if (ft->num_sectors * 512LL >= 32*BYTES_PER_MB)
1.1 root 39: ft->cluster_size = 2;
40: else
41: ft->cluster_size = 1;
42: }
43:
44: // Geometry always set to SECTORS/1/1
45: ft->secs_track = 1;
46: ft->heads = 1;
47:
48: ft->dir_entries = 512;
49: ft->fats = 2;
1.1.1.6 root 50: ft->create_time = (unsigned int) time (NULL);
1.1 root 51: ft->media = 0xf8;
52: ft->sector_size = SECTOR_SIZE;
1.1.1.6 root 53: ft->hidden = 63;
1.1 root 54:
55: ft->size_root_dir = ft->dir_entries * 32;
56:
1.1.1.6 root 57: // FAT12
1.1 root 58: ft->size_fat = 12;
1.1.1.6 root 59: ft->reserved = 2;
60: fatsecs = ft->num_sectors - (ft->size_root_dir + SECTOR_SIZE - 1) / SECTOR_SIZE - ft->reserved;
61: ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) / (ft->cluster_size * SECTOR_SIZE + 3));
62: ft->fat_length = (((ft->cluster_count * 3 + 1) >> 1) + SECTOR_SIZE - 1) / SECTOR_SIZE;
1.1 root 63:
1.1.1.6 root 64: if (ft->cluster_count >= 4085) // FAT16
1.1 root 65: {
66: ft->size_fat = 16;
1.1.1.6 root 67: ft->reserved = 8;
68: fatsecs = ft->num_sectors - (ft->size_root_dir + SECTOR_SIZE - 1) / SECTOR_SIZE - ft->reserved;
69: ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) / (ft->cluster_size * SECTOR_SIZE + 4));
70: ft->fat_length = (ft->cluster_count * 2 + SECTOR_SIZE - 1) / SECTOR_SIZE;
1.1 root 71: }
1.1.1.6 root 72:
73: if(ft->cluster_count >= 65525) // FAT32
1.1 root 74: {
75: ft->size_fat = 32;
1.1.1.6 root 76: ft->reserved = 38;
77: fatsecs = ft->num_sectors - ft->reserved;
1.1 root 78: ft->size_root_dir = ft->cluster_size * SECTOR_SIZE;
1.1.1.6 root 79: ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) / (ft->cluster_size * SECTOR_SIZE + 8));
80: ft->fat_length = (ft->cluster_count * 4 + SECTOR_SIZE - 1) / SECTOR_SIZE;
1.1 root 81: }
82:
83: if (ft->num_sectors >= 65536 || ft->size_fat == 32)
84: {
85: ft->sectors = 0;
86: ft->total_sect = ft->num_sectors;
87: }
88: else
89: {
90: ft->sectors = ft->num_sectors;
91: ft->total_sect = 0;
92: }
93: }
94:
95: void
96: PutBoot (fatparams * ft, unsigned char *boot)
97: {
98: int cnt = 0;
99:
100: boot[cnt++] = 0xeb; /* boot jump */
101: boot[cnt++] = 0x3c;
102: boot[cnt++] = 0x90;
1.1.1.6 root 103: memcpy (boot + cnt, "MSDOS5.0", 8); /* system id */
1.1 root 104: cnt += 8;
1.1.1.6 root 105: memcpy (boot + cnt, &ft->sector_size, 2); /* bytes per sector */
1.1 root 106: cnt += 2;
1.1.1.6 root 107: memcpy (boot + cnt, &ft->cluster_size, 1); /* sectors per cluster */
1.1 root 108: cnt++;
1.1.1.6 root 109: memcpy (boot + cnt, &ft->reserved, 2); /* reserved sectors */
110: cnt += 2;
111: memcpy (boot + cnt, &ft->fats, 1); /* 2 fats */
1.1 root 112: cnt++;
113:
114: if(ft->size_fat == 32)
115: {
116: boot[cnt++] = 0x00;
117: boot[cnt++] = 0x00;
118: }
119: else
120: {
1.1.1.6 root 121: memcpy (boot + cnt, &ft->dir_entries, 2); /* 512 root entries */
1.1 root 122: cnt += 2;
123: }
124:
1.1.1.6 root 125: memcpy (boot + cnt, &ft->sectors, 2); /* # sectors */
1.1 root 126: cnt += 2;
1.1.1.6 root 127: memcpy (boot + cnt, &ft->media, 1); /* media byte */
1.1 root 128: cnt++;
129:
130: if(ft->size_fat == 32)
131: {
132: boot[cnt++] = 0x00;
133: boot[cnt++] = 0x00;
134: }
135: else
136: {
1.1.1.6 root 137: memcpy (boot + cnt, &ft->fat_length, 2); /* fat size */
1.1 root 138: cnt += 2;
139: }
140:
1.1.1.6 root 141: memcpy (boot + cnt, &ft->secs_track, 2); /* # sectors per track */
1.1 root 142: cnt += 2;
1.1.1.6 root 143: memcpy (boot + cnt, &ft->heads, 2); /* # heads */
1.1 root 144: cnt += 2;
1.1.1.6 root 145: memcpy (boot + cnt, &ft->hidden, 4); /* # hidden sectors */
146: cnt += 4;
147: memcpy (boot + cnt, &ft->total_sect, 4); /* # huge sectors */
1.1 root 148: cnt += 4;
149:
150: if(ft->size_fat == 32)
151: {
152: memcpy (boot + cnt, &ft->fat_length, 4); cnt += 4; /* fat size 32 */
1.1.1.6 root 153: boot[cnt++] = 0x00; /* ExtFlags */
1.1 root 154: boot[cnt++] = 0x00;
155: boot[cnt++] = 0x00; /* FSVer */
156: boot[cnt++] = 0x00;
157: boot[cnt++] = 0x02; /* RootClus */
158: boot[cnt++] = 0x00;
159: boot[cnt++] = 0x00;
160: boot[cnt++] = 0x00;
161: boot[cnt++] = 0x01; /* FSInfo */
162: boot[cnt++] = 0x00;
163: boot[cnt++] = 0x06; /* BkBootSec */
164: boot[cnt++] = 0x00;
165: memset(boot+cnt, 0, 12); cnt+=12; /* Reserved */
166: }
167:
1.1.1.6 root 168: boot[cnt++] = 0x00; /* drive number */ // FIXED 80 > 00
1.1 root 169: boot[cnt++] = 0x00; /* reserved */
170: boot[cnt++] = 0x29; /* boot sig */
1.1.1.6 root 171: memcpy (boot + cnt, &ft->create_time, 4); /* vol id */
1.1 root 172: cnt += 4;
1.1.1.6 root 173: memcpy (boot + cnt, ft->volume_name, 11); /* vol title */
1.1 root 174: cnt += 11;
175:
176: switch(ft->size_fat) /* filesystem type */
177: {
178: case 12: memcpy (boot + cnt, "FAT12 ", 8); break;
179: case 16: memcpy (boot + cnt, "FAT16 ", 8); break;
180: case 32: memcpy (boot + cnt, "FAT32 ", 8); break;
181: }
182: cnt += 8;
183:
184: memset (boot + cnt, 0, ft->size_fat==32 ? 420:448); /* boot code */
185: cnt += ft->size_fat==32 ? 420:448;
186: boot[cnt++] = 0x55;
187: boot[cnt++] = 0xaa; /* boot sig */
188: }
189:
190: /* FAT32 FSInfo */
191: PutFSInfo (unsigned char *sector)
192: {
1.1.1.6 root 193: memset (sector, 0, 512);
194: sector[3]=0x41; /* LeadSig */
195: sector[2]=0x61;
196: sector[1]=0x52;
197: sector[0]=0x52;
198: sector[484+3]=0x61; /* StrucSig */
199: sector[484+2]=0x41;
200: sector[484+1]=0x72;
201: sector[484+0]=0x72;
202: sector[488+3]=0xff; /* Free_Count */
203: sector[488+2]=0xff;
204: sector[488+1]=0xff;
205: sector[488+0]=0xff;
206: sector[492+3]=0xff; /* Nxt_Free */
207: sector[492+2]=0xff;
208: sector[492+1]=0xff;
209: sector[492+0]=0xff;
210: sector[508+3]=0xaa; /* TrailSig */
211: sector[508+2]=0x55;
212: sector[508+1]=0x00;
213: sector[508+0]=0x00;
1.1 root 214: }
215:
216:
217: int
1.1.1.8 root 218: FormatFat (unsigned __int64 startSector, fatparams * ft, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat)
1.1 root 219: {
220: int write_buf_cnt = 0;
221: char sector[SECTOR_SIZE], *write_buf;
1.1.1.4 root 222: unsigned __int64 nSecNo = startSector;
1.1 root 223: int x, n;
1.1.1.6 root 224: int retVal;
1.1.1.7 root 225: char temporaryKey[DISKKEY_SIZE];
1.1 root 226:
1.1.1.8 root 227: #ifdef _WIN32
228: LARGE_INTEGER startOffset;
229: LARGE_INTEGER newOffset;
230:
1.1.1.4 root 231: // Seek to start sector
232: startOffset.QuadPart = startSector * SECTOR_SIZE;
1.1.1.6 root 233: if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN)
234: || newOffset.QuadPart != startOffset.QuadPart)
1.1.1.4 root 235: {
236: return ERR_VOL_SEEKING;
237: }
1.1.1.8 root 238: #endif
1.1 root 239:
1.1.1.4 root 240: /* Write the data area */
1.1 root 241:
1.1.1.8 root 242: write_buf = (char *)TCalloc (WRITE_BUF_SIZE);
1.1 root 243: memset (sector, 0, sizeof (sector));
244:
245: PutBoot (ft, (unsigned char *) sector);
1.1.1.6 root 246: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
1.1.1.8 root 247: cryptoInfo) == FALSE)
1.1 root 248: goto fail;
249:
250: /* fat32 boot area */
251: if (ft->size_fat == 32)
252: {
253: /* fsinfo */
254: PutFSInfo((unsigned char *) sector);
1.1.1.6 root 255: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
1.1.1.8 root 256: cryptoInfo) == FALSE)
1.1 root 257: goto fail;
258:
259: /* reserved */
1.1.1.4 root 260: while (nSecNo - startSector < 6)
1.1 root 261: {
262: memset (sector, 0, sizeof (sector));
263: sector[508+3]=0xaa; /* TrailSig */
264: sector[508+2]=0x55;
1.1.1.6 root 265: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
1.1.1.8 root 266: cryptoInfo) == FALSE)
1.1 root 267: goto fail;
268: }
269:
270: /* bootsector backup */
271: memset (sector, 0, sizeof (sector));
272: PutBoot (ft, (unsigned char *) sector);
1.1.1.6 root 273: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
1.1.1.8 root 274: cryptoInfo) == FALSE)
1.1 root 275: goto fail;
276:
277: PutFSInfo((unsigned char *) sector);
1.1.1.6 root 278: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
1.1.1.8 root 279: cryptoInfo) == FALSE)
1.1 root 280: goto fail;
1.1.1.6 root 281: }
1.1 root 282:
1.1.1.6 root 283: /* reserved */
1.1.1.8 root 284: while (nSecNo - startSector < (unsigned int)ft->reserved)
1.1.1.6 root 285: {
286: memset (sector, 0, sizeof (sector));
287: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
1.1.1.8 root 288: cryptoInfo) == FALSE)
1.1.1.6 root 289: goto fail;
1.1 root 290: }
291:
292: /* write fat */
293: for (x = 1; x <= ft->fats; x++)
294: {
295: for (n = 0; n < ft->fat_length; n++)
296: {
297: memset (sector, 0, SECTOR_SIZE);
298:
299: if (n == 0)
300: {
301: unsigned char fat_sig[12];
302: if (ft->size_fat == 32)
303: {
304: fat_sig[0] = (unsigned char) ft->media;
305: fat_sig[1] = fat_sig[2] = 0xff;
306: fat_sig[3] = 0x0f;
307: fat_sig[4] = fat_sig[5] = fat_sig[6] = 0xff;
308: fat_sig[7] = 0x0f;
309: fat_sig[8] = fat_sig[9] = fat_sig[10] = 0xff;
310: fat_sig[11] = 0x0f;
311: memcpy (sector, fat_sig, 12);
312: }
313: else if (ft->size_fat == 16)
314: {
315: fat_sig[0] = (unsigned char) ft->media;
316: fat_sig[1] = 0xff;
317: fat_sig[2] = 0xff;
318: fat_sig[3] = 0xff;
319: memcpy (sector, fat_sig, 4);
320: }
321: else if (ft->size_fat == 12)
322: {
323: fat_sig[0] = (unsigned char) ft->media;
324: fat_sig[1] = 0xff;
325: fat_sig[2] = 0xff;
326: fat_sig[3] = 0x00;
327: memcpy (sector, fat_sig, 4);
328: }
329: }
330:
1.1.1.6 root 331: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
1.1.1.8 root 332: cryptoInfo) == FALSE)
1.1 root 333: goto fail;
334: }
335: }
336:
337:
338: /* write rootdir */
339: for (x = 0; x < ft->size_root_dir / SECTOR_SIZE; x++)
340: {
341: memset (sector, 0, SECTOR_SIZE);
1.1.1.6 root 342: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
1.1.1.8 root 343: cryptoInfo) == FALSE)
1.1 root 344: goto fail;
345:
346: }
347:
1.1.1.7 root 348: /* Fill the rest of the data area with random data */
1.1.1.4 root 349:
1.1 root 350: if(!quickFormat)
351: {
1.1.1.7 root 352: /* Generate a random temporary key set to be used for "dummy" encryption that will fill
353: the free disk space (data area) with random data. This is necessary for plausible
354: deniability of hidden volumes (and also reduces the amount of predictable plaintext
355: within the volume). */
1.1 root 356:
1.1.1.9 ! root 357: // Temporary master key
! 358: if (!RandgetBytes (temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE))
! 359: goto fail;
! 360: // Secondary key (LRW mode)
! 361: if (!RandgetBytes (cryptoInfo->iv, sizeof cryptoInfo->iv, FALSE))
! 362: goto fail;
1.1.1.6 root 363:
1.1.1.7 root 364: retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks);
1.1.1.6 root 365: if (retVal != 0)
1.1.1.7 root 366: {
367: burn (temporaryKey, sizeof(temporaryKey));
1.1.1.6 root 368: return retVal;
1.1.1.7 root 369: }
370: if (!EAInitMode (cryptoInfo))
371: {
372: burn (temporaryKey, sizeof(temporaryKey));
373: return ERR_MODE_INIT_FAILED;
374: }
1.1 root 375:
1.1.1.6 root 376: x = ft->num_sectors - ft->reserved - ft->size_root_dir / SECTOR_SIZE - ft->fat_length * 2;
1.1 root 377: while (x--)
378: {
1.1.1.7 root 379: /* Generate random plaintext. Note that reused plaintext blocks are not a concern
380: here since LRW mode is designed to hide patterns. Furthermore, patterns in plaintext
381: do occur commonly on media in the "real world", so it might actually be a fatal
382: mistake to try to avoid them completely. */
1.1.1.9 ! root 383:
! 384: #if RNG_POOL_SIZE > SECTOR_SIZE
! 385: #error RNG_POOL_SIZE > SECTOR_SIZE
! 386: #endif
! 387:
! 388: #ifdef _WIN32
! 389: if (!RandpeekBytes (sector, RNG_POOL_SIZE)
! 390: || !RandpeekBytes (sector + RNG_POOL_SIZE, SECTOR_SIZE - RNG_POOL_SIZE))
! 391: goto fail;
1.1.1.7 root 392: #else
1.1.1.9 ! root 393: if ((nSecNo & 0x3fff) == 0)
! 394: {
! 395: if (!RandgetBytes (sector, RNG_POOL_SIZE, FALSE)
! 396: || !RandgetBytes (sector + RNG_POOL_SIZE, SECTOR_SIZE - RNG_POOL_SIZE, FALSE))
! 397: goto fail;
! 398: }
1.1.1.7 root 399: #endif
400: // Encrypt the random plaintext and write it to the disk
1.1.1.6 root 401: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
1.1.1.8 root 402: cryptoInfo) == FALSE)
1.1 root 403: goto fail;
404: }
1.1.1.3 root 405: UpdateProgressBar (nSecNo);
1.1 root 406: }
1.1.1.3 root 407: else
408: UpdateProgressBar (ft->num_sectors);
1.1.1.8 root 409:
410: if (write_buf_cnt != 0
411: #ifdef _WIN32
412: && _lwrite ((HFILE)dev, write_buf, write_buf_cnt) == HFILE_ERROR)
413: #else
414: && fwrite (write_buf, 1, write_buf_cnt, (FILE *)dev) != (size_t)write_buf_cnt)
415: #endif
1.1 root 416: goto fail;
417:
418: TCfree (write_buf);
1.1.1.7 root 419: burn (temporaryKey, sizeof(temporaryKey));
1.1 root 420: return 0;
421:
1.1.1.7 root 422: fail:
1.1 root 423:
424: TCfree (write_buf);
1.1.1.7 root 425: burn (temporaryKey, sizeof(temporaryKey));
1.1 root 426: return ERR_OS_ERROR;
427: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.