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