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

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

unix.superglobalmegacorp.com

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