Annotation of truecrypt/common/fat.c, revision 1.1.1.6

1.1.1.6 ! root        1: /* Legal Notice: The source code contained in this file has been derived from
        !             2:    the source code of Encryption for the Masses 2.02a, which is Copyright (c)
        !             3:    1998-99 Paul Le Roux and which is covered by the 'License Agreement for
        !             4:    Encryption for the Masses'. Modifications and additions to that source code
        !             5:    contained in this file are Copyright (c) 2004-2005 TrueCrypt Foundation and
        !             6:    Copyright (c) 2004 TrueCrypt Team, and are covered by TrueCrypt License 2.0
        !             7:    the full text of which is contained in the file License.txt included in
        !             8:    TrueCrypt binary and source code distribution archives.  */
        !             9: 
        !            10: #include "Tcdefs.h"
        !            11: 
        !            12: #include "Crypto.h"
        !            13: #include "Random.h"
        !            14: #include "Format.h"
        !            15: #include "Fat.h"
        !            16: #include "Progress.h"
1.1       root       17: 
                     18: #include <time.h>
                     19: 
                     20: void
                     21: GetFatParams (fatparams * ft)
                     22: {
                     23:        int fatsecs;
1.1.1.5   root       24:        if(ft->cluster_size == 0)       // 'Default' cluster size
1.1       root       25:        {
1.1.1.6 ! root       26:                if (ft->num_sectors * 512I64 >= 256*BYTES_PER_GB)
1.1       root       27:                        ft->cluster_size = 128;
1.1.1.6 ! root       28:                else if (ft->num_sectors * 512I64 >= 64*BYTES_PER_GB)
1.1       root       29:                        ft->cluster_size = 64;
1.1.1.6 ! root       30:                else if (ft->num_sectors * 512I64 >= 16*BYTES_PER_GB)
1.1       root       31:                        ft->cluster_size = 32;
1.1.1.6 ! root       32:                else if (ft->num_sectors * 512I64 >= 8*BYTES_PER_GB)
1.1       root       33:                        ft->cluster_size = 16;
1.1.1.6 ! root       34:                else if (ft->num_sectors * 512I64 >= 128*BYTES_PER_MB)
1.1       root       35:                        ft->cluster_size = 8;
1.1.1.6 ! root       36:                else if (ft->num_sectors * 512I64 >= 64*BYTES_PER_MB)
1.1       root       37:                        ft->cluster_size = 4;
1.1.1.6 ! root       38:                else if (ft->num_sectors * 512I64 >= 32*BYTES_PER_MB)
1.1       root       39:                        ft->cluster_size = 2;
                     40:                else
                     41:                        ft->cluster_size = 1;
                     42:        }
                     43: 
                     44:        // Geometry always set to SECTORS/1/1
                     45:        ft->secs_track = 1; 
                     46:        ft->heads = 1; 
                     47: 
                     48:        ft->dir_entries = 512;
                     49:        ft->fats = 2;
1.1.1.6 ! root       50:        ft->create_time = (unsigned int) time (NULL);
1.1       root       51:        ft->media = 0xf8;
                     52:        ft->sector_size = SECTOR_SIZE;
1.1.1.6 ! root       53:        ft->hidden = 63;
1.1       root       54: 
                     55:        ft->size_root_dir = ft->dir_entries * 32;
                     56: 
1.1.1.6 ! root       57:        // FAT12
1.1       root       58:        ft->size_fat = 12;
1.1.1.6 ! root       59:        ft->reserved = 2;
        !            60:        fatsecs = ft->num_sectors - (ft->size_root_dir + SECTOR_SIZE - 1) / SECTOR_SIZE - ft->reserved;
        !            61:        ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) / (ft->cluster_size * SECTOR_SIZE + 3));
        !            62:        ft->fat_length = (((ft->cluster_count * 3 + 1) >> 1) + SECTOR_SIZE - 1) / SECTOR_SIZE;
1.1       root       63: 
1.1.1.6 ! root       64:        if (ft->cluster_count >= 4085) // FAT16
1.1       root       65:        {
                     66:                ft->size_fat = 16;
1.1.1.6 ! root       67:                ft->reserved = 8;
        !            68:                fatsecs = ft->num_sectors - (ft->size_root_dir + SECTOR_SIZE - 1) / SECTOR_SIZE - ft->reserved;
        !            69:                ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) / (ft->cluster_size * SECTOR_SIZE + 4));
        !            70:                ft->fat_length = (ft->cluster_count * 2 + SECTOR_SIZE - 1) / SECTOR_SIZE;
1.1       root       71:        }
1.1.1.6 ! root       72:        
        !            73:        if(ft->cluster_count >= 65525) // FAT32
1.1       root       74:        {
                     75:                ft->size_fat = 32;
1.1.1.6 ! root       76:                ft->reserved = 38;
        !            77:                fatsecs = ft->num_sectors - ft->reserved;
1.1       root       78:                ft->size_root_dir = ft->cluster_size * SECTOR_SIZE;
1.1.1.6 ! root       79:                ft->cluster_count = (int) (((__int64) fatsecs * SECTOR_SIZE) / (ft->cluster_size * SECTOR_SIZE + 8));
        !            80:                ft->fat_length = (ft->cluster_count * 4 + SECTOR_SIZE - 1) / SECTOR_SIZE;
1.1       root       81:        }
                     82: 
                     83:        if (ft->num_sectors >= 65536 || ft->size_fat == 32)
                     84:        {
                     85:                ft->sectors = 0;
                     86:                ft->total_sect = ft->num_sectors;
                     87:        }
                     88:        else
                     89:        {
                     90:                ft->sectors = ft->num_sectors;
                     91:                ft->total_sect = 0;
                     92:        }
                     93: }
                     94: 
                     95: void
                     96: PutBoot (fatparams * ft, unsigned char *boot)
                     97: {
                     98:        int cnt = 0;
                     99: 
                    100:        boot[cnt++] = 0xeb;     /* boot jump */
                    101:        boot[cnt++] = 0x3c;
                    102:        boot[cnt++] = 0x90;
1.1.1.6 ! root      103:        memcpy (boot + cnt, "MSDOS5.0", 8); /* system id */
1.1       root      104:        cnt += 8;
1.1.1.6 ! root      105:        memcpy (boot + cnt, &ft->sector_size, 2);       /* bytes per sector */
1.1       root      106:        cnt += 2;
1.1.1.6 ! root      107:        memcpy (boot + cnt, &ft->cluster_size, 1);      /* sectors per cluster */
1.1       root      108:        cnt++;
1.1.1.6 ! root      109:        memcpy (boot + cnt, &ft->reserved, 2);          /* reserved sectors */
        !           110:        cnt += 2;
        !           111:        memcpy (boot + cnt, &ft->fats, 1);                      /* 2 fats */
1.1       root      112:        cnt++;
                    113: 
                    114:        if(ft->size_fat == 32)
                    115:        {
                    116:                boot[cnt++] = 0x00;
                    117:                boot[cnt++] = 0x00;
                    118:        }
                    119:        else
                    120:        {
1.1.1.6 ! root      121:                memcpy (boot + cnt, &ft->dir_entries, 2);       /* 512 root entries */
1.1       root      122:                cnt += 2;
                    123:        }
                    124: 
1.1.1.6 ! root      125:        memcpy (boot + cnt, &ft->sectors, 2);                   /* # sectors */
1.1       root      126:        cnt += 2;
1.1.1.6 ! root      127:        memcpy (boot + cnt, &ft->media, 1);                             /* media byte */
1.1       root      128:        cnt++;
                    129: 
                    130:        if(ft->size_fat == 32)  
                    131:        {
                    132:                boot[cnt++] = 0x00;
                    133:                boot[cnt++] = 0x00;
                    134:        }
                    135:        else 
                    136:        { 
1.1.1.6 ! root      137:                memcpy (boot + cnt, &ft->fat_length, 2);        /* fat size */
1.1       root      138:                cnt += 2;
                    139:        }
                    140: 
1.1.1.6 ! root      141:        memcpy (boot + cnt, &ft->secs_track, 2);        /* # sectors per track */
1.1       root      142:        cnt += 2;
1.1.1.6 ! root      143:        memcpy (boot + cnt, &ft->heads, 2);                     /* # heads */
1.1       root      144:        cnt += 2;
1.1.1.6 ! root      145:        memcpy (boot + cnt, &ft->hidden, 4);            /* # hidden sectors */
        !           146:        cnt += 4;
        !           147:        memcpy (boot + cnt, &ft->total_sect, 4);        /* # huge sectors */
1.1       root      148:        cnt += 4;
                    149: 
                    150:        if(ft->size_fat == 32)
                    151:        {
                    152:                memcpy (boot + cnt, &ft->fat_length, 4); cnt += 4;      /* fat size 32 */
1.1.1.6 ! root      153:                boot[cnt++] = 0x00;     /* ExtFlags */
1.1       root      154:                boot[cnt++] = 0x00;
                    155:                boot[cnt++] = 0x00;     /* FSVer */
                    156:                boot[cnt++] = 0x00;
                    157:                boot[cnt++] = 0x02;     /* RootClus */
                    158:                boot[cnt++] = 0x00;
                    159:                boot[cnt++] = 0x00;
                    160:                boot[cnt++] = 0x00;
                    161:                boot[cnt++] = 0x01;     /* FSInfo */
                    162:                boot[cnt++] = 0x00;
                    163:                boot[cnt++] = 0x06;     /* BkBootSec */
                    164:                boot[cnt++] = 0x00;
                    165:                memset(boot+cnt, 0, 12); cnt+=12;       /* Reserved */
                    166:        }
                    167: 
1.1.1.6 ! root      168:        boot[cnt++] = 0x00;     /* drive number */   // FIXED 80 > 00
1.1       root      169:        boot[cnt++] = 0x00;     /* reserved */
                    170:        boot[cnt++] = 0x29;     /* boot sig */
1.1.1.6 ! root      171:        memcpy (boot + cnt, &ft->create_time, 4);       /* vol id */
1.1       root      172:        cnt += 4;
1.1.1.6 ! root      173:        memcpy (boot + cnt, ft->volume_name, 11);       /* vol title */
1.1       root      174:        cnt += 11;
                    175: 
                    176:        switch(ft->size_fat) /* filesystem type */
                    177:        {
                    178:                case 12: memcpy (boot + cnt, "FAT12   ", 8); break;
                    179:                case 16: memcpy (boot + cnt, "FAT16   ", 8); break;
                    180:                case 32: memcpy (boot + cnt, "FAT32   ", 8); break;
                    181:        }
                    182:        cnt += 8;
                    183: 
                    184:        memset (boot + cnt, 0, ft->size_fat==32 ? 420:448);     /* boot code */
                    185:        cnt += ft->size_fat==32 ? 420:448;
                    186:        boot[cnt++] = 0x55;
                    187:        boot[cnt++] = 0xaa;     /* boot sig */
                    188: }
                    189: 
                    190: /* FAT32 FSInfo */
                    191: PutFSInfo (unsigned char *sector)
                    192: {
1.1.1.6 ! root      193:        memset (sector, 0, 512);
        !           194:        sector[3]=0x41; /* LeadSig */
        !           195:        sector[2]=0x61; 
        !           196:        sector[1]=0x52; 
        !           197:        sector[0]=0x52; 
        !           198:        sector[484+3]=0x61; /* StrucSig */
        !           199:        sector[484+2]=0x41; 
        !           200:        sector[484+1]=0x72; 
        !           201:        sector[484+0]=0x72; 
        !           202:        sector[488+3]=0xff; /* Free_Count */
        !           203:        sector[488+2]=0xff;
        !           204:        sector[488+1]=0xff;
        !           205:        sector[488+0]=0xff;
        !           206:        sector[492+3]=0xff; /* Nxt_Free */
        !           207:        sector[492+2]=0xff;
        !           208:        sector[492+1]=0xff;
        !           209:        sector[492+0]=0xff;
        !           210:        sector[508+3]=0xaa; /* TrailSig */
        !           211:        sector[508+2]=0x55;
        !           212:        sector[508+1]=0x00;
        !           213:        sector[508+0]=0x00;
1.1       root      214: }
                    215: 
                    216: 
                    217: int
1.1.1.6 ! root      218: FormatFat (unsigned __int64 startSector, fatparams * ft, HFILE dev, PCRYPTO_INFO cryptoInfo, diskio_f write, BOOL quickFormat)
1.1       root      219: {
                    220:        int write_buf_cnt = 0;
                    221:        char sector[SECTOR_SIZE], *write_buf;
1.1.1.4   root      222:        unsigned __int64 nSecNo = startSector;
                    223:        LARGE_INTEGER startOffset;
                    224:        LARGE_INTEGER newOffset;
1.1       root      225:        int x, n;
1.1.1.6 ! root      226:        int retVal;
1.1       root      227: 
1.1.1.4   root      228:        // Seek to start sector
                    229:        startOffset.QuadPart = startSector * SECTOR_SIZE;
1.1.1.6 ! root      230:        if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN)
        !           231:                || newOffset.QuadPart != startOffset.QuadPart)
1.1.1.4   root      232:        {
                    233:                return ERR_VOL_SEEKING;
                    234:        }
1.1       root      235: 
1.1.1.4   root      236:        /* Write the data area */
1.1       root      237: 
1.1.1.4   root      238:        write_buf = TCalloc (WRITE_BUF_SIZE);
1.1       root      239:        memset (sector, 0, sizeof (sector));
                    240: 
                    241:        PutBoot (ft, (unsigned char *) sector);
1.1.1.6 ! root      242:        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
        !           243:                cryptoInfo, write) == FALSE)
1.1       root      244:                goto fail;
                    245: 
                    246:        /* fat32 boot area */
                    247:        if (ft->size_fat == 32)                         
                    248:        {
                    249:                /* fsinfo */
                    250:                PutFSInfo((unsigned char *) sector);
1.1.1.6 ! root      251:                if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
        !           252:                        cryptoInfo, write) == FALSE)
1.1       root      253:                        goto fail;
                    254: 
                    255:                /* reserved */
1.1.1.4   root      256:                while (nSecNo - startSector < 6)
1.1       root      257:                {
                    258:                        memset (sector, 0, sizeof (sector));
                    259:                        sector[508+3]=0xaa; /* TrailSig */
                    260:                        sector[508+2]=0x55;
1.1.1.6 ! root      261:                        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
        !           262:                                cryptoInfo, write) == FALSE)
1.1       root      263:                                goto fail;
                    264:                }
                    265:                
                    266:                /* bootsector backup */
                    267:                memset (sector, 0, sizeof (sector));
                    268:                PutBoot (ft, (unsigned char *) sector);
1.1.1.6 ! root      269:                if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
        !           270:                                 cryptoInfo, write) == FALSE)
1.1       root      271:                        goto fail;
                    272: 
                    273:                PutFSInfo((unsigned char *) sector);
1.1.1.6 ! root      274:                if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
        !           275:                        cryptoInfo, write) == FALSE)
1.1       root      276:                        goto fail;
1.1.1.6 ! root      277:        }
1.1       root      278: 
1.1.1.6 ! root      279:        /* reserved */
        !           280:        while (nSecNo - startSector < ft->reserved)
        !           281:        {
        !           282:                memset (sector, 0, sizeof (sector));
        !           283:                if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
        !           284:                        cryptoInfo, write) == FALSE)
        !           285:                        goto fail;
1.1       root      286:        }
                    287: 
                    288:        /* write fat */
                    289:        for (x = 1; x <= ft->fats; x++)
                    290:        {
                    291:                for (n = 0; n < ft->fat_length; n++)
                    292:                {
                    293:                        memset (sector, 0, SECTOR_SIZE);
                    294: 
                    295:                        if (n == 0)
                    296:                        {
                    297:                                unsigned char fat_sig[12];
                    298:                                if (ft->size_fat == 32)
                    299:                                {
                    300:                                        fat_sig[0] = (unsigned char) ft->media;
                    301:                                        fat_sig[1] = fat_sig[2] = 0xff;
                    302:                                        fat_sig[3] = 0x0f;
                    303:                                        fat_sig[4] = fat_sig[5] = fat_sig[6] = 0xff;
                    304:                                        fat_sig[7] = 0x0f;
                    305:                                        fat_sig[8] = fat_sig[9] = fat_sig[10] = 0xff;
                    306:                                        fat_sig[11] = 0x0f;
                    307:                                        memcpy (sector, fat_sig, 12);
                    308:                                }                               
                    309:                                else if (ft->size_fat == 16)
                    310:                                {
                    311:                                        fat_sig[0] = (unsigned char) ft->media;
                    312:                                        fat_sig[1] = 0xff;
                    313:                                        fat_sig[2] = 0xff;
                    314:                                        fat_sig[3] = 0xff;
                    315:                                        memcpy (sector, fat_sig, 4);
                    316:                                }
                    317:                                else if (ft->size_fat == 12)
                    318:                                {
                    319:                                        fat_sig[0] = (unsigned char) ft->media;
                    320:                                        fat_sig[1] = 0xff;
                    321:                                        fat_sig[2] = 0xff;
                    322:                                        fat_sig[3] = 0x00;
                    323:                                        memcpy (sector, fat_sig, 4);
                    324:                                }
                    325:                        }
                    326: 
1.1.1.6 ! root      327:                        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
        !           328:                                    cryptoInfo, write) == FALSE)
1.1       root      329:                                goto fail;
                    330:                }
                    331:        }
                    332: 
                    333: 
                    334:        /* write rootdir */
                    335:        for (x = 0; x < ft->size_root_dir / SECTOR_SIZE; x++)
                    336:        {
                    337:                memset (sector, 0, SECTOR_SIZE);
1.1.1.6 ! root      338:                if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
        !           339:                                 cryptoInfo, write) == FALSE)
1.1       root      340:                        goto fail;
                    341: 
                    342:        }
                    343: 
1.1.1.4   root      344:        /* Fill the rest of the data area */
                    345: 
1.1       root      346:        if(!quickFormat)
                    347:        {
1.1.1.4   root      348:                char key[DISKKEY_SIZE];
1.1       root      349: 
1.1.1.4   root      350:                /* Generate a random key and IV to be used for "dummy" encryption that will fill the
                    351:                   free disk space (data area) with random data. That will reduce the amount of
                    352:                   predictable plaintext within the volume and also increase the level of plausible
                    353:                   deniability of hidden volumes. */
                    354:                RandgetBytes (key, DISKKEY_SIZE, FALSE); 
1.1.1.2   root      355:                RandgetBytes (cryptoInfo->iv, sizeof cryptoInfo->iv, FALSE); 
1.1.1.6 ! root      356: 
        !           357:                retVal = EAInit (cryptoInfo->ea, key, cryptoInfo->ks);
        !           358:                if (retVal != 0)
        !           359:                        return retVal;
        !           360: 
1.1.1.4   root      361:                RandgetBytes (sector, 256, FALSE); 
                    362:                RandgetBytes (sector + 256, 256, FALSE); 
1.1       root      363: 
1.1.1.6 ! root      364:                x = ft->num_sectors - ft->reserved - ft->size_root_dir / SECTOR_SIZE - ft->fat_length * 2;
1.1       root      365:                while (x--)
                    366:                {
1.1.1.6 ! root      367:                        if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
        !           368:                                cryptoInfo, write) == FALSE)
1.1       root      369:                                goto fail;
                    370:                }
1.1.1.3   root      371:                UpdateProgressBar (nSecNo);
1.1       root      372:        }
1.1.1.3   root      373:        else
                    374:                UpdateProgressBar (ft->num_sectors);
                    375:                
1.1       root      376:        if (write_buf_cnt != 0 && (*write) (dev, write_buf, write_buf_cnt) == HFILE_ERROR)
                    377:                goto fail;
                    378: 
                    379:        TCfree (write_buf);
                    380:        return 0;
                    381: 
1.1.1.4   root      382:     fail:
1.1       root      383: 
                    384:        TCfree (write_buf);
                    385:        return ERR_OS_ERROR;
                    386: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.