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

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.6   root        6:    Copyright (c) 2004 TrueCrypt Team, and are covered by TrueCrypt License 2.0
                      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: #ifdef _WIN32
        !           280:        if (!RandgetBytes (keyInfo.key_salt, PKCS5_SALT_SIZE, !bWipeMode))
        !           281:                return ERR_CIPHER_INIT_WEAK_KEY; 
        !           282: #else
        !           283:        if (!bWipeMode)
        !           284:        {
        !           285:                if (!RandgetBytes (keyInfo.key_salt, PKCS5_SALT_SIZE, FALSE))
        !           286:                        return ERR_CIPHER_INIT_WEAK_KEY; 
        !           287:        }
        !           288:        else
        !           289:        {
        !           290:                if (!RandpeekBytes (keyInfo.key_salt, PKCS5_SALT_SIZE))
        !           291:                        return ERR_CIPHER_INIT_WEAK_KEY; 
        !           292:        }
        !           293: #endif 
1.1       root      294: 
1.1.1.7   root      295:        // PKCS5 is used to derive the header key and the secondary header key (LRW mode) from the password
1.1.1.6   root      296:        switch (pkcs5)
1.1       root      297:        {
1.1.1.6   root      298:        case SHA1:
                    299:                derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
                    300:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                    301:                break;
                    302: 
                    303:        case RIPEMD160:
                    304:                derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
                    305:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                    306:                break;
                    307: 
                    308:        case WHIRLPOOL:
                    309:                derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.key_salt,
                    310:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, DISK_IV_SIZE + EAGetLargestKey());
                    311:                break;
                    312:        } 
1.1.1.7   root      313:        // Verify that the secondary key is not weak
                    314:        if (DetectWeakSecondaryKey (dk, CipherGetBlockSize (EAGetFirstCipher (ea))))
                    315:                return ERR_CIPHER_INIT_WEAK_KEY; 
                    316: 
1.1       root      317: 
1.1.1.6   root      318:        /* Header setup */
1.1       root      319: 
                    320:        // Salt
1.1.1.6   root      321:        mputBytes (p, keyInfo.key_salt, PKCS5_SALT_SIZE);       
1.1       root      322: 
                    323:        // Magic
1.1.1.8 ! root      324:        mputLong (p, 0x54525545);
1.1       root      325: 
                    326:        // Header version
1.1.1.4   root      327:        mputWord (p, VOLUME_HEADER_VERSION);
1.1       root      328: 
                    329:        // Required program version to handle this volume
1.1.1.4   root      330:        mputWord (p, VOL_REQ_PROG_VERSION);
1.1       root      331: 
1.1.1.7   root      332:        // CRC of the key set
1.1       root      333:        x = crc32(keyInfo.key, DISKKEY_SIZE);
                    334:        mputLong (p, x);
                    335: 
                    336:        // Time
                    337:        {
1.1.1.8 ! root      338: #ifdef _WIN32
1.1       root      339:                SYSTEMTIME st;
                    340:                FILETIME ft;
                    341: 
                    342:                // Volume creation time
                    343:                if (volumeCreationTime == 0)
                    344:                {
                    345:                        GetLocalTime (&st);
                    346:                        SystemTimeToFileTime (&st, &ft);
                    347:                }
                    348:                else
                    349:                {
                    350:                        ft.dwHighDateTime = (DWORD)(volumeCreationTime >> 32);
                    351:                        ft.dwLowDateTime = (DWORD)volumeCreationTime;
                    352:                }
                    353:                mputLong (p, ft.dwHighDateTime);
                    354:                mputLong (p, ft.dwLowDateTime);
                    355: 
1.1.1.6   root      356:                // Header modification time/date
1.1       root      357:                GetLocalTime (&st);
                    358:                SystemTimeToFileTime (&st, &ft);
                    359:                mputLong (p, ft.dwHighDateTime);
                    360:                mputLong (p, ft.dwLowDateTime);
1.1.1.8 ! root      361: 
        !           362: #else
        !           363:                struct timeval tv;
        !           364:                unsigned __int64 ct, wt;
        !           365:                gettimeofday (&tv, NULL);
        !           366: 
        !           367:                // Unix time => Windows file time
        !           368:                wt = ((unsigned __int64)tv.tv_sec + 134774LL * 24 * 3600) * 1000LL * 1000 * 10;
        !           369: 
        !           370:                if (volumeCreationTime == 0)
        !           371:                        ct = wt;
        !           372:                else
        !           373:                        ct = volumeCreationTime;
        !           374: 
        !           375:                mputInt64 (p, ct);
        !           376:                mputInt64 (p, wt);
        !           377: #endif
        !           378: 
1.1       root      379:        }
                    380: 
1.1.1.4   root      381:        // Hidden volume size
                    382:        cryptoInfo->hiddenVolumeSize = hiddenVolumeSize;
                    383:        mputInt64 (p, cryptoInfo->hiddenVolumeSize);
1.1.1.7   root      384:        cryptoInfo->hiddenVolume = cryptoInfo->hiddenVolumeSize != 0;
1.1.1.4   root      385: 
1.1.1.7   root      386:        // The key set
1.1       root      387:        memcpy (header + HEADER_DISKKEY, keyInfo.key, DISKKEY_SIZE);
                    388: 
                    389: 
1.1.1.6   root      390:        /* Header encryption */
1.1       root      391: 
                    392:        memcpy (cryptoInfo->iv, dk, DISK_IV_SIZE);
1.1.1.6   root      393:        retVal = EAInit (cryptoInfo->ea, dk + DISK_IV_SIZE, cryptoInfo->ks);
                    394:        if (retVal != 0)
                    395:                return retVal;
1.1       root      396: 
1.1.1.7   root      397:        // Mode of operation
                    398:        if (!EAInitMode (cryptoInfo))
                    399:                return ERR_OUTOFMEMORY;
                    400: 
                    401:        EncryptBuffer ((unsigned __int32 *) (header + HEADER_ENCRYPTEDDATA),
                    402:                HEADER_ENCRYPTEDDATASIZE,
                    403:                cryptoInfo);
1.1       root      404: 
                    405: 
1.1.1.6   root      406:        /* cryptoInfo setup for further use (disk format) */
1.1       root      407: 
1.1.1.6   root      408:        // Init with the master key 
                    409:        retVal = EAInit (cryptoInfo->ea, keyInfo.key + DISK_IV_SIZE, cryptoInfo->ks);
                    410:        if (retVal != 0)
                    411:                return retVal;
1.1.1.8 ! root      412:        memcpy (cryptoInfo->master_key, keyInfo.key + DISK_IV_SIZE, sizeof (keyInfo.key) - DISK_IV_SIZE);
1.1       root      413: 
1.1.1.7   root      414:        // The secondary key (LRW mode)
1.1       root      415:        memcpy (cryptoInfo->iv, keyInfo.key, DISK_IV_SIZE);
                    416: 
1.1.1.7   root      417:        // Mode of operation
                    418:        if (!EAInitMode (cryptoInfo))
                    419:                return ERR_OUTOFMEMORY;
                    420: 
1.1.1.2   root      421: 
1.1       root      422: #ifdef VOLFORMAT
1.1.1.3   root      423:        if (showKeys)
1.1       root      424:        {
                    425:                char tmp[64];
                    426:                BOOL dots3 = FALSE;
                    427:                int i, j;
                    428: 
1.1.1.4   root      429:                j = EAGetKeySize (ea);
1.1       root      430: 
1.1.1.6   root      431:                if (j > NBR_KEY_BYTES_TO_DISPLAY)
1.1       root      432:                {
                    433:                        dots3 = TRUE;
1.1.1.6   root      434:                        j = NBR_KEY_BYTES_TO_DISPLAY;
1.1       root      435:                }
                    436: 
                    437:                tmp[0] = 0;
                    438:                for (i = 0; i < j; i++)
                    439:                {
                    440:                        char tmp2[8] =
                    441:                        {0};
                    442:                        sprintf (tmp2, "%02X", (int) (unsigned char) keyInfo.key[i + DISK_IV_SIZE]);
                    443:                        strcat (tmp, tmp2);
                    444:                }
                    445: 
1.1.1.6   root      446:                if (dots3)
1.1       root      447:                {
                    448:                        strcat (tmp, "...");
                    449:                }
                    450: 
                    451: 
                    452:                SetWindowText (hDiskKey, tmp);
                    453: 
                    454:                tmp[0] = 0;
1.1.1.6   root      455:                for (i = 0; i < NBR_KEY_BYTES_TO_DISPLAY; i++)
1.1       root      456:                {
                    457:                        char tmp2[8];
1.1.1.3   root      458:                        sprintf (tmp2, "%02X", (int) (unsigned char) dk[DISK_IV_SIZE + i]);
1.1       root      459:                        strcat (tmp, tmp2);
                    460:                }
                    461: 
1.1.1.6   root      462:                if (dots3)
1.1.1.3   root      463:                {
                    464:                        strcat (tmp, "...");
                    465:                }
                    466: 
                    467:                SetWindowText (hHeaderKey, tmp);
1.1       root      468:        }
                    469: #endif
                    470: 
1.1.1.3   root      471:        burn (dk, sizeof(dk));
1.1       root      472:        burn (&keyInfo, sizeof (keyInfo));
                    473: 
                    474:        *retInfo = cryptoInfo;
                    475:        return 0;
                    476: }
                    477: 
                    478: #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.