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