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

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

unix.superglobalmegacorp.com

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