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

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