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