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

1.1.1.10  root        1: /*
1.1.1.12! root        2:  Legal Notice: Some portions of the source code contained in this file were
        !             3:  derived from the source code of Encryption for the Masses 2.02a, which is
        !             4:  Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
        !             5:  Agreement for Encryption for the Masses'. Modifications and additions to
        !             6:  the original source code (contained in this file) and all other portions of
        !             7:  this file are Copyright (c) 2003-2008 TrueCrypt Foundation and are governed
        !             8:  by the TrueCrypt License 2.4 the full text of which is contained in the
        !             9:  file License.txt included in TrueCrypt binary and source code distribution
1.1.1.10  root       10:  packages. */
1.1       root       11: 
1.1.1.6   root       12: #include "Tcdefs.h"
1.1       root       13: 
1.1.1.12! root       14: #ifndef TC_WINDOWS_BOOT
1.1       root       15: #include <fcntl.h>
1.1.1.10  root       16: #include <string.h>
1.1       root       17: #include <sys/types.h>
                     18: #include <sys/stat.h>
                     19: #include <time.h>
1.1.1.12! root       20: #endif
1.1       root       21: 
1.1.1.6   root       22: #ifdef _WIN32
                     23: #include <io.h>
                     24: #include "Random.h"
                     25: #endif
                     26: 
                     27: #include "Crypto.h"
1.1.1.10  root       28: #include "Common/Endian.h"
1.1.1.6   root       29: #include "Volumes.h"
                     30: 
                     31: #include "Pkcs5.h"
                     32: #include "Crc.h"
1.1       root       33: 
                     34: 
1.1.1.12! root       35: 
        !            36: /* Volume header v3 structure: */
        !            37: //
        !            38: // Offset      Length  Description
        !            39: // ------------------------------------------
        !            40: // Unencrypted:
        !            41: // 0           64              Salt
        !            42: // Encrypted:
        !            43: // 64          4               ASCII string 'TRUE'
        !            44: // 68          2               Header version
        !            45: // 70          2               Required program version
        !            46: // 72          4               CRC-32 checksum of the (decrypted) bytes 256-511
        !            47: // 76          8               Volume creation time
        !            48: // 84          8               Header creation time
        !            49: // 92          8               Size of hidden volume in bytes (0 = normal volume)
        !            50: // 100         8               Size of the volume in bytes (identical with field 92 for hidden volumes)
        !            51: // 108         8               Start byte offset of the encrypted area of the volume
        !            52: // 116         8               Size of the encrypted area of the volume in bytes
        !            53: // 124         132             Reserved (set to zero)
        !            54: // 256         256             Concatenated primary master key(s) and secondary master key(s) (XTS mode)
1.1       root       55: 
                     56: 
1.1.1.12! root       57: /* Deprecated/legacy volume header v2 structure (used before TrueCrypt 5.0): */
1.1       root       58: //
                     59: // Offset      Length  Description
                     60: // ------------------------------------------
                     61: // Unencrypted:
1.1.1.6   root       62: // 0           64              Salt
1.1       root       63: // Encrypted:
1.1.1.4   root       64: // 64          4               ASCII string 'TRUE'
1.1       root       65: // 68          2               Header version
                     66: // 70          2               Required program version
1.1.1.7   root       67: // 72          4               CRC-32 checksum of the (decrypted) bytes 256-511
1.1       root       68: // 76          8               Volume creation time
                     69: // 84          8               Header creation time
1.1.1.4   root       70: // 92          8               Size of hidden volume in bytes (0 = normal volume)
1.1.1.7   root       71: // 100         156             Reserved (set to zero)
1.1.1.12! root       72: // 256         32              For LRW (deprecated/legacy), secondary key
        !            73: //                                     For CBC (deprecated/legacy), data used to generate IV and whitening values
1.1.1.7   root       74: // 288         224             Master key(s)
1.1       root       75: 
1.1.1.12! root       76: 
        !            77: 
        !            78: uint16 GetHeaderField16 (byte *header, size_t offset)
        !            79: {
        !            80:        return BE16 (*(uint16 *) (header + offset));
        !            81: }
        !            82: 
        !            83: 
        !            84: uint32 GetHeaderField32 (byte *header, size_t offset)
        !            85: {
        !            86:        return BE32 (*(uint32 *) (header + offset));
        !            87: }
        !            88: 
        !            89: 
        !            90: UINT64_STRUCT GetHeaderField64 (byte *header, size_t offset)
        !            91: {
        !            92:        UINT64_STRUCT uint64Struct;
        !            93: 
        !            94: #ifndef TC_NO_COMPILER_INT64
        !            95:        uint64Struct.Value = BE64 (*(uint64 *) (header + offset));
        !            96: #else
        !            97:        uint64Struct.HighPart = BE32 (*(uint32 *) (header + offset));
        !            98:        uint64Struct.LowPart = BE32 (*(uint32 *) (header + offset + 4));
        !            99: #endif
        !           100:        return uint64Struct;
        !           101: }
        !           102: 
        !           103: 
        !           104: int VolumeReadHeader (BOOL bBoot, char *encryptedHeader, Password *password, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
1.1       root      105: {
1.1.1.6   root      106:        char header[HEADER_SIZE];
1.1       root      107:        KEY_INFO keyInfo;
                    108:        PCRYPTO_INFO cryptoInfo;
1.1.1.12! root      109:        char dk[MASTER_KEYDATA_SIZE];
        !           110:        int pkcs5_prf;
1.1       root      111:        int headerVersion, requiredVersion;
1.1.1.6   root      112:        int status;
1.1.1.12! root      113:        int primaryKeyOffset;
1.1.1.6   root      114: 
1.1.1.12! root      115: #ifdef _WIN32
        !           116: #ifndef DEVICE_DRIVER
        !           117:        VirtualLock (&keyInfo, sizeof (keyInfo));
        !           118:        VirtualLock (&dk, sizeof (dk));
        !           119: #endif
        !           120: #endif
1.1.1.7   root      121: 
1.1.1.12! root      122:        if (retHeaderCryptoInfo != NULL)
        !           123:        {
        !           124:                cryptoInfo = retHeaderCryptoInfo;
        !           125:        }
        !           126:        else
        !           127:        {
        !           128:                cryptoInfo = *retInfo = crypto_open ();
        !           129:                if (cryptoInfo == NULL)
        !           130:                        return ERR_OUTOFMEMORY;
        !           131:        }
1.1       root      132: 
1.1.1.12! root      133:        crypto_loadkey (&keyInfo, password->Text, (int) password->Length);
1.1       root      134: 
1.1.1.12! root      135:        // PKCS5 is used to derive the primary header key(s) and secondary header key(s) (XTS mode) from the password
        !           136:        memcpy (keyInfo.salt, encryptedHeader + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE);
1.1       root      137: 
1.1.1.3   root      138:        // Test all available PKCS5 PRFs
1.1.1.12! root      139:        for (pkcs5_prf = FIRST_PRF_ID; pkcs5_prf <= LAST_PRF_ID; pkcs5_prf++)
1.1       root      140:        {
1.1.1.12! root      141:                BOOL lrw64InitDone = FALSE;             // Deprecated/legacy
        !           142:                BOOL lrw128InitDone = FALSE;    // Deprecated/legacy
1.1.1.7   root      143: 
1.1.1.12! root      144:                keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, bBoot);
1.1.1.6   root      145: 
1.1.1.12! root      146:                switch (pkcs5_prf)
1.1.1.3   root      147:                {
1.1.1.12! root      148:                case RIPEMD160:
        !           149:                        derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
        !           150:                                PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
1.1.1.6   root      151:                        break;
                    152: 
1.1.1.12! root      153: #ifndef TC_WINDOWS_BOOT
        !           154: 
        !           155:                case SHA512:
        !           156:                        derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
        !           157:                                PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
        !           158:                        break;
        !           159: 
        !           160:                case SHA1:
        !           161:                        // Deprecated/legacy
        !           162:                        derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
        !           163:                                PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
1.1.1.6   root      164:                        break;
                    165: 
                    166:                case WHIRLPOOL:
1.1.1.12! root      167:                        derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
        !           168:                                PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
1.1.1.6   root      169:                        break;
1.1.1.12! root      170: #endif
        !           171: 
        !           172:                default:                
        !           173:                        // Unknown/wrong ID
        !           174:                        TC_THROW_FATAL_EXCEPTION;
1.1.1.4   root      175:                } 
1.1       root      176: 
1.1.1.12! root      177:                // Test all available modes of operation
        !           178:                for (cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
        !           179:                        cryptoInfo->mode <= LAST_MODE_OF_OPERATION;
        !           180:                        cryptoInfo->mode++)
1.1.1.3   root      181:                {
1.1.1.12! root      182:                        switch (cryptoInfo->mode)
        !           183:                        {
        !           184: #ifndef TC_WINDOWS_BOOT
        !           185:                        case LRW:
        !           186:                        case CBC:
        !           187:                        case INNER_CBC:
        !           188:                        case OUTER_CBC:
        !           189: 
        !           190:                                // For LRW (deprecated/legacy), copy the tweak key 
        !           191:                                // For CBC (deprecated/legacy), copy the IV/whitening seed 
        !           192:                                memcpy (cryptoInfo->k2, dk, LEGACY_VOL_IV_SIZE);
        !           193:                                primaryKeyOffset = LEGACY_VOL_IV_SIZE;
        !           194:                                break;
        !           195: #endif
        !           196:                        default:
        !           197:                                primaryKeyOffset = 0;
        !           198:                        }
1.1.1.6   root      199: 
1.1.1.12! root      200:                        // Test all available encryption algorithms
        !           201:                        for (cryptoInfo->ea = EAGetFirst ();
        !           202:                                cryptoInfo->ea != 0;
        !           203:                                cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
1.1.1.6   root      204:                        {
1.1.1.12! root      205:                                int blockSize;
        !           206: 
        !           207:                                if (!EAIsModeSupported (cryptoInfo->ea, cryptoInfo->mode))
        !           208:                                        continue;       // This encryption algorithm has never been available with this mode of operation
1.1.1.7   root      209: 
1.1.1.12! root      210:                                blockSize = CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea));
        !           211: 
        !           212:                                status = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
        !           213:                                if (status == ERR_CIPHER_INIT_FAILURE)
        !           214:                                        goto err;
        !           215: 
        !           216:                                // Init objects related to the mode of operation
        !           217: 
        !           218:                                if (cryptoInfo->mode == XTS)
        !           219:                                {
        !           220:                                        // Copy the secondary key (if cascade, multiple concatenated)
        !           221:                                        memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
        !           222: 
        !           223:                                        // Secondary key schedule
        !           224:                                        if (!EAInitMode (cryptoInfo))
        !           225:                                        {
        !           226:                                                status = ERR_MODE_INIT_FAILED;
        !           227:                                                goto err;
        !           228:                                        }
        !           229:                                }
        !           230: #ifndef TC_WINDOWS_BOOT
        !           231:                                else if (cryptoInfo->mode == LRW
1.1.1.7   root      232:                                        && (blockSize == 8 && !lrw64InitDone || blockSize == 16 && !lrw128InitDone))
                    233:                                {
1.1.1.12! root      234:                                        // Deprecated/legacy
        !           235: 
1.1.1.7   root      236:                                        if (!EAInitMode (cryptoInfo))
                    237:                                        {
                    238:                                                status = ERR_MODE_INIT_FAILED;
                    239:                                                goto err;
                    240:                                        }
                    241: 
1.1.1.12! root      242:                                        if (blockSize == 8)
1.1.1.7   root      243:                                                lrw64InitDone = TRUE;
                    244:                                        else if (blockSize == 16)
                    245:                                                lrw128InitDone = TRUE;
                    246:                                }
1.1.1.12! root      247: #endif
1.1.1.7   root      248: 
1.1.1.12! root      249:                                // Copy the header for decryption
        !           250:                                memcpy (header, encryptedHeader, HEADER_SIZE);
1.1.1.7   root      251: 
                    252:                                // Try to decrypt header 
                    253: 
1.1.1.12! root      254:                                DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
1.1.1.7   root      255: 
                    256:                                // Magic 'TRUE'
1.1.1.12! root      257:                                if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x54525545)
1.1.1.7   root      258:                                        continue;
                    259: 
                    260:                                // Header version
1.1.1.12! root      261:                                headerVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION);
1.1.1.7   root      262: 
                    263:                                // Required program version
1.1.1.12! root      264:                                requiredVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_REQUIRED_VERSION);
1.1.1.7   root      265: 
                    266:                                // Check CRC of the key set
1.1.1.12! root      267:                                if (GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
1.1.1.7   root      268:                                        continue;
                    269: 
                    270:                                // Now we have the correct password, cipher, hash algorithm, and volume type
                    271: 
                    272:                                // Check the version required to handle this volume
                    273:                                if (requiredVersion > VERSION_NUM)
                    274:                                {
                    275:                                        status = ERR_NEW_VERSION_REQUIRED;
                    276:                                        goto err;
                    277:                                }
                    278: 
1.1.1.12! root      279: #ifndef TC_WINDOWS_BOOT
1.1.1.7   root      280:                                // Volume creation time
1.1.1.12! root      281:                                cryptoInfo->volume_creation_time = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_CREATION_TIME).Value;
1.1.1.7   root      282: 
                    283:                                // Header creation time
1.1.1.12! root      284:                                cryptoInfo->header_creation_time = GetHeaderField64 (header, TC_HEADER_OFFSET_MODIFICATION_TIME).Value;
1.1.1.7   root      285: 
                    286:                                // Hidden volume size (if any)
1.1.1.12! root      287:                                cryptoInfo->hiddenVolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE).Value;
        !           288: #endif
        !           289:                                // Volume size
        !           290:                                cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);
        !           291:                                
        !           292:                                // Encrypted area size and length
        !           293:                                cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
        !           294:                                cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);
        !           295: 
        !           296:                                // Preserve scheduled header keys if requested                  
        !           297:                                if (retHeaderCryptoInfo)
        !           298:                                {
        !           299:                                        if (retInfo == NULL)
        !           300:                                        {
        !           301:                                                cryptoInfo->pkcs5 = pkcs5_prf;
        !           302:                                                cryptoInfo->noIterations = keyInfo.noIterations;
        !           303:                                                goto ret;
        !           304:                                        }
        !           305: 
        !           306:                                        cryptoInfo = *retInfo = crypto_open ();
        !           307:                                        if (cryptoInfo == NULL)
        !           308:                                        {
        !           309:                                                status = ERR_OUTOFMEMORY;
        !           310:                                                goto err;
        !           311:                                        }
1.1.1.7   root      312: 
1.1.1.12! root      313:                                        memcpy (cryptoInfo, retHeaderCryptoInfo, sizeof (*cryptoInfo));
        !           314:                                }
        !           315: 
        !           316:                                // Master key data
        !           317:                                memcpy (keyInfo.master_keydata, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE);
        !           318:                                memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
        !           319: 
        !           320: #ifndef TC_WINDOWS_BOOT
        !           321:                                // PKCS #5
        !           322:                                memcpy (cryptoInfo->salt, keyInfo.salt, PKCS5_SALT_SIZE);
        !           323:                                cryptoInfo->pkcs5 = pkcs5_prf;
1.1.1.7   root      324:                                cryptoInfo->noIterations = keyInfo.noIterations;
1.1.1.12! root      325: #endif
1.1.1.7   root      326: 
                    327:                                // Init the encryption algorithm with the decrypted master key
1.1.1.12! root      328:                                status = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
1.1.1.7   root      329:                                if (status == ERR_CIPHER_INIT_FAILURE)
                    330:                                        goto err;
                    331: 
1.1.1.12! root      332:                                switch (cryptoInfo->mode)
        !           333:                                {
        !           334: #ifndef TC_WINDOWS_BOOT
        !           335:                                case LRW:
        !           336:                                case CBC:
        !           337:                                case INNER_CBC:
        !           338:                                case OUTER_CBC:
        !           339: 
        !           340:                                        // For LRW (deprecated/legacy), the tweak key
        !           341:                                        // For CBC (deprecated/legacy), the IV/whitening seed
        !           342:                                        memcpy (cryptoInfo->k2, keyInfo.master_keydata, LEGACY_VOL_IV_SIZE);
        !           343:                                        break;
        !           344: #endif
        !           345:                                default:
        !           346:                                        // The secondary master key (if cascade, multiple concatenated)
        !           347:                                        memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
        !           348: 
        !           349:                                }
1.1.1.7   root      350: 
                    351:                                if (!EAInitMode (cryptoInfo))
                    352:                                {
                    353:                                        status = ERR_MODE_INIT_FAILED;
                    354:                                        goto err;
                    355:                                }
1.1.1.6   root      356: 
1.1.1.12! root      357:                                // Clear out the temporary key buffers
        !           358: ret:
1.1.1.7   root      359:                                burn (dk, sizeof(dk));
1.1.1.12! root      360:                                burn (&keyInfo, sizeof (keyInfo));
1.1.1.6   root      361: 
1.1.1.7   root      362:                                return 0;
                    363:                        }
1.1.1.2   root      364:                }
1.1       root      365:        }
1.1.1.6   root      366:        status = ERR_PASSWORD_WRONG;
1.1       root      367: 
1.1.1.6   root      368: err:
1.1.1.12! root      369:        if (cryptoInfo != retHeaderCryptoInfo)
        !           370:        {
        !           371:                crypto_close(cryptoInfo);
        !           372:                *retInfo = NULL; 
        !           373:        }
        !           374: 
1.1       root      375:        burn (&keyInfo, sizeof (keyInfo));
1.1.1.12! root      376:        burn (dk, sizeof(dk));
1.1.1.6   root      377:        return status;
1.1       root      378: }
                    379: 
1.1.1.12! root      380: #if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT)
1.1       root      381: 
                    382: #ifdef VOLFORMAT
1.1.1.10  root      383: #include "../Format/TcFormat.h"
1.1       root      384: #endif
                    385: 
1.1.1.12! root      386: // Creates a volume header in memory
        !           387: int VolumeWriteHeader (BOOL bBoot, char *header, int ea, int mode, Password *password,
        !           388:                   int pkcs5_prf, char *masterKeydata, unsigned __int64 volumeCreationTime, PCRYPTO_INFO *retInfo,
        !           389:                   unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize,
        !           390:                   unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, BOOL bWipeMode)
1.1       root      391: {
                    392:        unsigned char *p = (unsigned char *) header;
1.1.1.6   root      393:        static KEY_INFO keyInfo;
1.1       root      394: 
1.1.1.6   root      395:        int nUserKeyLen = password->Length;
1.1       root      396:        PCRYPTO_INFO cryptoInfo = crypto_open ();
1.1.1.12! root      397:        static char dk[MASTER_KEYDATA_SIZE];
1.1       root      398:        int x;
1.1.1.6   root      399:        int retVal = 0;
1.1.1.12! root      400:        int primaryKeyOffset;
1.1       root      401: 
                    402:        if (cryptoInfo == NULL)
                    403:                return ERR_OUTOFMEMORY;
                    404: 
1.1.1.12! root      405:        memset (header, 0, HEADER_SIZE);
1.1.1.8   root      406: 
                    407: #ifdef _WIN32
1.1.1.2   root      408:        VirtualLock (&keyInfo, sizeof (keyInfo));
1.1.1.6   root      409:        VirtualLock (&dk, sizeof (dk));
1.1.1.8   root      410: #endif
1.1       root      411: 
1.1.1.6   root      412:        /* Encryption setup */
1.1       root      413: 
1.1.1.12! root      414:        if (masterKeydata == NULL)
1.1.1.7   root      415:        {
1.1.1.12! root      416:                // We have no master key data (creating a new volume) so we'll use the TrueCrypt RNG to generate them
1.1.1.7   root      417: 
1.1.1.12! root      418:                int bytesNeeded;
        !           419: 
        !           420:                switch (mode)
        !           421:                {
        !           422:                case LRW:
        !           423:                case CBC:
        !           424:                case INNER_CBC:
        !           425:                case OUTER_CBC:
        !           426: 
        !           427:                        // Deprecated/legacy modes of operation
        !           428:                        bytesNeeded = LEGACY_VOL_IV_SIZE + EAGetKeySize (ea);
        !           429: 
        !           430:                        /* In fact, this should never be the case since new volumes are not supposed to use
        !           431:                           any deprecated mode of operation. */
        !           432:                        return ERR_VOL_FORMAT_BAD;
        !           433: 
        !           434:                default:
        !           435:                        bytesNeeded = EAGetKeySize (ea) * 2;    // Size of primary + secondary key(s)
        !           436:                }
        !           437: 
        !           438:                if (!RandgetBytes (keyInfo.master_keydata, bytesNeeded, TRUE))
1.1.1.8   root      439:                        return ERR_CIPHER_INIT_WEAK_KEY;
1.1.1.7   root      440:        }
1.1.1.2   root      441:        else
1.1.1.12! root      442:        {
        !           443:                // We already have existing master key data (the header is being re-encrypted)
        !           444:                memcpy (keyInfo.master_keydata, masterKeydata, MASTER_KEYDATA_SIZE);
        !           445:        }
1.1.1.2   root      446: 
1.1.1.6   root      447:        // User key 
                    448:        memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
1.1       root      449:        keyInfo.keyLength = nUserKeyLen;
1.1.1.12! root      450:        keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, bBoot);
1.1       root      451: 
                    452:        // User selected encryption algorithm
1.1.1.4   root      453:        cryptoInfo->ea = ea;
1.1       root      454: 
1.1.1.7   root      455:        // Mode of operation
                    456:        cryptoInfo->mode = mode;
                    457: 
1.1.1.8   root      458:        // Salt for header key derivation
1.1.1.12! root      459:        if (!RandgetBytes (keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
1.1.1.8   root      460:                return ERR_CIPHER_INIT_WEAK_KEY; 
1.1       root      461: 
1.1.1.12! root      462:        // PBKDF2 (PKCS5) is used to derive primary header key(s) and secondary header key(s) (XTS) from the password/keyfiles
        !           463:        switch (pkcs5_prf)
1.1       root      464:        {
1.1.1.12! root      465:        case SHA512:
        !           466:                derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
        !           467:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
        !           468:                break;
        !           469: 
1.1.1.6   root      470:        case SHA1:
1.1.1.12! root      471:                // Deprecated/legacy
        !           472:                derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
        !           473:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
1.1.1.6   root      474:                break;
                    475: 
                    476:        case RIPEMD160:
1.1.1.12! root      477:                derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
        !           478:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
1.1.1.6   root      479:                break;
                    480: 
                    481:        case WHIRLPOOL:
1.1.1.12! root      482:                derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
        !           483:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
1.1.1.6   root      484:                break;
1.1.1.7   root      485: 
1.1.1.12! root      486:        default:                
        !           487:                // Unknown/wrong ID
        !           488:                TC_THROW_FATAL_EXCEPTION;
        !           489:        } 
1.1       root      490: 
1.1.1.6   root      491:        /* Header setup */
1.1       root      492: 
                    493:        // Salt
1.1.1.12! root      494:        mputBytes (p, keyInfo.salt, PKCS5_SALT_SIZE);   
1.1       root      495: 
                    496:        // Magic
1.1.1.8   root      497:        mputLong (p, 0x54525545);
1.1       root      498: 
                    499:        // Header version
1.1.1.12! root      500:        switch (mode)
        !           501:        {
        !           502:        case LRW:
        !           503:        case CBC:
        !           504:        case OUTER_CBC:
        !           505:        case INNER_CBC:
        !           506:                // Deprecated/legacy modes (used before TrueCrypt 5.0)
        !           507:                mputWord (p, 0x0002);
        !           508:                break;
        !           509:        default:
        !           510:                mputWord (p, VOLUME_HEADER_VERSION);
        !           511:        }
1.1       root      512: 
                    513:        // Required program version to handle this volume
1.1.1.12! root      514:        switch (mode)
        !           515:        {
        !           516:        case LRW:
        !           517:                // Deprecated/legacy
        !           518:                mputWord (p, 0x0410);
        !           519:                break;
        !           520:        case OUTER_CBC:
        !           521:        case INNER_CBC:
        !           522:                // Deprecated/legacy
        !           523:                mputWord (p, 0x0300);
        !           524:                break;
        !           525:        case CBC:
        !           526:                // Deprecated/legacy
        !           527:                mputWord (p, hiddenVolumeSize > 0 ? 0x0300 : 0x0100);
        !           528:                break;
        !           529:        default:
        !           530:                mputWord (p, VOL_REQ_PROG_VERSION);
        !           531:        }
1.1       root      532: 
1.1.1.12! root      533:        // CRC of the master key data
        !           534:        x = GetCrc32(keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
1.1       root      535:        mputLong (p, x);
                    536: 
                    537:        // Time
                    538:        {
1.1.1.8   root      539: #ifdef _WIN32
1.1       root      540:                SYSTEMTIME st;
                    541:                FILETIME ft;
                    542: 
                    543:                // Volume creation time
                    544:                if (volumeCreationTime == 0)
                    545:                {
                    546:                        GetLocalTime (&st);
                    547:                        SystemTimeToFileTime (&st, &ft);
                    548:                }
                    549:                else
                    550:                {
                    551:                        ft.dwHighDateTime = (DWORD)(volumeCreationTime >> 32);
                    552:                        ft.dwLowDateTime = (DWORD)volumeCreationTime;
                    553:                }
                    554:                mputLong (p, ft.dwHighDateTime);
                    555:                mputLong (p, ft.dwLowDateTime);
                    556: 
1.1.1.6   root      557:                // Header modification time/date
1.1       root      558:                GetLocalTime (&st);
                    559:                SystemTimeToFileTime (&st, &ft);
                    560:                mputLong (p, ft.dwHighDateTime);
                    561:                mputLong (p, ft.dwLowDateTime);
1.1.1.8   root      562: 
                    563: #else
                    564:                struct timeval tv;
                    565:                unsigned __int64 ct, wt;
                    566:                gettimeofday (&tv, NULL);
                    567: 
                    568:                // Unix time => Windows file time
                    569:                wt = ((unsigned __int64)tv.tv_sec + 134774LL * 24 * 3600) * 1000LL * 1000 * 10;
                    570: 
                    571:                if (volumeCreationTime == 0)
                    572:                        ct = wt;
                    573:                else
                    574:                        ct = volumeCreationTime;
                    575: 
                    576:                mputInt64 (p, ct);
                    577:                mputInt64 (p, wt);
                    578: #endif
                    579: 
1.1       root      580:        }
                    581: 
1.1.1.12! root      582:        // Size of hidden volume (if any)
1.1.1.4   root      583:        cryptoInfo->hiddenVolumeSize = hiddenVolumeSize;
                    584:        mputInt64 (p, cryptoInfo->hiddenVolumeSize);
1.1.1.12! root      585: 
1.1.1.7   root      586:        cryptoInfo->hiddenVolume = cryptoInfo->hiddenVolumeSize != 0;
1.1.1.4   root      587: 
1.1.1.12! root      588:        // Volume size
        !           589:        cryptoInfo->VolumeSize.Value = volumeSize;
        !           590:        mputInt64 (p, volumeSize);
        !           591: 
        !           592:        // Encrypted area start
        !           593:        cryptoInfo->EncryptedAreaStart.Value = encryptedAreaStart;
        !           594:        mputInt64 (p, encryptedAreaStart);
        !           595: 
        !           596:        // Encrypted area size
        !           597:        cryptoInfo->EncryptedAreaLength.Value = encryptedAreaLength;
        !           598:        mputInt64 (p, encryptedAreaLength);
        !           599: 
        !           600:        // The master key data
        !           601:        memcpy (header + HEADER_MASTER_KEYDATA_OFFSET, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
1.1       root      602: 
                    603: 
1.1.1.6   root      604:        /* Header encryption */
1.1       root      605: 
1.1.1.12! root      606:        switch (mode)
        !           607:        {
        !           608:        case LRW:
        !           609:        case CBC:
        !           610:        case INNER_CBC:
        !           611:        case OUTER_CBC:
        !           612: 
        !           613:                // For LRW (deprecated/legacy), the tweak key
        !           614:                // For CBC (deprecated/legacy), the IV/whitening seed
        !           615:                memcpy (cryptoInfo->k2, dk, LEGACY_VOL_IV_SIZE);
        !           616:                primaryKeyOffset = LEGACY_VOL_IV_SIZE;
        !           617:                break;
        !           618: 
        !           619:        default:
        !           620:                // The secondary key (if cascade, multiple concatenated)
        !           621:                memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
        !           622:                primaryKeyOffset = 0;
        !           623:        }
        !           624: 
        !           625:        retVal = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
        !           626:        if (retVal != ERR_SUCCESS)
1.1.1.6   root      627:                return retVal;
1.1       root      628: 
1.1.1.7   root      629:        // Mode of operation
                    630:        if (!EAInitMode (cryptoInfo))
                    631:                return ERR_OUTOFMEMORY;
                    632: 
1.1.1.12! root      633: 
        !           634:        // Encrypt the entire header (except the salt)
        !           635:        EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET,
        !           636:                HEADER_ENCRYPTED_DATA_SIZE,
1.1.1.7   root      637:                cryptoInfo);
1.1       root      638: 
                    639: 
1.1.1.6   root      640:        /* cryptoInfo setup for further use (disk format) */
1.1       root      641: 
1.1.1.12! root      642:        // Init with the master key(s) 
        !           643:        retVal = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
        !           644:        if (retVal != ERR_SUCCESS)
1.1.1.6   root      645:                return retVal;
1.1       root      646: 
1.1.1.12! root      647:        memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
        !           648: 
        !           649:        switch (cryptoInfo->mode)
        !           650:        {
        !           651:        case LRW:
        !           652:        case CBC:
        !           653:        case INNER_CBC:
        !           654:        case OUTER_CBC:
        !           655: 
        !           656:                // For LRW (deprecated/legacy), the tweak key
        !           657:                // For CBC (deprecated/legacy), the IV/whitening seed
        !           658:                memcpy (cryptoInfo->k2, keyInfo.master_keydata, LEGACY_VOL_IV_SIZE);
        !           659:                break;
        !           660: 
        !           661:        default:
        !           662:                // The secondary master key (if cascade, multiple concatenated)
        !           663:                memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
        !           664:        }
1.1       root      665: 
1.1.1.7   root      666:        // Mode of operation
                    667:        if (!EAInitMode (cryptoInfo))
                    668:                return ERR_OUTOFMEMORY;
                    669: 
1.1.1.2   root      670: 
1.1       root      671: #ifdef VOLFORMAT
1.1.1.3   root      672:        if (showKeys)
1.1       root      673:        {
                    674:                BOOL dots3 = FALSE;
                    675:                int i, j;
                    676: 
1.1.1.4   root      677:                j = EAGetKeySize (ea);
1.1       root      678: 
1.1.1.6   root      679:                if (j > NBR_KEY_BYTES_TO_DISPLAY)
1.1       root      680:                {
                    681:                        dots3 = TRUE;
1.1.1.6   root      682:                        j = NBR_KEY_BYTES_TO_DISPLAY;
1.1       root      683:                }
                    684: 
1.1.1.12! root      685:                MasterKeyGUIView[0] = 0;
1.1       root      686:                for (i = 0; i < j; i++)
                    687:                {
1.1.1.12! root      688:                        char tmp2[8] = {0};
        !           689:                        sprintf (tmp2, "%02X", (int) (unsigned char) keyInfo.master_keydata[i + primaryKeyOffset]);
        !           690:                        strcat (MasterKeyGUIView, tmp2);
1.1       root      691:                }
                    692: 
1.1.1.6   root      693:                if (dots3)
1.1       root      694:                {
1.1.1.12! root      695:                        strcat (MasterKeyGUIView, "...");
1.1       root      696:                }
                    697: 
1.1.1.12! root      698:                SendMessage (hMasterKey, WM_SETTEXT, 0, (LPARAM) MasterKeyGUIView);
1.1       root      699: 
1.1.1.12! root      700:                HeaderKeyGUIView[0] = 0;
1.1.1.6   root      701:                for (i = 0; i < NBR_KEY_BYTES_TO_DISPLAY; i++)
1.1       root      702:                {
                    703:                        char tmp2[8];
1.1.1.12! root      704:                        sprintf (tmp2, "%02X", (int) (unsigned char) dk[primaryKeyOffset + i]);
        !           705:                        strcat (HeaderKeyGUIView, tmp2);
1.1       root      706:                }
                    707: 
1.1.1.6   root      708:                if (dots3)
1.1.1.3   root      709:                {
1.1.1.12! root      710:                        strcat (HeaderKeyGUIView, "...");
1.1.1.3   root      711:                }
                    712: 
1.1.1.12! root      713:                SendMessage (hHeaderKey, WM_SETTEXT, 0, (LPARAM) HeaderKeyGUIView);
1.1       root      714:        }
1.1.1.12! root      715: #endif // #ifdef VOLFORMAT
1.1       root      716: 
1.1.1.3   root      717:        burn (dk, sizeof(dk));
1.1       root      718:        burn (&keyInfo, sizeof (keyInfo));
                    719: 
                    720:        *retInfo = cryptoInfo;
                    721:        return 0;
                    722: }
                    723: 
1.1.1.12! root      724: #endif // !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT)

unix.superglobalmegacorp.com

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