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

1.1.1.3   root        1: /* The source code contained in this file has been derived from the source code
                      2:    of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and
1.1.1.5 ! root        3:    additions to that source code contained in this file are Copyright (c) 2004-2005
1.1.1.4   root        4:    TrueCrypt Foundation and Copyright (c) 2004 TrueCrypt Team. Unmodified
1.1.1.3   root        5:    parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation
                      6:    release. Please see the file license.txt for full license details. */
1.1       root        7: 
                      8: #include "TCdefs.h"
                      9: 
                     10: #include <fcntl.h>
                     11: #include <sys/types.h>
                     12: #include <sys/stat.h>
                     13: #include <io.h>
                     14: #include <time.h>
                     15: 
                     16: #include "crypto.h"
                     17: #include "random.h"
                     18: #include "endian.h"
                     19: #include "fat.h"
                     20: #include "volumes.h"
                     21: 
1.1.1.4   root       22: #include "Aes.h"
1.1       root       23: #include "pkcs5.h"
                     24: #include "crc.h"
                     25: 
                     26: 
1.1.1.4   root       27: /* When FALSE, hidden volumes will not be attempted to mount. This variable could be used in future.
                     28: Should a large number of new ciphers be implemented, setting this to FALSE (via program prefs) might
                     29: speed mounting up. */
                     30: BOOL mountingHiddenVolumesAllowed = TRUE;      
1.1       root       31: 
                     32: 
                     33: // Volume header structure:
                     34: //
                     35: // Offset      Length  Description
                     36: // ------------------------------------------
                     37: // Unencrypted:
                     38: // 0           64              Key salt
                     39: // Encrypted:
1.1.1.4   root       40: // 64          4               ASCII string 'TRUE'
1.1       root       41: // 68          2               Header version
                     42: // 70          2               Required program version
                     43: // 72          4               CRC32 of disk IV and key
                     44: // 76          8               Volume creation time
                     45: // 84          8               Header creation time
1.1.1.4   root       46: // 92          8               Size of hidden volume in bytes (0 = normal volume)
                     47: // 100         156             Unused
1.1       root       48: // 256         32              Disk IV
                     49: // 288         224             Disk key
                     50: 
                     51: int
1.1.1.4   root       52: VolumeReadHeader (char *encryptedHeader, char *encryptedHeaderHiddenVol, char *lpszPassword, PCRYPTO_INFO *retInfo)
1.1       root       53: {
                     54:        char header[SECTOR_SIZE];
                     55:        unsigned char *input = (unsigned char *) header;
                     56:        KEY_INFO keyInfo;
1.1.1.4   root       57:        KEY_INFO keyInfoHiddenVol;
1.1       root       58:        PCRYPTO_INFO cryptoInfo;
                     59:        int nStatus = 0, nKeyLen;
                     60:        char dk[DISKKEY_SIZE];
1.1.1.4   root       61:        char dkHiddenVol[DISKKEY_SIZE];
1.1       root       62:        int pkcs5;
                     63:        int headerVersion, requiredVersion;
1.1.1.4   root       64:        int volType, lastVolType = NORMAL_VOLUME;
1.1       root       65:        
                     66:        cryptoInfo = *retInfo = crypto_open ();
                     67:        if (cryptoInfo == NULL)
                     68:                return ERR_OUTOFMEMORY;
                     69: 
                     70:        crypto_loadkey (&keyInfo, lpszPassword, strlen (lpszPassword));
                     71: 
                     72:        // PKCS5 is used to derive header key and IV from user password
                     73:        memcpy (keyInfo.key_salt, encryptedHeader + HEADER_USERKEY_SALT, USERKEY_SALT_SIZE);
1.1.1.4   root       74: 
                     75:        if (mountingHiddenVolumesAllowed && encryptedHeaderHiddenVol != 0)
                     76:        {
                     77:                // Salt for a possible hidden volume
                     78:                memcpy (keyInfoHiddenVol.key_salt, encryptedHeaderHiddenVol + HEADER_USERKEY_SALT, USERKEY_SALT_SIZE);
                     79:                lastVolType = HIDDEN_VOLUME;
                     80:        }
                     81: 
1.1       root       82:        keyInfo.noIterations = USERKEY_ITERATIONS;              
                     83: 
1.1.1.3   root       84:        // Test all available PKCS5 PRFs
                     85:        for (pkcs5 = 1; pkcs5 <= LAST_PRF_ID; pkcs5++)
1.1       root       86:        {
1.1.1.3   root       87:                if (pkcs5 == SHA1)
                     88:                {
                     89:                        derive_sha_key (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
1.1.1.4   root       90:                                USERKEY_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                     91:                        if (mountingHiddenVolumesAllowed)
                     92:                        {
                     93:                                // Derive header for a possible hidden volume (HMAC-SHA-1)
                     94:                                derive_sha_key (keyInfo.userKey, keyInfo.keyLength, keyInfoHiddenVol.key_salt,
                     95:                                        USERKEY_SALT_SIZE, keyInfo.noIterations, dkHiddenVol, DISK_IV_SIZE + EAGetLargestKey());
                     96:                        }
                     97:                } 
                     98:                else if (pkcs5 == RIPEMD160)
1.1.1.3   root       99:                {
                    100:                        derive_rmd160_key (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
1.1.1.4   root      101:                                USERKEY_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                    102:                        if (mountingHiddenVolumesAllowed)
                    103:                        {
                    104:                                // Derive header for a possible hidden volume (HMAC-RIPEMD-160)
                    105:                                derive_rmd160_key (keyInfo.userKey, keyInfo.keyLength, keyInfoHiddenVol.key_salt,
                    106:                                        USERKEY_SALT_SIZE, keyInfo.noIterations, dkHiddenVol, DISK_IV_SIZE + EAGetLargestKey());
                    107:                        }
1.1.1.3   root      108:                }
1.1       root      109: 
1.1.1.4   root      110:                // Test all available encryption algorithms
                    111:                for (cryptoInfo->ea = EAGetFirst (); cryptoInfo->ea != 0; cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
1.1.1.3   root      112:                {
1.1.1.4   root      113:                        // Test all volume types
                    114:                        for (volType = NORMAL_VOLUME; volType <= lastVolType; volType++)
1.1.1.3   root      115:                        {
1.1.1.4   root      116:                                // Copy header for decryption and init an encryption algorithm
                    117:                                if (volType == NORMAL_VOLUME)
                    118:                                {
                    119:                                        memcpy (header, encryptedHeader, SECTOR_SIZE);  
                    120:                                        memcpy (cryptoInfo->iv, dk, DISK_IV_SIZE);
                    121:                                        EAInit (cryptoInfo->ea, dk + DISK_IV_SIZE, cryptoInfo->ks);
                    122:                                }
                    123:                                else if (volType == HIDDEN_VOLUME)
                    124:                                {                                       
                    125:                                        memcpy (header, encryptedHeaderHiddenVol, SECTOR_SIZE);  
                    126:                                        memcpy (cryptoInfo->iv, dkHiddenVol, DISK_IV_SIZE);
                    127:                                        EAInit (cryptoInfo->ea, dkHiddenVol + DISK_IV_SIZE, cryptoInfo->ks);
                    128:                                }
                    129: 
                    130:                                input = header;
                    131: 
                    132:                                // Try to decrypt header 
                    133: 
                    134:                                DecryptBuffer ((unsigned long *) (header + HEADER_ENCRYPTEDDATA), HEADER_ENCRYPTEDDATASIZE,
                    135:                                        cryptoInfo->ks, cryptoInfo->iv, &cryptoInfo->iv[8], cryptoInfo->ea);
                    136: 
                    137:                                input += HEADER_ENCRYPTEDDATA;
                    138: 
                    139:                                // Magic
                    140:                                if (mgetLong (input) != 'TRUE')
                    141:                                        continue;
                    142: 
                    143:                                // Header version
                    144:                                headerVersion = mgetWord (input);
                    145: 
                    146:                                // Required program version
                    147:                                requiredVersion = mgetWord (input);
                    148: 
                    149:                                // Check CRC of disk IV and key
                    150:                                if (mgetLong (input) != crc32 (header + HEADER_DISKKEY, DISKKEY_SIZE))
                    151:                                        continue;
                    152: 
                    153:                                // Now we have the correct password, cipher, hash algorithm, and volume type
                    154: 
                    155:                                // Check the version required to handle this volume
                    156:                                if (requiredVersion > VERSION_NUM)
                    157:                                        return ERR_NEW_VERSION_REQUIRED;
                    158: 
                    159:                                // Volume creation time
                    160:                                cryptoInfo->volume_creation_time = mgetInt64 (input);
                    161: 
                    162:                                // Header creation time
                    163:                                cryptoInfo->header_creation_time = mgetInt64 (input);
                    164: 
                    165:                                // Hidden volume
                    166:                                cryptoInfo->hiddenVolumeSize = mgetInt64 (input);
                    167: 
                    168:                                if (volType == HIDDEN_VOLUME)   // If mounted as a hidden volume
                    169:                                {
                    170:                                        cryptoInfo->hiddenVolume = TRUE;
                    171:                                }
                    172:                                else
                    173:                                {
                    174:                                        cryptoInfo->hiddenVolume = FALSE;
                    175:                                        cryptoInfo->hiddenVolumeSize = 0;
                    176:                                }
                    177: 
                    178:                                // Disk key
                    179:                                nKeyLen = DISKKEY_SIZE;
                    180:                                memcpy (keyInfo.key, header + HEADER_DISKKEY, nKeyLen);
                    181: 
                    182:                                memcpy (cryptoInfo->master_decrypted_key, keyInfo.key, nKeyLen);
                    183:                                memcpy (cryptoInfo->key_salt, keyInfo.key_salt, USERKEY_SALT_SIZE);
                    184:                                cryptoInfo->pkcs5 = pkcs5;
                    185:                                cryptoInfo->noIterations = keyInfo.noIterations;
                    186: 
                    187:                                // Init the encryption algorithm with the decrypted master key
                    188:                                EAInit (cryptoInfo->ea, keyInfo.key + DISK_IV_SIZE, cryptoInfo->ks);
                    189: 
                    190:                                // Disk IV
                    191:                                memcpy (cryptoInfo->iv, keyInfo.key, DISK_IV_SIZE);
                    192: 
                    193:                                // Clear out the temp. key buffers
                    194:                                burn (dk, sizeof(dk));
                    195:                                burn (dkHiddenVol, sizeof(dkHiddenVol));
1.1.1.3   root      196: 
1.1.1.4   root      197:                                return 0;
                    198:                        }
1.1.1.2   root      199:                }
1.1       root      200:        }
                    201: 
                    202:        crypto_close(cryptoInfo);
                    203:        burn (&keyInfo, sizeof (keyInfo));
1.1.1.4   root      204:        burn (&keyInfoHiddenVol, sizeof (keyInfoHiddenVol));
1.1       root      205:        return ERR_PASSWORD_WRONG;
                    206: }
                    207: 
                    208: #ifndef DEVICE_DRIVER
                    209: 
                    210: #ifdef VOLFORMAT
1.1.1.3   root      211: extern BOOL showKeys;
1.1       root      212: extern HWND hDiskKey;
1.1.1.3   root      213: extern HWND hHeaderKey;
1.1       root      214: #endif
                    215: 
                    216: // VolumeWriteHeader:
                    217: // Creates volume header in memory
                    218: int
1.1.1.4   root      219: VolumeWriteHeader (char *header, int ea, char *lpszPassword,
                    220:                   int pkcs5, char *masterKey, unsigned __int64 volumeCreationTime, PCRYPTO_INFO * retInfo,
                    221:                   unsigned __int64 hiddenVolumeSize)
1.1       root      222: {
                    223:        unsigned char *p = (unsigned char *) header;
                    224:        KEY_INFO keyInfo;
                    225: 
                    226:        int nUserKeyLen = strlen(lpszPassword);
                    227:        PCRYPTO_INFO cryptoInfo = crypto_open ();
                    228:        char dk[DISKKEY_SIZE];
                    229:        int x;
                    230: 
                    231:        if (cryptoInfo == NULL)
                    232:                return ERR_OUTOFMEMORY;
                    233: 
                    234:        memset (header, 0, SECTOR_SIZE);
1.1.1.2   root      235:        VirtualLock (&keyInfo, sizeof (keyInfo));
1.1       root      236: 
                    237:        //// Encryption setup
                    238: 
1.1.1.2   root      239:        // Generate disk key and IV
                    240:        if(masterKey == 0)
                    241:                RandgetBytes (keyInfo.key, DISKKEY_SIZE, TRUE);
                    242:        else
                    243:                memcpy (keyInfo.key, masterKey, DISKKEY_SIZE);
                    244: 
1.1       root      245:        // User key
                    246:        memcpy (keyInfo.userKey, lpszPassword, nUserKeyLen);
                    247:        keyInfo.keyLength = nUserKeyLen;
                    248:        keyInfo.noIterations = USERKEY_ITERATIONS;
                    249: 
                    250:        // User selected encryption algorithm
1.1.1.4   root      251:        cryptoInfo->ea = ea;
1.1       root      252: 
                    253:        // Salt for header key derivation 
1.1.1.2   root      254:        RandgetBytes (keyInfo.key_salt, USERKEY_SALT_SIZE, TRUE);
1.1       root      255: 
1.1.1.4   root      256:        // PKCS5 is used to derive the header key and IV from the password
1.1       root      257:        if (pkcs5 == SHA1)
                    258:        {
                    259:                derive_sha_key (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
1.1.1.4   root      260:                                USERKEY_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey() );
1.1       root      261:        }
1.1.1.3   root      262:        else if (pkcs5 == RIPEMD160)
                    263:        {
                    264:                derive_rmd160_key (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
1.1.1.4   root      265:                                USERKEY_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey() );
1.1.1.3   root      266:        }
1.1       root      267: 
                    268: 
                    269:        //// Header setup
                    270: 
                    271:        // Salt
                    272:        mputBytes (p, keyInfo.key_salt, USERKEY_SALT_SIZE);     
                    273: 
                    274:        // Magic
                    275:        mputLong (p, 'TRUE');
                    276: 
                    277:        // Header version
1.1.1.4   root      278:        mputWord (p, VOLUME_HEADER_VERSION);
1.1       root      279: 
                    280:        // Required program version to handle this volume
1.1.1.4   root      281:        mputWord (p, VOL_REQ_PROG_VERSION);
1.1       root      282: 
                    283:        // CRC of disk key
                    284:        x = crc32(keyInfo.key, DISKKEY_SIZE);
                    285:        mputLong (p, x);
                    286: 
                    287:        // Time
                    288:        {
                    289:                SYSTEMTIME st;
                    290:                FILETIME ft;
                    291: 
                    292:                // Volume creation time
                    293:                if (volumeCreationTime == 0)
                    294:                {
                    295:                        GetLocalTime (&st);
                    296:                        SystemTimeToFileTime (&st, &ft);
                    297:                }
                    298:                else
                    299:                {
                    300:                        ft.dwHighDateTime = (DWORD)(volumeCreationTime >> 32);
                    301:                        ft.dwLowDateTime = (DWORD)volumeCreationTime;
                    302:                }
                    303:                mputLong (p, ft.dwHighDateTime);
                    304:                mputLong (p, ft.dwLowDateTime);
                    305: 
                    306:                // Password change time
                    307:                GetLocalTime (&st);
                    308:                SystemTimeToFileTime (&st, &ft);
                    309:                mputLong (p, ft.dwHighDateTime);
                    310:                mputLong (p, ft.dwLowDateTime);
                    311:        }
                    312: 
1.1.1.4   root      313:        // Hidden volume size
                    314:        cryptoInfo->hiddenVolumeSize = hiddenVolumeSize;
                    315:        mputInt64 (p, cryptoInfo->hiddenVolumeSize);
                    316: 
1.1       root      317:        // Disk key and IV
                    318:        memcpy (header + HEADER_DISKKEY, keyInfo.key, DISKKEY_SIZE);
                    319: 
                    320: 
                    321:        //// Header encryption
                    322: 
                    323:        memcpy (cryptoInfo->iv, dk, DISK_IV_SIZE);
1.1.1.4   root      324:        EAInit (cryptoInfo->ea, dk + DISK_IV_SIZE, cryptoInfo->ks);
1.1       root      325: 
1.1.1.4   root      326:        EncryptBuffer ((unsigned long *) (header + HEADER_ENCRYPTEDDATA), HEADER_ENCRYPTEDDATASIZE,
                    327:                        cryptoInfo->ks, cryptoInfo->iv, &cryptoInfo->iv[8], cryptoInfo->ea);
1.1       root      328: 
                    329: 
                    330:        //// cryptoInfo setup for further use (disk format)
                    331: 
                    332:        // Init with master disk key for sector decryption
1.1.1.4   root      333:        EAInit (cryptoInfo->ea, keyInfo.key + DISK_IV_SIZE, cryptoInfo->ks);
1.1       root      334: 
                    335:        // Disk IV
                    336:        memcpy (cryptoInfo->iv, keyInfo.key, DISK_IV_SIZE);
                    337: 
1.1.1.2   root      338: 
1.1       root      339: #ifdef VOLFORMAT
1.1.1.3   root      340:        if (showKeys)
1.1       root      341:        {
                    342:                char tmp[64];
                    343:                BOOL dots3 = FALSE;
                    344:                int i, j;
                    345: 
1.1.1.4   root      346:                j = EAGetKeySize (ea);
1.1       root      347: 
1.1.1.3   root      348:                if (j > 14)
1.1       root      349:                {
                    350:                        dots3 = TRUE;
1.1.1.3   root      351:                        j = 14;
1.1       root      352:                }
                    353: 
                    354:                tmp[0] = 0;
                    355:                for (i = 0; i < j; i++)
                    356:                {
                    357:                        char tmp2[8] =
                    358:                        {0};
                    359:                        sprintf (tmp2, "%02X", (int) (unsigned char) keyInfo.key[i + DISK_IV_SIZE]);
                    360:                        strcat (tmp, tmp2);
                    361:                }
                    362: 
                    363:                if (dots3 == TRUE)
                    364:                {
                    365:                        strcat (tmp, "...");
                    366:                }
                    367: 
                    368: 
                    369:                SetWindowText (hDiskKey, tmp);
                    370: 
                    371:                tmp[0] = 0;
1.1.1.3   root      372:                for (i = 0; i < 14; i++)
1.1       root      373:                {
                    374:                        char tmp2[8];
1.1.1.3   root      375:                        sprintf (tmp2, "%02X", (int) (unsigned char) dk[DISK_IV_SIZE + i]);
1.1       root      376:                        strcat (tmp, tmp2);
                    377:                }
                    378: 
1.1.1.3   root      379:                if (dots3 == TRUE)
                    380:                {
                    381:                        strcat (tmp, "...");
                    382:                }
                    383: 
                    384:                SetWindowText (hHeaderKey, tmp);
1.1       root      385:        }
                    386: #endif
                    387: 
1.1.1.3   root      388:        burn (dk, sizeof(dk));
1.1       root      389:        burn (&keyInfo, sizeof (keyInfo));
1.1.1.2   root      390:        VirtualUnlock (&keyInfo, sizeof (keyInfo));
1.1       root      391: 
                    392:        *retInfo = cryptoInfo;
                    393:        return 0;
                    394: }
                    395: 
                    396: #endif                         /* !NT4_DRIVER */
1.1.1.4   root      397: 

unix.superglobalmegacorp.com

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