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

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

unix.superglobalmegacorp.com

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