|
|
1.1.1.10! root 1: /* ! 2: Legal Notice: The source code contained in this file has been derived from ! 3: the source code of Encryption for the Masses 2.02a, which is Copyright (c) ! 4: Paul Le Roux and which is covered by the 'License Agreement for Encryption ! 5: for the Masses'. Modifications and additions to that source code contained ! 6: in this file are Copyright (c) TrueCrypt Foundation and are covered by the ! 7: TrueCrypt License 2.2 the full text of which is contained in the file ! 8: License.txt included in TrueCrypt binary and source code distribution ! 9: packages. */ ! 10: ! 11: #include <stdlib.h> ! 12: #include <string.h> ! 13: #include <time.h> 1.1.1.6 root 14: 15: #include "Tcdefs.h" 16: 17: #include "Crypto.h" 1.1.1.10! root 18: #include "Common/Endian.h" 1.1.1.6 root 19: #include "Format.h" 20: #include "Fat.h" 21: #include "Progress.h" 1.1.1.8 root 22: #include "Random.h" 1.1 root 23: 24: void 25: GetFatParams (fatparams * ft) 26: { 1.1.1.10! root 27: unsigned int fatsecs; 1.1.1.5 root 28: if(ft->cluster_size == 0) // 'Default' cluster size 1.1 root 29: { 1.1.1.8 root 30: if (ft->num_sectors * 512LL >= 256*BYTES_PER_GB) 1.1 root 31: ft->cluster_size = 128; 1.1.1.8 root 32: else if (ft->num_sectors * 512LL >= 64*BYTES_PER_GB) 1.1 root 33: ft->cluster_size = 64; 1.1.1.8 root 34: else if (ft->num_sectors * 512LL >= 16*BYTES_PER_GB) 1.1 root 35: ft->cluster_size = 32; 1.1.1.8 root 36: else if (ft->num_sectors * 512LL >= 8*BYTES_PER_GB) 1.1 root 37: ft->cluster_size = 16; 1.1.1.8 root 38: else if (ft->num_sectors * 512LL >= 128*BYTES_PER_MB) 1.1 root 39: ft->cluster_size = 8; 1.1.1.8 root 40: else if (ft->num_sectors * 512LL >= 64*BYTES_PER_MB) 1.1 root 41: ft->cluster_size = 4; 1.1.1.8 root 42: else if (ft->num_sectors * 512LL >= 32*BYTES_PER_MB) 1.1 root 43: ft->cluster_size = 2; 44: else 45: ft->cluster_size = 1; 46: } 47: 48: // Geometry always set to SECTORS/1/1 49: ft->secs_track = 1; 50: ft->heads = 1; 51: 52: ft->dir_entries = 512; 53: ft->fats = 2; 1.1.1.6 root 54: ft->create_time = (unsigned int) time (NULL); 1.1 root 55: ft->media = 0xf8; 56: ft->sector_size = SECTOR_SIZE; 1.1.1.6 root 57: ft->hidden = 63; 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.6 root 71: ft->reserved = 8; 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.6 root 80: ft->reserved = 38; 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: { 94: ft->sectors = ft->num_sectors; 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.10! root 138: *(__int16 *)(boot + cnt) = LE16(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.10! root 172: *(__int32 *)(boot + cnt) = LE32(ft->create_time); /* vol id */ 1.1 root 173: cnt += 4; 1.1.1.6 root 174: memcpy (boot + cnt, ft->volume_name, 11); /* vol title */ 1.1 root 175: cnt += 11; 176: 177: switch(ft->size_fat) /* filesystem type */ 178: { 179: case 12: memcpy (boot + cnt, "FAT12 ", 8); break; 180: case 16: memcpy (boot + cnt, "FAT16 ", 8); break; 181: case 32: memcpy (boot + cnt, "FAT32 ", 8); break; 182: } 183: cnt += 8; 184: 185: memset (boot + cnt, 0, ft->size_fat==32 ? 420:448); /* boot code */ 186: cnt += ft->size_fat==32 ? 420:448; 187: boot[cnt++] = 0x55; 188: boot[cnt++] = 0xaa; /* boot sig */ 189: } 190: 1.1.1.10! root 191: 1.1 root 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.9 root 359: // Temporary master key 360: if (!RandgetBytes (temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE)) 361: goto fail; 362: // Secondary key (LRW mode) 363: if (!RandgetBytes (cryptoInfo->iv, sizeof cryptoInfo->iv, FALSE)) 364: goto fail; 1.1.1.6 root 365: 1.1.1.7 root 366: retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks); 1.1.1.6 root 367: if (retVal != 0) 1.1.1.7 root 368: { 369: burn (temporaryKey, sizeof(temporaryKey)); 1.1.1.6 root 370: return retVal; 1.1.1.7 root 371: } 372: if (!EAInitMode (cryptoInfo)) 373: { 374: burn (temporaryKey, sizeof(temporaryKey)); 375: return ERR_MODE_INIT_FAILED; 376: } 1.1 root 377: 1.1.1.6 root 378: x = ft->num_sectors - ft->reserved - ft->size_root_dir / SECTOR_SIZE - ft->fat_length * 2; 1.1 root 379: while (x--) 380: { 1.1.1.7 root 381: /* Generate random plaintext. Note that reused plaintext blocks are not a concern 382: here since LRW mode is designed to hide patterns. Furthermore, patterns in plaintext 383: do occur commonly on media in the "real world", so it might actually be a fatal 384: mistake to try to avoid them completely. */ 1.1.1.9 root 385: 386: #if RNG_POOL_SIZE > SECTOR_SIZE 387: #error RNG_POOL_SIZE > SECTOR_SIZE 388: #endif 389: 390: #ifdef _WIN32 391: if (!RandpeekBytes (sector, RNG_POOL_SIZE) 392: || !RandpeekBytes (sector + RNG_POOL_SIZE, SECTOR_SIZE - RNG_POOL_SIZE)) 393: goto fail; 1.1.1.7 root 394: #else 1.1.1.9 root 395: if ((nSecNo & 0x3fff) == 0) 396: { 397: if (!RandgetBytes (sector, RNG_POOL_SIZE, FALSE) 398: || !RandgetBytes (sector + RNG_POOL_SIZE, SECTOR_SIZE - RNG_POOL_SIZE, FALSE)) 399: goto fail; 400: } 1.1.1.7 root 401: #endif 402: // Encrypt the random plaintext and write it to the disk 1.1.1.6 root 403: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, 1.1.1.8 root 404: cryptoInfo) == FALSE) 1.1 root 405: goto fail; 406: } 1.1.1.3 root 407: UpdateProgressBar (nSecNo); 1.1 root 408: } 1.1.1.3 root 409: else 410: UpdateProgressBar (ft->num_sectors); 1.1.1.8 root 411: 412: if (write_buf_cnt != 0 413: #ifdef _WIN32 414: && _lwrite ((HFILE)dev, write_buf, write_buf_cnt) == HFILE_ERROR) 415: #else 416: && fwrite (write_buf, 1, write_buf_cnt, (FILE *)dev) != (size_t)write_buf_cnt) 417: #endif 1.1 root 418: goto fail; 419: 420: TCfree (write_buf); 1.1.1.7 root 421: burn (temporaryKey, sizeof(temporaryKey)); 1.1 root 422: return 0; 423: 1.1.1.7 root 424: fail: 1.1 root 425: 426: TCfree (write_buf); 1.1.1.7 root 427: burn (temporaryKey, sizeof(temporaryKey)); 1.1 root 428: return ERR_OS_ERROR; 429: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.