|
|
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.