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