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

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.9 ! root        6:    Copyright (c) 2004 TrueCrypt Team, and are covered by TrueCrypt License 2.1
1.1.1.6   root        7:    the full text of which is contained in the file License.txt included in
                      8:    TrueCrypt binary and source code distribution archives.  */
1.1       root        9: 
1.1.1.6   root       10: #include "Tcdefs.h"
1.1       root       11: 
                     12: #include <fcntl.h>
                     13: #include <sys/types.h>
                     14: #include <sys/stat.h>
                     15: #include <time.h>
                     16: 
1.1.1.6   root       17: #ifdef _WIN32
                     18: #include <io.h>
                     19: #include "Random.h"
                     20: #endif
                     21: 
                     22: #include "Crypto.h"
                     23: #include "Endian.h"
                     24: #include "Volumes.h"
                     25: 
                     26: #include "Pkcs5.h"
                     27: #include "Crc.h"
1.1       root       28: 
                     29: 
1.1.1.6   root       30: #define NBR_KEY_BYTES_TO_DISPLAY       16
1.1       root       31: 
                     32: 
                     33: // Volume header structure:
                     34: //
                     35: // Offset      Length  Description
                     36: // ------------------------------------------
                     37: // Unencrypted:
1.1.1.6   root       38: // 0           64              Salt
1.1       root       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
1.1.1.7   root       43: // 72          4               CRC-32 checksum of the (decrypted) bytes 256-511
1.1       root       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)
1.1.1.7   root       47: // 100         156             Reserved (set to zero)
                     48: // 256         32              Secondary key (LRW mode)
                     49: // 288         224             Master key(s)
1.1       root       50: 
                     51: int
1.1.1.6   root       52: VolumeReadHeader (char *encryptedHeader, Password *password, PCRYPTO_INFO *retInfo)
1.1       root       53: {
1.1.1.6   root       54:        char header[HEADER_SIZE];
1.1       root       55:        unsigned char *input = (unsigned char *) header;
                     56:        KEY_INFO keyInfo;
                     57:        PCRYPTO_INFO cryptoInfo;
1.1.1.6   root       58:        int nKeyLen;
1.1       root       59:        char dk[DISKKEY_SIZE];
                     60:        int pkcs5;
                     61:        int headerVersion, requiredVersion;
1.1.1.6   root       62:        int status;
                     63: 
1.1.1.7   root       64: 
1.1       root       65:        cryptoInfo = *retInfo = crypto_open ();
                     66:        if (cryptoInfo == NULL)
                     67:                return ERR_OUTOFMEMORY;
                     68: 
1.1.1.6   root       69:        crypto_loadkey (&keyInfo, password->Text, password->Length);
1.1       root       70: 
1.1.1.7   root       71:        // PKCS5 is used to derive the header key and the secondary header key (LRW mode) from the user password
1.1.1.6   root       72:        memcpy (keyInfo.key_salt, encryptedHeader + HEADER_USERKEY_SALT, PKCS5_SALT_SIZE);
1.1       root       73: 
1.1.1.3   root       74:        // Test all available PKCS5 PRFs
                     75:        for (pkcs5 = 1; pkcs5 <= LAST_PRF_ID; pkcs5++)
1.1       root       76:        {
1.1.1.7   root       77:                BOOL lrw64InitDone = FALSE;
                     78:                BOOL lrw128InitDone = FALSE;
                     79: 
1.1.1.6   root       80:                keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5);
                     81: 
                     82:                switch (pkcs5)
1.1.1.3   root       83:                {
1.1.1.6   root       84:                case SHA1:
                     85:                        derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
                     86:                                PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                     87:                        break;
                     88: 
                     89:                case RIPEMD160:
                     90:                        derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
                     91:                                PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                     92:                        break;
                     93: 
                     94:                case WHIRLPOOL:
                     95:                        derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
                     96:                                PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                     97:                        break;
1.1.1.4   root       98:                } 
1.1       root       99: 
1.1.1.4   root      100:                // Test all available encryption algorithms
1.1.1.7   root      101:                for (cryptoInfo->ea = EAGetFirst ();
                    102:                        cryptoInfo->ea != 0;
                    103:                        cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
1.1.1.3   root      104:                {
1.1.1.7   root      105:                        int blockSize = CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea));
1.1.1.6   root      106: 
                    107:                        status = EAInit (cryptoInfo->ea, dk + DISK_IV_SIZE, cryptoInfo->ks);
                    108:                        if (status == ERR_CIPHER_INIT_FAILURE)
                    109:                                goto err;
                    110: 
1.1.1.7   root      111:                        // Test all available modes of operation
                    112:                        for (cryptoInfo->mode = EAGetFirstMode (cryptoInfo->ea);
                    113:                                cryptoInfo->mode != 0;
                    114:                                cryptoInfo->mode = EAGetNextMode (cryptoInfo->ea, cryptoInfo->mode))
1.1.1.6   root      115:                        {
1.1.1.7   root      116:                                // Copy header for decryption and init an encryption algorithm
                    117:                                memcpy (header, encryptedHeader, SECTOR_SIZE);  
                    118:                                memcpy (cryptoInfo->iv, dk, DISK_IV_SIZE);
                    119: 
                    120:                                if (cryptoInfo->mode == LRW
                    121:                                        && (blockSize == 8 && !lrw64InitDone || blockSize == 16 && !lrw128InitDone))
                    122:                                {
                    123:                                        if (!EAInitMode (cryptoInfo))
                    124:                                        {
                    125:                                                status = ERR_MODE_INIT_FAILED;
                    126:                                                goto err;
                    127:                                        }
                    128: 
                    129:                                        if (blockSize == 8)
                    130:                                                lrw64InitDone = TRUE;
                    131:                                        else if (blockSize == 16)
                    132:                                                lrw128InitDone = TRUE;
                    133:                                }
                    134: 
                    135:                                input = header;
                    136: 
                    137:                                // Try to decrypt header 
                    138: 
                    139:                                DecryptBuffer ((unsigned __int32 *) (header + HEADER_ENCRYPTEDDATA), HEADER_ENCRYPTEDDATASIZE,
                    140:                                        cryptoInfo);
                    141: 
                    142:                                input += HEADER_ENCRYPTEDDATA;
                    143: 
                    144:                                // Magic 'TRUE'
                    145:                                if (mgetLong (input) != 0x54525545)
                    146:                                        continue;
                    147: 
                    148:                                // Header version
                    149:                                headerVersion = mgetWord (input);
                    150: 
                    151:                                // Required program version
                    152:                                requiredVersion = mgetWord (input);
                    153: 
                    154:                                // Check CRC of the key set
                    155:                                if (mgetLong (input) != crc32 (header + HEADER_DISKKEY, DISKKEY_SIZE))
                    156:                                        continue;
                    157: 
                    158:                                // Now we have the correct password, cipher, hash algorithm, and volume type
                    159: 
                    160:                                // Check the version required to handle this volume
                    161:                                if (requiredVersion > VERSION_NUM)
                    162:                                {
                    163:                                        status = ERR_NEW_VERSION_REQUIRED;
                    164:                                        goto err;
                    165:                                }
                    166: 
                    167:                                // Volume creation time
                    168:                                cryptoInfo->volume_creation_time = mgetInt64 (input);
                    169: 
                    170:                                // Header creation time
                    171:                                cryptoInfo->header_creation_time = mgetInt64 (input);
                    172: 
                    173:                                // Hidden volume size (if any)
                    174:                                cryptoInfo->hiddenVolumeSize = mgetInt64 (input);
                    175: 
                    176:                                // Disk key
                    177:                                nKeyLen = DISKKEY_SIZE;
                    178:                                memcpy (keyInfo.key, header + HEADER_DISKKEY, nKeyLen);
                    179: 
                    180:                                memcpy (cryptoInfo->master_key, keyInfo.key, nKeyLen);
                    181:                                memcpy (cryptoInfo->key_salt, keyInfo.key_salt, PKCS5_SALT_SIZE);
                    182:                                cryptoInfo->pkcs5 = pkcs5;
                    183:                                cryptoInfo->noIterations = keyInfo.noIterations;
                    184: 
                    185:                                // Init the encryption algorithm with the decrypted master key
                    186:                                status = EAInit (cryptoInfo->ea, keyInfo.key + DISK_IV_SIZE, cryptoInfo->ks);
                    187:                                if (status == ERR_CIPHER_INIT_FAILURE)
                    188:                                        goto err;
                    189: 
                    190:                                // The secondary key (LRW mode) for the data area
                    191:                                memcpy (cryptoInfo->iv, keyInfo.key, DISK_IV_SIZE);
                    192: 
                    193:                                // Mode of operation
                    194:                                if (!EAInitMode (cryptoInfo))
                    195:                                {
                    196:                                        status = ERR_MODE_INIT_FAILED;
                    197:                                        goto err;
                    198:                                }
1.1.1.6   root      199: 
1.1.1.7   root      200:                                // Clear out the temp. key buffers
                    201:                                burn (dk, sizeof(dk));
1.1.1.6   root      202: 
1.1.1.7   root      203:                                return 0;
1.1.1.6   root      204: 
1.1.1.7   root      205:                        }
1.1.1.2   root      206:                }
1.1       root      207:        }
1.1.1.6   root      208:        status = ERR_PASSWORD_WRONG;
1.1       root      209: 
1.1.1.6   root      210: err:
1.1       root      211:        crypto_close(cryptoInfo);
1.1.1.7   root      212:        *retInfo = NULL; 
1.1       root      213:        burn (&keyInfo, sizeof (keyInfo));
1.1.1.6   root      214:        return status;
1.1       root      215: }
                    216: 
                    217: #ifndef DEVICE_DRIVER
                    218: 
                    219: #ifdef VOLFORMAT
1.1.1.3   root      220: extern BOOL showKeys;
1.1       root      221: extern HWND hDiskKey;
1.1.1.3   root      222: extern HWND hHeaderKey;
1.1       root      223: #endif
                    224: 
1.1.1.6   root      225: 
1.1       root      226: // VolumeWriteHeader:
                    227: // Creates volume header in memory
                    228: int
1.1.1.7   root      229: VolumeWriteHeader (char *header, int ea, int mode, Password *password,
1.1.1.4   root      230:                   int pkcs5, char *masterKey, unsigned __int64 volumeCreationTime, PCRYPTO_INFO * retInfo,
1.1.1.6   root      231:                   unsigned __int64 hiddenVolumeSize, BOOL bWipeMode)
1.1       root      232: {
                    233:        unsigned char *p = (unsigned char *) header;
1.1.1.6   root      234:        static KEY_INFO keyInfo;
1.1       root      235: 
1.1.1.6   root      236:        int nUserKeyLen = password->Length;
1.1       root      237:        PCRYPTO_INFO cryptoInfo = crypto_open ();
1.1.1.6   root      238:        static char dk[DISKKEY_SIZE];
1.1       root      239:        int x;
1.1.1.6   root      240:        int retVal = 0;
1.1       root      241: 
                    242:        if (cryptoInfo == NULL)
                    243:                return ERR_OUTOFMEMORY;
                    244: 
                    245:        memset (header, 0, SECTOR_SIZE);
1.1.1.8   root      246: 
                    247: #ifdef _WIN32
1.1.1.2   root      248:        VirtualLock (&keyInfo, sizeof (keyInfo));
1.1.1.6   root      249:        VirtualLock (&dk, sizeof (dk));
1.1.1.8   root      250: #endif
1.1       root      251: 
1.1.1.6   root      252:        /* Encryption setup */
1.1       root      253: 
1.1.1.7   root      254:        // If necessary, generate the master key and the secondary key (LRW mode)
1.1.1.2   root      255:        if(masterKey == 0)
1.1.1.7   root      256:        {
1.1.1.8   root      257:                if (!RandgetBytes (keyInfo.key, DISK_IV_SIZE + EAGetKeySize (ea), TRUE))
                    258:                        return ERR_CIPHER_INIT_WEAK_KEY;
1.1.1.7   root      259: 
                    260:                // Verify that the secondary key is not weak
                    261:                if (DetectWeakSecondaryKey (keyInfo.key, CipherGetBlockSize (EAGetFirstCipher (ea))))
1.1.1.8   root      262:                        return ERR_CIPHER_INIT_WEAK_KEY;
1.1.1.7   root      263:        }
1.1.1.2   root      264:        else
                    265:                memcpy (keyInfo.key, masterKey, DISKKEY_SIZE);
                    266: 
1.1.1.6   root      267:        // User key 
                    268:        memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
1.1       root      269:        keyInfo.keyLength = nUserKeyLen;
1.1.1.6   root      270:        keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5);
1.1       root      271: 
                    272:        // User selected encryption algorithm
1.1.1.4   root      273:        cryptoInfo->ea = ea;
1.1       root      274: 
1.1.1.7   root      275:        // Mode of operation
                    276:        cryptoInfo->mode = mode;
                    277: 
1.1.1.8   root      278:        // Salt for header key derivation
                    279:        if (!RandgetBytes (keyInfo.key_salt, PKCS5_SALT_SIZE, !bWipeMode))
                    280:                return ERR_CIPHER_INIT_WEAK_KEY; 
1.1       root      281: 
1.1.1.7   root      282:        // PKCS5 is used to derive the header key and the secondary header key (LRW mode) from the password
1.1.1.6   root      283:        switch (pkcs5)
1.1       root      284:        {
1.1.1.6   root      285:        case SHA1:
                    286:                derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
                    287:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                    288:                break;
                    289: 
                    290:        case RIPEMD160:
                    291:                derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
                    292:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                    293:                break;
                    294: 
                    295:        case WHIRLPOOL:
                    296:                derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
                    297:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                    298:                break;
                    299:        } 
1.1.1.7   root      300:        // Verify that the secondary key is not weak
                    301:        if (DetectWeakSecondaryKey (dk, CipherGetBlockSize (EAGetFirstCipher (ea))))
                    302:                return ERR_CIPHER_INIT_WEAK_KEY; 
                    303: 
1.1       root      304: 
1.1.1.6   root      305:        /* Header setup */
1.1       root      306: 
                    307:        // Salt
1.1.1.6   root      308:        mputBytes (p, keyInfo.key_salt, PKCS5_SALT_SIZE);       
1.1       root      309: 
                    310:        // Magic
1.1.1.8   root      311:        mputLong (p, 0x54525545);
1.1       root      312: 
                    313:        // Header version
1.1.1.4   root      314:        mputWord (p, VOLUME_HEADER_VERSION);
1.1       root      315: 
                    316:        // Required program version to handle this volume
1.1.1.4   root      317:        mputWord (p, VOL_REQ_PROG_VERSION);
1.1       root      318: 
1.1.1.7   root      319:        // CRC of the key set
1.1       root      320:        x = crc32(keyInfo.key, DISKKEY_SIZE);
                    321:        mputLong (p, x);
                    322: 
                    323:        // Time
                    324:        {
1.1.1.8   root      325: #ifdef _WIN32
1.1       root      326:                SYSTEMTIME st;
                    327:                FILETIME ft;
                    328: 
                    329:                // Volume creation time
                    330:                if (volumeCreationTime == 0)
                    331:                {
                    332:                        GetLocalTime (&st);
                    333:                        SystemTimeToFileTime (&st, &ft);
                    334:                }
                    335:                else
                    336:                {
                    337:                        ft.dwHighDateTime = (DWORD)(volumeCreationTime >> 32);
                    338:                        ft.dwLowDateTime = (DWORD)volumeCreationTime;
                    339:                }
                    340:                mputLong (p, ft.dwHighDateTime);
                    341:                mputLong (p, ft.dwLowDateTime);
                    342: 
1.1.1.6   root      343:                // Header modification time/date
1.1       root      344:                GetLocalTime (&st);
                    345:                SystemTimeToFileTime (&st, &ft);
                    346:                mputLong (p, ft.dwHighDateTime);
                    347:                mputLong (p, ft.dwLowDateTime);
1.1.1.8   root      348: 
                    349: #else
                    350:                struct timeval tv;
                    351:                unsigned __int64 ct, wt;
                    352:                gettimeofday (&tv, NULL);
                    353: 
                    354:                // Unix time => Windows file time
                    355:                wt = ((unsigned __int64)tv.tv_sec + 134774LL * 24 * 3600) * 1000LL * 1000 * 10;
                    356: 
                    357:                if (volumeCreationTime == 0)
                    358:                        ct = wt;
                    359:                else
                    360:                        ct = volumeCreationTime;
                    361: 
                    362:                mputInt64 (p, ct);
                    363:                mputInt64 (p, wt);
                    364: #endif
                    365: 
1.1       root      366:        }
                    367: 
1.1.1.4   root      368:        // Hidden volume size
                    369:        cryptoInfo->hiddenVolumeSize = hiddenVolumeSize;
                    370:        mputInt64 (p, cryptoInfo->hiddenVolumeSize);
1.1.1.7   root      371:        cryptoInfo->hiddenVolume = cryptoInfo->hiddenVolumeSize != 0;
1.1.1.4   root      372: 
1.1.1.7   root      373:        // The key set
1.1       root      374:        memcpy (header + HEADER_DISKKEY, keyInfo.key, DISKKEY_SIZE);
                    375: 
                    376: 
1.1.1.6   root      377:        /* Header encryption */
1.1       root      378: 
                    379:        memcpy (cryptoInfo->iv, dk, DISK_IV_SIZE);
1.1.1.6   root      380:        retVal = EAInit (cryptoInfo->ea, dk + DISK_IV_SIZE, cryptoInfo->ks);
                    381:        if (retVal != 0)
                    382:                return retVal;
1.1       root      383: 
1.1.1.7   root      384:        // Mode of operation
                    385:        if (!EAInitMode (cryptoInfo))
                    386:                return ERR_OUTOFMEMORY;
                    387: 
                    388:        EncryptBuffer ((unsigned __int32 *) (header + HEADER_ENCRYPTEDDATA),
                    389:                HEADER_ENCRYPTEDDATASIZE,
                    390:                cryptoInfo);
1.1       root      391: 
                    392: 
1.1.1.6   root      393:        /* cryptoInfo setup for further use (disk format) */
1.1       root      394: 
1.1.1.6   root      395:        // Init with the master key 
                    396:        retVal = EAInit (cryptoInfo->ea, keyInfo.key + DISK_IV_SIZE, cryptoInfo->ks);
                    397:        if (retVal != 0)
                    398:                return retVal;
1.1.1.8   root      399:        memcpy (cryptoInfo->master_key, keyInfo.key + DISK_IV_SIZE, sizeof (keyInfo.key) - DISK_IV_SIZE);
1.1       root      400: 
1.1.1.7   root      401:        // The secondary key (LRW mode)
1.1       root      402:        memcpy (cryptoInfo->iv, keyInfo.key, DISK_IV_SIZE);
                    403: 
1.1.1.7   root      404:        // Mode of operation
                    405:        if (!EAInitMode (cryptoInfo))
                    406:                return ERR_OUTOFMEMORY;
                    407: 
1.1.1.2   root      408: 
1.1       root      409: #ifdef VOLFORMAT
1.1.1.3   root      410:        if (showKeys)
1.1       root      411:        {
                    412:                char tmp[64];
                    413:                BOOL dots3 = FALSE;
                    414:                int i, j;
                    415: 
1.1.1.4   root      416:                j = EAGetKeySize (ea);
1.1       root      417: 
1.1.1.6   root      418:                if (j > NBR_KEY_BYTES_TO_DISPLAY)
1.1       root      419:                {
                    420:                        dots3 = TRUE;
1.1.1.6   root      421:                        j = NBR_KEY_BYTES_TO_DISPLAY;
1.1       root      422:                }
                    423: 
                    424:                tmp[0] = 0;
                    425:                for (i = 0; i < j; i++)
                    426:                {
                    427:                        char tmp2[8] =
                    428:                        {0};
                    429:                        sprintf (tmp2, "%02X", (int) (unsigned char) keyInfo.key[i + DISK_IV_SIZE]);
                    430:                        strcat (tmp, tmp2);
                    431:                }
                    432: 
1.1.1.6   root      433:                if (dots3)
1.1       root      434:                {
                    435:                        strcat (tmp, "...");
                    436:                }
                    437: 
                    438: 
                    439:                SetWindowText (hDiskKey, tmp);
                    440: 
                    441:                tmp[0] = 0;
1.1.1.6   root      442:                for (i = 0; i < NBR_KEY_BYTES_TO_DISPLAY; i++)
1.1       root      443:                {
                    444:                        char tmp2[8];
1.1.1.3   root      445:                        sprintf (tmp2, "%02X", (int) (unsigned char) dk[DISK_IV_SIZE + i]);
1.1       root      446:                        strcat (tmp, tmp2);
                    447:                }
                    448: 
1.1.1.6   root      449:                if (dots3)
1.1.1.3   root      450:                {
                    451:                        strcat (tmp, "...");
                    452:                }
                    453: 
                    454:                SetWindowText (hHeaderKey, tmp);
1.1       root      455:        }
                    456: #endif
                    457: 
1.1.1.3   root      458:        burn (dk, sizeof(dk));
1.1       root      459:        burn (&keyInfo, sizeof (keyInfo));
                    460: 
                    461:        *retInfo = cryptoInfo;
                    462:        return 0;
                    463: }
                    464: 
                    465: #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.