Annotation of truecrypt/common/volumes.c, revision 1.1

1.1     ! root        1: /* Copyright (C) 2004 TrueCrypt Team, truecrypt.org
        !             2:    This product uses components written by Paul Le Roux <[email protected]> */
        !             3: 
        !             4: #include "TCdefs.h"
        !             5: 
        !             6: #include <fcntl.h>
        !             7: #include <sys/types.h>
        !             8: #include <sys/stat.h>
        !             9: #include <io.h>
        !            10: #include <time.h>
        !            11: 
        !            12: #include "crypto.h"
        !            13: #include "random.h"
        !            14: #include "endian.h"
        !            15: #include "fat.h"
        !            16: #include "volumes.h"
        !            17: 
        !            18: #include "pkcs5.h"
        !            19: #include "crc.h"
        !            20: 
        !            21: void _cdecl
        !            22: EncryptSector8 (unsigned long *data,
        !            23:                unsigned __int64 secNo,
        !            24:                unsigned long noSectors,
        !            25:                unsigned char *ks,
        !            26:                unsigned char *iv,
        !            27:                int cipher)
        !            28: {
        !            29:        unsigned long sectorIV[2];
        !            30:        unsigned long *IV = (unsigned long *) iv;
        !            31:        unsigned __int64 *IV64 = (unsigned __int64 *) iv;
        !            32:        unsigned long x1, x2;
        !            33:        unsigned long j;
        !            34: 
        !            35:        while (noSectors--)
        !            36:        {
        !            37:                // Sector encryption is implemented by making IV unique for each
        !            38:                // sector and obfuscating cipher text
        !            39:                IV64[0] ^= secNo;
        !            40:                IV64[1] ^= secNo;
        !            41:                IV64[2] ^= secNo;
        !            42: 
        !            43:                sectorIV[0] = IV[0];
        !            44:                sectorIV[1] = IV[1];
        !            45: 
        !            46:                x1 = crc32long ( &IV[2] ) ^ crc32long ( &IV[5] );
        !            47:                x2 = crc32long ( &IV[3] ) ^ crc32long ( &IV[4] );
        !            48: 
        !            49:                IV64[0] ^= secNo;
        !            50:                IV64[1] ^= secNo;
        !            51:                IV64[2] ^= secNo;
        !            52: 
        !            53:                // CBC encrypt the entire sector
        !            54:                for (j = 0; j < 64; j++)
        !            55:                {
        !            56:                        // CBC
        !            57:                        data[0] ^= sectorIV[0];
        !            58:                        data[1] ^= sectorIV[1];
        !            59: 
        !            60:                        encipher_block (cipher, data, ks);
        !            61: 
        !            62:                        sectorIV[0] = data[0];
        !            63:                        sectorIV[1] = data[1];
        !            64: 
        !            65:                        // Cipher text XOR
        !            66:                        data[0] ^= x1;
        !            67:                        data[1] ^= x2;
        !            68: 
        !            69:                        data += 2;
        !            70:                }
        !            71: 
        !            72:                secNo++;
        !            73:        }
        !            74: }
        !            75: 
        !            76: void
        !            77:   _cdecl
        !            78: DecryptSector8 (unsigned long *data,
        !            79:                unsigned __int64 secNo,
        !            80:                unsigned long noSectors,
        !            81:                unsigned char *ks,
        !            82:                unsigned char *iv,
        !            83:                int cipher)
        !            84: {
        !            85:        unsigned long sectorIV[2];
        !            86:        unsigned long *IV = (unsigned long *) iv;
        !            87:        unsigned __int64 *IV64 = (unsigned __int64 *) iv;
        !            88:        unsigned long x1, x2;
        !            89:        int j;
        !            90: 
        !            91:        while (noSectors--)
        !            92:        {
        !            93:                IV64[0] ^= secNo;
        !            94:                IV64[1] ^= secNo;
        !            95:                IV64[2] ^= secNo;
        !            96: 
        !            97:                sectorIV[0] = IV[0];
        !            98:                sectorIV[1] = IV[1];
        !            99: 
        !           100:                x1 = crc32long ( &IV[2] ) ^ crc32long ( &IV[5] );
        !           101:                x2 = crc32long ( &IV[3] ) ^ crc32long ( &IV[4] );
        !           102: 
        !           103:                IV64[0] ^= secNo;
        !           104:                IV64[1] ^= secNo;
        !           105:                IV64[2] ^= secNo;
        !           106: 
        !           107:                // CBC decrypt the sector
        !           108:                for (j = 0; j < 64; j++)
        !           109:                {
        !           110:                        unsigned long a, b;
        !           111: 
        !           112:                        // Cipher text XOR
        !           113:                        data[0] ^= x1;
        !           114:                        data[1] ^= x2;
        !           115: 
        !           116:                        // CBC
        !           117:                        a = data[0];
        !           118:                        b = data[1];
        !           119: 
        !           120:                        decipher_block (cipher, data, ks);
        !           121: 
        !           122:                        data[0] ^= sectorIV[0];
        !           123:                        data[1] ^= sectorIV[1];
        !           124: 
        !           125:                        sectorIV[0] = a;
        !           126:                        sectorIV[1] = b;
        !           127: 
        !           128:                        data += 2;
        !           129:                }
        !           130: 
        !           131:                secNo++;
        !           132:        }
        !           133: }
        !           134: 
        !           135: // EncryptBuffer
        !           136: //
        !           137: // Encrypts data in buffer
        !           138: // Returns number of bytes encrypted
        !           139: //
        !           140: // len = length of data in bytes
        !           141: int _cdecl 
        !           142: EncryptBuffer (unsigned char *buf,
        !           143:                unsigned long len,
        !           144:                unsigned char *ks,
        !           145:                unsigned char *iv,
        !           146:                int cipher)
        !           147: {
        !           148:        unsigned long *data = (unsigned long *) buf;
        !           149:        unsigned long *IV = (unsigned long *) iv;
        !           150:        unsigned long bufIV[2];
        !           151:        unsigned long j;
        !           152: 
        !           153:        len /= get_block_size (cipher);
        !           154: 
        !           155:        bufIV[0] = IV[0];
        !           156:        bufIV[1] = IV[1];
        !           157: 
        !           158:        if (get_block_size (cipher) == 8)
        !           159:        {
        !           160:                /* CBC encrypt the buffer */
        !           161:                for (j = 0; j < len; j++)
        !           162:                {
        !           163:                        // CBC
        !           164:                        data[0] ^= bufIV[0];
        !           165:                        data[1] ^= bufIV[1];
        !           166: 
        !           167:                        encipher_block (cipher, data, ks);
        !           168: 
        !           169:                        bufIV[0] = data[0];
        !           170:                        bufIV[1] = data[1];
        !           171: 
        !           172:                        // Cipher text XOR
        !           173:                        data[0] ^= IV[2];
        !           174:                        data[1] ^= IV[3];
        !           175: 
        !           176:                        data += 2;
        !           177:                }
        !           178:        }
        !           179:        else
        !           180:                return 0;
        !           181: 
        !           182:        return len;
        !           183: }
        !           184: 
        !           185: // DecryptBuffer
        !           186: //
        !           187: // Decrypts data in buffer
        !           188: // Returns number of bytes encrypted
        !           189: //
        !           190: // len = length of data in bytes
        !           191: 
        !           192: int _cdecl
        !           193: DecryptBuffer (unsigned char *buf,
        !           194:                unsigned long len,
        !           195:                unsigned char *ks,
        !           196:                unsigned char *iv,
        !           197:                int cipher)
        !           198: {
        !           199:        unsigned long *data = (unsigned long *)buf;
        !           200:        unsigned long *IV = (unsigned long *) iv;
        !           201:        unsigned long bufIV[2];
        !           202:        unsigned long j;
        !           203: 
        !           204:        len /= get_block_size (cipher);
        !           205: 
        !           206:        bufIV[0] = IV[0];
        !           207:        bufIV[1] = IV[1];
        !           208: 
        !           209:        if (get_block_size (cipher) == 8)
        !           210:        {
        !           211:                /* CBC encrypt the buffer */
        !           212:                for (j = 0; j < len; j++)
        !           213:                {
        !           214:                        unsigned long a, b;
        !           215: 
        !           216:                        // Cipher text XOR
        !           217:                        data[0] ^= IV[2];
        !           218:                        data[1] ^= IV[3];
        !           219: 
        !           220:                        // CBC
        !           221:                        a = data[0];
        !           222:                        b = data[1];
        !           223: 
        !           224:                        decipher_block (cipher, data, ks);
        !           225: 
        !           226:                        data[0] ^= bufIV[0];
        !           227:                        data[1] ^= bufIV[1];
        !           228: 
        !           229:                        bufIV[0] = a;
        !           230:                        bufIV[1] = b;
        !           231: 
        !           232:                        data += 2;
        !           233:                }
        !           234:        }
        !           235:        else
        !           236:                return 0;
        !           237: 
        !           238:        return len;
        !           239: }
        !           240: 
        !           241: // Volume header structure:
        !           242: //
        !           243: // Offset      Length  Description
        !           244: // ------------------------------------------
        !           245: // Unencrypted:
        !           246: // 0           64              Key salt
        !           247: // Encrypted:
        !           248: // 64          4               Magic 'TRUE'
        !           249: // 68          2               Header version
        !           250: // 70          2               Required program version
        !           251: // 72          4               CRC32 of disk IV and key
        !           252: // 76          8               Volume creation time
        !           253: // 84          8               Header creation time
        !           254: // 92          164             unused
        !           255: // 256         32              Disk IV
        !           256: // 288         224             Disk key
        !           257: 
        !           258: int
        !           259: VolumeReadHeader (char *encryptedHeader, char *lpszPassword, PCRYPTO_INFO * retInfo)
        !           260: {
        !           261:        char header[SECTOR_SIZE];
        !           262:        unsigned char *input = (unsigned char *) header;
        !           263:        KEY_INFO keyInfo;
        !           264:        PCRYPTO_INFO cryptoInfo;
        !           265:        int nStatus = 0, nKeyLen;
        !           266:        char dk[DISKKEY_SIZE];
        !           267:        int pkcs5;
        !           268:        int headerVersion, requiredVersion;
        !           269:        
        !           270:        cryptoInfo = *retInfo = crypto_open ();
        !           271:        if (cryptoInfo == NULL)
        !           272:                return ERR_OUTOFMEMORY;
        !           273: 
        !           274:        crypto_loadkey (&keyInfo, lpszPassword, strlen (lpszPassword));
        !           275: 
        !           276:        // PKCS5 is used to derive header key and IV from user password
        !           277:        memcpy (keyInfo.key_salt, encryptedHeader + HEADER_USERKEY_SALT, USERKEY_SALT_SIZE);
        !           278:        keyInfo.noIterations = USERKEY_ITERATIONS;              
        !           279:        pkcs5 = SHA1;
        !           280: 
        !           281:        if (pkcs5 == SHA1)
        !           282:        {
        !           283:                derive_sha_key (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
        !           284:                USERKEY_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + MAX_CIPHER_KEY);
        !           285:        }
        !           286:        // IV for header decryption
        !           287:        memcpy (cryptoInfo->iv, dk, DISK_IV_SIZE);
        !           288: 
        !           289:        // Test all available ciphers
        !           290:        for (cryptoInfo->cipher = 1; cryptoInfo->cipher <= LAST_CIPHER_ID; cryptoInfo->cipher++)
        !           291:        {
        !           292:                // Copy header for decryption
        !           293:                memcpy (header, encryptedHeader, SECTOR_SIZE);  
        !           294:                input = header;
        !           295: 
        !           296:                // Try to decrypt header 
        !           297:                init_cipher (cryptoInfo->cipher, dk + DISK_IV_SIZE, cryptoInfo->ks);
        !           298: 
        !           299:                DecryptBuffer (header + HEADER_ENCRYPTEDDATA, HEADER_ENCRYPTEDDATASIZE,
        !           300:                                                        cryptoInfo->ks, cryptoInfo->iv, cryptoInfo->cipher);
        !           301: 
        !           302:                input += HEADER_ENCRYPTEDDATA;
        !           303: 
        !           304:                // Magic
        !           305:                if (mgetLong (input) != 'TRUE')
        !           306:                        continue;
        !           307: 
        !           308:                // Header version
        !           309:                headerVersion = mgetWord (input);
        !           310: 
        !           311:                // Required program version
        !           312:                requiredVersion = mgetWord (input);
        !           313: 
        !           314:                // Check CRC of disk IV and key
        !           315:                if (mgetLong (input) != crc32 (header + HEADER_DISKKEY, DISKKEY_SIZE))
        !           316:                        continue;
        !           317: 
        !           318:                // Volume creation time
        !           319:                ((unsigned long *)(&cryptoInfo->volume_creation_time))[1] = mgetLong (input);
        !           320:                ((unsigned long *)(&cryptoInfo->volume_creation_time))[0] = mgetLong (input);
        !           321: 
        !           322:                // Header creation time
        !           323:                ((unsigned long *)(&cryptoInfo->header_creation_time))[1] = mgetLong (input);
        !           324:                ((unsigned long *)(&cryptoInfo->header_creation_time))[0] = mgetLong (input);
        !           325: 
        !           326:                // Password and cipher OK
        !           327: 
        !           328:                // Check the version required to handle this volume
        !           329:                if (requiredVersion > VERSION_NUM)
        !           330:                        return ERR_NEW_VERSION_REQUIRED;
        !           331: 
        !           332:                // Disk key
        !           333:                nKeyLen = DISKKEY_SIZE;
        !           334:                memcpy (keyInfo.key, header + HEADER_DISKKEY, nKeyLen);
        !           335: 
        !           336:                memcpy (cryptoInfo->master_decrypted_key, keyInfo.key, nKeyLen);
        !           337:                memcpy (cryptoInfo->key_salt, keyInfo.key_salt, USERKEY_SALT_SIZE);
        !           338:                cryptoInfo->pkcs5 = pkcs5;
        !           339:                cryptoInfo->noIterations = keyInfo.noIterations;
        !           340: 
        !           341:                // Init with decrypted master disk key for sector decryption
        !           342:                init_cipher (cryptoInfo->cipher, keyInfo.key + DISK_IV_SIZE, cryptoInfo->ks);
        !           343: 
        !           344:                // Disk IV
        !           345:                memcpy (cryptoInfo->iv, keyInfo.key, DISK_IV_SIZE);
        !           346: 
        !           347:                /* Clear out the temp. key buffer */
        !           348:                burn (dk, sizeof(dk));
        !           349: 
        !           350:                cryptoInfo->encrypt_sector = &EncryptSector8;
        !           351:                cryptoInfo->decrypt_sector = &DecryptSector8;
        !           352:        
        !           353:                return 0;
        !           354:        }
        !           355: 
        !           356:        crypto_close(cryptoInfo);
        !           357:        burn (&keyInfo, sizeof (keyInfo));
        !           358:        return ERR_PASSWORD_WRONG;
        !           359: }
        !           360: 
        !           361: #ifndef DEVICE_DRIVER
        !           362: 
        !           363: #ifdef VOLFORMAT
        !           364: extern HWND hDiskKey;
        !           365: extern HWND hKeySalt;
        !           366: #endif
        !           367: 
        !           368: // VolumeWriteHeader:
        !           369: // Creates volume header in memory
        !           370: int
        !           371: VolumeWriteHeader (char *header, int cipher, char *lpszPassword,
        !           372:                   int pkcs5, char *masterKey, unsigned __int64 volumeCreationTime, PCRYPTO_INFO * retInfo )
        !           373: {
        !           374:        unsigned char *p = (unsigned char *) header;
        !           375:        KEY_INFO keyInfo;
        !           376: 
        !           377:        int nUserKeyLen = strlen(lpszPassword);
        !           378:        PCRYPTO_INFO cryptoInfo = crypto_open ();
        !           379:        char dk[DISKKEY_SIZE];
        !           380:        int x;
        !           381: 
        !           382:        if (cryptoInfo == NULL)
        !           383:                return ERR_OUTOFMEMORY;
        !           384: 
        !           385:        memset (header, 0, SECTOR_SIZE);
        !           386: 
        !           387:        //// Encryption setup
        !           388: 
        !           389:        // User key
        !           390:        memcpy (keyInfo.userKey, lpszPassword, nUserKeyLen);
        !           391:        keyInfo.keyLength = nUserKeyLen;
        !           392:        keyInfo.noIterations = USERKEY_ITERATIONS;
        !           393: 
        !           394:        // User selected encryption algorithm
        !           395:        cryptoInfo->cipher = cipher;
        !           396: 
        !           397:        // Salt for header key derivation 
        !           398:        RandgetBytes (keyInfo.key_salt, USERKEY_SALT_SIZE);
        !           399: 
        !           400:        // PKCS5 is used to derive header key and IV from user password
        !           401:        if (pkcs5 == SHA1)
        !           402:        {
        !           403:                derive_sha_key (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
        !           404:                                USERKEY_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + MAX_CIPHER_KEY );
        !           405:        }
        !           406: 
        !           407:        // Generate disk key and IV
        !           408:        if(masterKey == 0)
        !           409:                RandgetBytes (keyInfo.key, DISKKEY_SIZE);
        !           410:        else
        !           411:                memcpy(keyInfo.key, masterKey, DISKKEY_SIZE);
        !           412: 
        !           413: 
        !           414:        //// Header setup
        !           415: 
        !           416:        // Salt
        !           417:        mputBytes (p, keyInfo.key_salt, USERKEY_SALT_SIZE);     
        !           418: 
        !           419:        // Magic
        !           420:        mputLong (p, 'TRUE');
        !           421: 
        !           422:        // Header version
        !           423:        mputWord (p, 0x0001);
        !           424: 
        !           425:        // Required program version to handle this volume
        !           426:        mputWord (p, VOLUME_VERSION_NUM);
        !           427: 
        !           428:        // CRC of disk key
        !           429:        x = crc32(keyInfo.key, DISKKEY_SIZE);
        !           430:        mputLong (p, x);
        !           431: 
        !           432:        // Time
        !           433:        {
        !           434:                SYSTEMTIME st;
        !           435:                FILETIME ft;
        !           436: 
        !           437:                // Volume creation time
        !           438:                if (volumeCreationTime == 0)
        !           439:                {
        !           440:                        GetLocalTime (&st);
        !           441:                        SystemTimeToFileTime (&st, &ft);
        !           442:                }
        !           443:                else
        !           444:                {
        !           445:                        ft.dwHighDateTime = (DWORD)(volumeCreationTime >> 32);
        !           446:                        ft.dwLowDateTime = (DWORD)volumeCreationTime;
        !           447:                }
        !           448:                mputLong (p, ft.dwHighDateTime);
        !           449:                mputLong (p, ft.dwLowDateTime);
        !           450: 
        !           451:                // Password change time
        !           452:                GetLocalTime (&st);
        !           453:                SystemTimeToFileTime (&st, &ft);
        !           454:                mputLong (p, ft.dwHighDateTime);
        !           455:                mputLong (p, ft.dwLowDateTime);
        !           456:        }
        !           457: 
        !           458:        // Disk key and IV
        !           459:        memcpy (header + HEADER_DISKKEY, keyInfo.key, DISKKEY_SIZE);
        !           460: 
        !           461: 
        !           462:        //// Header encryption
        !           463: 
        !           464:        memcpy (cryptoInfo->iv, dk, DISK_IV_SIZE);
        !           465:        init_cipher (cryptoInfo->cipher, dk + DISK_IV_SIZE, cryptoInfo->ks);
        !           466: 
        !           467:        EncryptBuffer (header + HEADER_ENCRYPTEDDATA, HEADER_ENCRYPTEDDATASIZE, 
        !           468:                        cryptoInfo->ks, cryptoInfo->iv, cryptoInfo->cipher);
        !           469: 
        !           470: 
        !           471:        //// cryptoInfo setup for further use (disk format)
        !           472: 
        !           473:        // Init with master disk key for sector decryption
        !           474:        init_cipher (cryptoInfo->cipher, keyInfo.key + DISK_IV_SIZE, cryptoInfo->ks);
        !           475: 
        !           476:        // Disk IV
        !           477:        memcpy (cryptoInfo->iv, keyInfo.key, DISK_IV_SIZE);
        !           478: 
        !           479:        // Clear out the temp. key buffer
        !           480:        burn (dk, sizeof(dk));
        !           481: 
        !           482:        if (get_block_size(cipher) == 8)
        !           483:        {
        !           484:                cryptoInfo->encrypt_sector = &EncryptSector8;
        !           485:                cryptoInfo->decrypt_sector = &DecryptSector8;
        !           486:        }
        !           487: 
        !           488: #ifdef VOLFORMAT
        !           489:        {
        !           490:                char tmp[64];
        !           491:                BOOL dots3 = FALSE;
        !           492:                int i, j;
        !           493: 
        !           494:                j = get_key_size (cipher);
        !           495: 
        !           496:                if (j > 21)
        !           497:                {
        !           498:                        dots3 = TRUE;
        !           499:                        j = 21;
        !           500:                }
        !           501: 
        !           502:                tmp[0] = 0;
        !           503:                for (i = 0; i < j; i++)
        !           504:                {
        !           505:                        char tmp2[8] =
        !           506:                        {0};
        !           507:                        sprintf (tmp2, "%02X", (int) (unsigned char) keyInfo.key[i + DISK_IV_SIZE]);
        !           508:                        strcat (tmp, tmp2);
        !           509:                }
        !           510: 
        !           511:                if (dots3 == TRUE)
        !           512:                {
        !           513:                        strcat (tmp, "...");
        !           514:                }
        !           515: 
        !           516: 
        !           517:                SetWindowText (hDiskKey, tmp);
        !           518: 
        !           519:                tmp[0] = 0;
        !           520:                for (i = 0; i < 20; i++)
        !           521:                {
        !           522:                        char tmp2[8];
        !           523:                        sprintf (tmp2, "%02X", (int) (unsigned char) keyInfo.key_salt[i]);
        !           524:                        strcat (tmp, tmp2);
        !           525:                }
        !           526: 
        !           527:                SetWindowText (hKeySalt, tmp);
        !           528:        }
        !           529: #endif
        !           530: 
        !           531:        burn (&keyInfo, sizeof (keyInfo));
        !           532: 
        !           533:        *retInfo = cryptoInfo;
        !           534:        return 0;
        !           535: }
        !           536: 
        !           537: 
        !           538: #endif                         /* !NT4_DRIVER */

unix.superglobalmegacorp.com

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