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

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

unix.superglobalmegacorp.com

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