|
|
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 ! 6: the original source code (contained in this file) and all other portions of ! 7: this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed ! 8: by the TrueCrypt License 2.4 the full text of which is contained in the ! 9: file License.txt included in TrueCrypt binary and source code distribution 1.1.1.10 root 10: packages. */ 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; 1.1.1.6 root 55: ft->create_time = (unsigned int) time (NULL); 1.1 root 56: ft->media = 0xf8; 57: ft->sector_size = SECTOR_SIZE; 1.1.1.11 root 58: ft->hidden = 0; 1.1 root 59: 60: ft->size_root_dir = ft->dir_entries * 32; 61: 1.1.1.6 root 62: // FAT12 1.1 root 63: ft->size_fat = 12; 1.1.1.6 root 64: ft->reserved = 2; 65: fatsecs = ft->num_sectors - (ft->size_root_dir + SECTOR_SIZE - 1) / SECTOR_SIZE - ft->reserved; 66: ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) / (ft->cluster_size * SECTOR_SIZE + 3)); 67: ft->fat_length = (((ft->cluster_count * 3 + 1) >> 1) + SECTOR_SIZE - 1) / SECTOR_SIZE; 1.1 root 68: 1.1.1.6 root 69: if (ft->cluster_count >= 4085) // FAT16 1.1 root 70: { 71: ft->size_fat = 16; 1.1.1.11 root 72: ft->reserved = 2; 1.1.1.6 root 73: fatsecs = ft->num_sectors - (ft->size_root_dir + SECTOR_SIZE - 1) / SECTOR_SIZE - ft->reserved; 74: ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) / (ft->cluster_size * SECTOR_SIZE + 4)); 75: ft->fat_length = (ft->cluster_count * 2 + SECTOR_SIZE - 1) / SECTOR_SIZE; 1.1 root 76: } 1.1.1.6 root 77: 78: if(ft->cluster_count >= 65525) // FAT32 1.1 root 79: { 80: ft->size_fat = 32; 1.1.1.11 root 81: ft->reserved = 32; 1.1.1.6 root 82: fatsecs = ft->num_sectors - ft->reserved; 1.1 root 83: ft->size_root_dir = ft->cluster_size * SECTOR_SIZE; 1.1.1.6 root 84: ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) / (ft->cluster_size * SECTOR_SIZE + 8)); 85: ft->fat_length = (ft->cluster_count * 4 + SECTOR_SIZE - 1) / SECTOR_SIZE; 1.1 root 86: } 87: 88: if (ft->num_sectors >= 65536 || ft->size_fat == 32) 89: { 90: ft->sectors = 0; 91: ft->total_sect = ft->num_sectors; 92: } 93: else 94: { 95: ft->sectors = ft->num_sectors; 96: ft->total_sect = 0; 97: } 98: } 99: 100: void 101: PutBoot (fatparams * ft, unsigned char *boot) 102: { 103: int cnt = 0; 104: 105: boot[cnt++] = 0xeb; /* boot jump */ 106: boot[cnt++] = 0x3c; 107: boot[cnt++] = 0x90; 1.1.1.6 root 108: memcpy (boot + cnt, "MSDOS5.0", 8); /* system id */ 1.1 root 109: cnt += 8; 1.1.1.10 root 110: *(__int16 *)(boot + cnt) = LE16(ft->sector_size); /* bytes per sector */ 1.1 root 111: cnt += 2; 1.1.1.10 root 112: boot[cnt++] = (__int8) ft->cluster_size; /* sectors per cluster */ 113: *(__int16 *)(boot + cnt) = LE16(ft->reserved); /* reserved sectors */ 1.1.1.6 root 114: cnt += 2; 1.1.1.10 root 115: boot[cnt++] = (__int8) ft->fats; /* 2 fats */ 1.1 root 116: 117: if(ft->size_fat == 32) 118: { 119: boot[cnt++] = 0x00; 120: boot[cnt++] = 0x00; 121: } 122: else 123: { 1.1.1.10 root 124: *(__int16 *)(boot + cnt) = LE16(ft->dir_entries); /* 512 root entries */ 1.1 root 125: cnt += 2; 126: } 127: 1.1.1.10 root 128: *(__int16 *)(boot + cnt) = LE16(ft->sectors); /* # sectors */ 1.1 root 129: cnt += 2; 1.1.1.10 root 130: boot[cnt++] = (__int8) ft->media; /* media byte */ 1.1 root 131: 132: if(ft->size_fat == 32) 133: { 134: boot[cnt++] = 0x00; 135: boot[cnt++] = 0x00; 136: } 137: else 138: { 1.1.1.10 root 139: *(__int16 *)(boot + cnt) = LE16(ft->fat_length); /* fat size */ 1.1 root 140: cnt += 2; 141: } 142: 1.1.1.10 root 143: *(__int16 *)(boot + cnt) = LE16(ft->secs_track); /* # sectors per track */ 1.1 root 144: cnt += 2; 1.1.1.10 root 145: *(__int16 *)(boot + cnt) = LE16(ft->heads); /* # heads */ 1.1 root 146: cnt += 2; 1.1.1.10 root 147: *(__int32 *)(boot + cnt) = LE32(ft->hidden); /* # hidden sectors */ 1.1.1.6 root 148: cnt += 4; 1.1.1.10 root 149: *(__int32 *)(boot + cnt) = LE32(ft->total_sect); /* # huge sectors */ 1.1 root 150: cnt += 4; 151: 152: if(ft->size_fat == 32) 153: { 1.1.1.10 root 154: *(__int32 *)(boot + cnt) = LE32(ft->fat_length); cnt += 4; /* fat size 32 */ 1.1.1.6 root 155: boot[cnt++] = 0x00; /* ExtFlags */ 1.1 root 156: boot[cnt++] = 0x00; 157: boot[cnt++] = 0x00; /* FSVer */ 158: boot[cnt++] = 0x00; 159: boot[cnt++] = 0x02; /* RootClus */ 160: boot[cnt++] = 0x00; 161: boot[cnt++] = 0x00; 162: boot[cnt++] = 0x00; 163: boot[cnt++] = 0x01; /* FSInfo */ 164: boot[cnt++] = 0x00; 165: boot[cnt++] = 0x06; /* BkBootSec */ 166: boot[cnt++] = 0x00; 167: memset(boot+cnt, 0, 12); cnt+=12; /* Reserved */ 168: } 169: 1.1.1.6 root 170: boot[cnt++] = 0x00; /* drive number */ // FIXED 80 > 00 1.1 root 171: boot[cnt++] = 0x00; /* reserved */ 172: boot[cnt++] = 0x29; /* boot sig */ 1.1.1.10 root 173: *(__int32 *)(boot + cnt) = LE32(ft->create_time); /* vol id */ 1.1 root 174: cnt += 4; 1.1.1.6 root 175: memcpy (boot + cnt, ft->volume_name, 11); /* vol title */ 1.1 root 176: cnt += 11; 177: 178: switch(ft->size_fat) /* filesystem type */ 179: { 180: case 12: memcpy (boot + cnt, "FAT12 ", 8); break; 181: case 16: memcpy (boot + cnt, "FAT16 ", 8); break; 182: case 32: memcpy (boot + cnt, "FAT32 ", 8); break; 183: } 184: cnt += 8; 185: 186: memset (boot + cnt, 0, ft->size_fat==32 ? 420:448); /* boot code */ 187: cnt += ft->size_fat==32 ? 420:448; 188: boot[cnt++] = 0x55; 189: boot[cnt++] = 0xaa; /* boot sig */ 190: } 191: 1.1.1.10 root 192: 1.1 root 193: /* FAT32 FSInfo */ 194: PutFSInfo (unsigned char *sector) 195: { 1.1.1.6 root 196: memset (sector, 0, 512); 197: sector[3]=0x41; /* LeadSig */ 198: sector[2]=0x61; 199: sector[1]=0x52; 200: sector[0]=0x52; 201: sector[484+3]=0x61; /* StrucSig */ 202: sector[484+2]=0x41; 203: sector[484+1]=0x72; 204: sector[484+0]=0x72; 205: sector[488+3]=0xff; /* Free_Count */ 206: sector[488+2]=0xff; 207: sector[488+1]=0xff; 208: sector[488+0]=0xff; 209: sector[492+3]=0xff; /* Nxt_Free */ 210: sector[492+2]=0xff; 211: sector[492+1]=0xff; 212: sector[492+0]=0xff; 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: #ifdef _WIN32 231: LARGE_INTEGER startOffset; 232: LARGE_INTEGER newOffset; 233: 1.1.1.4 root 234: // Seek to start sector 235: startOffset.QuadPart = startSector * SECTOR_SIZE; 1.1.1.6 root 236: if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN) 237: || newOffset.QuadPart != startOffset.QuadPart) 1.1.1.4 root 238: { 239: return ERR_VOL_SEEKING; 240: } 1.1.1.8 root 241: #endif 1.1 root 242: 1.1.1.4 root 243: /* Write the data area */ 1.1 root 244: 1.1.1.8 root 245: write_buf = (char *)TCalloc (WRITE_BUF_SIZE); 1.1 root 246: memset (sector, 0, sizeof (sector)); 247: 248: PutBoot (ft, (unsigned char *) sector); 1.1.1.6 root 249: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, 1.1.1.8 root 250: cryptoInfo) == FALSE) 1.1 root 251: goto fail; 252: 253: /* fat32 boot area */ 254: if (ft->size_fat == 32) 255: { 256: /* fsinfo */ 257: PutFSInfo((unsigned char *) sector); 1.1.1.6 root 258: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, 1.1.1.8 root 259: cryptoInfo) == FALSE) 1.1 root 260: goto fail; 261: 262: /* reserved */ 1.1.1.4 root 263: while (nSecNo - startSector < 6) 1.1 root 264: { 265: memset (sector, 0, sizeof (sector)); 266: sector[508+3]=0xaa; /* TrailSig */ 267: sector[508+2]=0x55; 1.1.1.6 root 268: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, 1.1.1.8 root 269: cryptoInfo) == FALSE) 1.1 root 270: goto fail; 271: } 272: 273: /* bootsector backup */ 274: memset (sector, 0, sizeof (sector)); 275: PutBoot (ft, (unsigned char *) sector); 1.1.1.6 root 276: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, 1.1.1.8 root 277: cryptoInfo) == FALSE) 1.1 root 278: goto fail; 279: 280: PutFSInfo((unsigned char *) sector); 1.1.1.6 root 281: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, 1.1.1.8 root 282: cryptoInfo) == FALSE) 1.1 root 283: goto fail; 1.1.1.6 root 284: } 1.1 root 285: 1.1.1.6 root 286: /* reserved */ 1.1.1.8 root 287: while (nSecNo - startSector < (unsigned int)ft->reserved) 1.1.1.6 root 288: { 289: memset (sector, 0, sizeof (sector)); 290: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, 1.1.1.8 root 291: cryptoInfo) == FALSE) 1.1.1.6 root 292: goto fail; 1.1 root 293: } 294: 295: /* write fat */ 296: for (x = 1; x <= ft->fats; x++) 297: { 298: for (n = 0; n < ft->fat_length; n++) 299: { 300: memset (sector, 0, SECTOR_SIZE); 301: 302: if (n == 0) 303: { 304: unsigned char fat_sig[12]; 305: if (ft->size_fat == 32) 306: { 307: fat_sig[0] = (unsigned char) ft->media; 308: fat_sig[1] = fat_sig[2] = 0xff; 309: fat_sig[3] = 0x0f; 310: fat_sig[4] = fat_sig[5] = fat_sig[6] = 0xff; 311: fat_sig[7] = 0x0f; 312: fat_sig[8] = fat_sig[9] = fat_sig[10] = 0xff; 313: fat_sig[11] = 0x0f; 314: memcpy (sector, fat_sig, 12); 315: } 316: else if (ft->size_fat == 16) 317: { 318: fat_sig[0] = (unsigned char) ft->media; 319: fat_sig[1] = 0xff; 320: fat_sig[2] = 0xff; 321: fat_sig[3] = 0xff; 322: memcpy (sector, fat_sig, 4); 323: } 324: else if (ft->size_fat == 12) 325: { 326: fat_sig[0] = (unsigned char) ft->media; 327: fat_sig[1] = 0xff; 328: fat_sig[2] = 0xff; 329: fat_sig[3] = 0x00; 330: memcpy (sector, fat_sig, 4); 331: } 332: } 333: 1.1.1.6 root 334: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, 1.1.1.8 root 335: cryptoInfo) == FALSE) 1.1 root 336: goto fail; 337: } 338: } 339: 340: 341: /* write rootdir */ 342: for (x = 0; x < ft->size_root_dir / SECTOR_SIZE; x++) 343: { 344: memset (sector, 0, SECTOR_SIZE); 1.1.1.6 root 345: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, 1.1.1.8 root 346: cryptoInfo) == FALSE) 1.1 root 347: goto fail; 348: 349: } 350: 1.1.1.7 root 351: /* Fill the rest of the data area with random data */ 1.1.1.4 root 352: 1.1 root 353: if(!quickFormat) 354: { 1.1.1.7 root 355: /* Generate a random temporary key set to be used for "dummy" encryption that will fill 356: the free disk space (data area) with random data. This is necessary for plausible 357: deniability of hidden volumes (and also reduces the amount of predictable plaintext 358: within the volume). */ 1.1 root 359: 1.1.1.9 root 360: // Temporary master key 361: if (!RandgetBytes (temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE)) 362: goto fail; 1.1.1.12! root 363: ! 364: // Temporary secondary key (XTS mode) ! 365: if (!RandgetBytes (cryptoInfo->k2, sizeof cryptoInfo->k2, FALSE)) 1.1.1.9 root 366: goto fail; 1.1.1.6 root 367: 1.1.1.7 root 368: retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks); 1.1.1.12! root 369: if (retVal != ERR_SUCCESS) 1.1.1.7 root 370: { 371: burn (temporaryKey, sizeof(temporaryKey)); 1.1.1.6 root 372: return retVal; 1.1.1.7 root 373: } 374: if (!EAInitMode (cryptoInfo)) 375: { 376: burn (temporaryKey, sizeof(temporaryKey)); 377: return ERR_MODE_INIT_FAILED; 378: } 1.1 root 379: 1.1.1.6 root 380: x = ft->num_sectors - ft->reserved - ft->size_root_dir / SECTOR_SIZE - ft->fat_length * 2; 1.1 root 381: while (x--) 382: { 1.1.1.12! root 383: /* Generate random plaintext. Note that reused plaintext blocks are not a concern here ! 384: since XTS mode is designed to hide patterns. Furthermore, patterns in plaintext do ! 385: occur commonly on media in the "real world", so it might actually be a fatal mistake ! 386: to try to avoid them completely. */ 1.1.1.9 root 387: 1.1.1.12! root 388: #if RNG_POOL_SIZE < SECTOR_SIZE ! 389: #error RNG_POOL_SIZE < SECTOR_SIZE 1.1.1.9 root 390: #endif 391: 392: #ifdef _WIN32 1.1.1.12! root 393: if (!RandpeekBytes (sector, SECTOR_SIZE)) 1.1.1.9 root 394: goto fail; 1.1.1.7 root 395: #else 1.1.1.9 root 396: if ((nSecNo & 0x3fff) == 0) 397: { 1.1.1.12! root 398: if (!RandgetBytes (sector, SECTOR_SIZE, FALSE)) 1.1.1.9 root 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.