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

1.1.1.2 ! root        1: /* Copyright (C) 2004 TrueCrypt Foundation
1.1       root        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
1.1.1.2 ! root      397:                RandgetBytes (key, MAX_CIPHER_KEY, FALSE); 
        !           398:                RandgetBytes (cryptoInfo->iv, sizeof cryptoInfo->iv, FALSE); 
1.1       root      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: }

unix.superglobalmegacorp.com

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