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