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

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
1.1.1.19  root        6:  the original source code (contained in this file) and all other portions
1.1.1.20  root        7:  of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
                      8:  and are governed by the TrueCrypt License 3.0 the full text of which is
1.1.1.19  root        9:  contained in the file License.txt included in TrueCrypt binary and source
                     10:  code distribution 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>
                     16: #include <sys/types.h>
                     17: #include <sys/stat.h>
                     18: #include <time.h>
1.1.1.14  root       19: #include "EncryptionThreadPool.h"
1.1.1.12  root       20: #endif
1.1       root       21: 
1.1.1.15  root       22: #include <stddef.h>
1.1.1.18  root       23: #include <string.h>
1.1.1.6   root       24: #include <io.h>
1.1.1.18  root       25: 
                     26: #ifndef DEVICE_DRIVER
1.1.1.6   root       27: #include "Random.h"
1.1.1.18  root       28: #endif
1.1.1.6   root       29: 
1.1.1.14  root       30: #include "Crc.h"
1.1.1.6   root       31: #include "Crypto.h"
1.1.1.15  root       32: #include "Endian.h"
1.1.1.6   root       33: #include "Volumes.h"
                     34: #include "Pkcs5.h"
1.1       root       35: 
                     36: 
1.1.1.20  root       37: /* Volume header v5 structure (used since TrueCrypt 7.0): */
                     38: //
                     39: // Offset      Length  Description
                     40: // ------------------------------------------
                     41: // Unencrypted:
                     42: // 0           64              Salt
                     43: // Encrypted:
                     44: // 64          4               ASCII string 'TRUE'
                     45: // 68          2               Header version
                     46: // 70          2               Required program version
                     47: // 72          4               CRC-32 checksum of the (decrypted) bytes 256-511
1.1.1.22! root       48: // 76          16              Reserved (must contain zeroes)
1.1.1.20  root       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, valid if field 70 >= 0x600 or flag bit 0 == 1)
                     51: // 108         8               Byte offset of the start of the master key scope (valid if field 70 >= 0x600 or flag bit 0 == 1)
                     52: // 116         8               Size of the encrypted area within the master key scope (valid if field 70 >= 0x600 or flag bit 0 == 1)
                     53: // 124         4               Flags: bit 0 set = system encryption; bit 1 set = non-system in-place encryption, bits 2-31 are reserved (set to zero)
                     54: // 128         4               Sector size in bytes
1.1.1.22! root       55: // 132         120             Reserved (must contain zeroes)
1.1.1.20  root       56: // 252         4               CRC-32 checksum of the (decrypted) bytes 64-251
                     57: // 256         256             Concatenated primary master key(s) and secondary master key(s) (XTS mode)
                     58: 
                     59: 
                     60: /* Deprecated/legacy volume header v4 structure (used by TrueCrypt 6.x): */
1.1.1.14  root       61: //
                     62: // Offset      Length  Description
                     63: // ------------------------------------------
                     64: // Unencrypted:
                     65: // 0           64              Salt
                     66: // Encrypted:
                     67: // 64          4               ASCII string 'TRUE'
                     68: // 68          2               Header version
                     69: // 70          2               Required program version
                     70: // 72          4               CRC-32 checksum of the (decrypted) bytes 256-511
1.1.1.22! root       71: // 76          16              Reserved (must contain zeroes)
1.1.1.14  root       72: // 92          8               Size of hidden volume in bytes (0 = normal volume)
1.1.1.16  root       73: // 100         8               Size of the volume in bytes (identical with field 92 for hidden volumes, valid if field 70 >= 0x600 or flag bit 0 == 1)
                     74: // 108         8               Byte offset of the start of the master key scope (valid if field 70 >= 0x600 or flag bit 0 == 1)
                     75: // 116         8               Size of the encrypted area within the master key scope (valid if field 70 >= 0x600 or flag bit 0 == 1)
1.1.1.15  root       76: // 124         4               Flags: bit 0 set = system encryption; bit 1 set = non-system in-place encryption, bits 2-31 are reserved
1.1.1.22! root       77: // 128         124             Reserved (must contain zeroes)
1.1.1.14  root       78: // 252         4               CRC-32 checksum of the (decrypted) bytes 64-251
                     79: // 256         256             Concatenated primary master key(s) and secondary master key(s) (XTS mode)
1.1.1.12  root       80: 
1.1.1.14  root       81: 
1.1.1.15  root       82: /* Deprecated/legacy volume header v3 structure (used by TrueCrypt 5.x): */
1.1.1.12  root       83: //
                     84: // Offset      Length  Description
                     85: // ------------------------------------------
                     86: // Unencrypted:
                     87: // 0           64              Salt
                     88: // Encrypted:
                     89: // 64          4               ASCII string 'TRUE'
                     90: // 68          2               Header version
                     91: // 70          2               Required program version
                     92: // 72          4               CRC-32 checksum of the (decrypted) bytes 256-511
                     93: // 76          8               Volume creation time
                     94: // 84          8               Header creation time
                     95: // 92          8               Size of hidden volume in bytes (0 = normal volume)
                     96: // 100         8               Size of the volume in bytes (identical with field 92 for hidden volumes)
                     97: // 108         8               Start byte offset of the encrypted area of the volume
                     98: // 116         8               Size of the encrypted area of the volume in bytes
1.1.1.22! root       99: // 124         132             Reserved (must contain zeroes)
1.1.1.12  root      100: // 256         256             Concatenated primary master key(s) and secondary master key(s) (XTS mode)
1.1       root      101: 
                    102: 
1.1.1.12  root      103: /* Deprecated/legacy volume header v2 structure (used before TrueCrypt 5.0): */
1.1       root      104: //
                    105: // Offset      Length  Description
                    106: // ------------------------------------------
                    107: // Unencrypted:
1.1.1.6   root      108: // 0           64              Salt
1.1       root      109: // Encrypted:
1.1.1.4   root      110: // 64          4               ASCII string 'TRUE'
1.1       root      111: // 68          2               Header version
                    112: // 70          2               Required program version
1.1.1.7   root      113: // 72          4               CRC-32 checksum of the (decrypted) bytes 256-511
1.1       root      114: // 76          8               Volume creation time
                    115: // 84          8               Header creation time
1.1.1.4   root      116: // 92          8               Size of hidden volume in bytes (0 = normal volume)
1.1.1.22! root      117: // 100         156             Reserved (must contain zeroes)
1.1.1.12  root      118: // 256         32              For LRW (deprecated/legacy), secondary key
                    119: //                                     For CBC (deprecated/legacy), data used to generate IV and whitening values
1.1.1.7   root      120: // 288         224             Master key(s)
1.1       root      121: 
1.1.1.12  root      122: 
                    123: 
1.1.1.15  root      124: uint16 GetHeaderField16 (byte *header, int offset)
1.1.1.12  root      125: {
                    126:        return BE16 (*(uint16 *) (header + offset));
                    127: }
                    128: 
                    129: 
1.1.1.15  root      130: uint32 GetHeaderField32 (byte *header, int offset)
1.1.1.12  root      131: {
                    132:        return BE32 (*(uint32 *) (header + offset));
                    133: }
                    134: 
                    135: 
1.1.1.15  root      136: UINT64_STRUCT GetHeaderField64 (byte *header, int offset)
1.1.1.12  root      137: {
                    138:        UINT64_STRUCT uint64Struct;
                    139: 
                    140: #ifndef TC_NO_COMPILER_INT64
                    141:        uint64Struct.Value = BE64 (*(uint64 *) (header + offset));
                    142: #else
                    143:        uint64Struct.HighPart = BE32 (*(uint32 *) (header + offset));
                    144:        uint64Struct.LowPart = BE32 (*(uint32 *) (header + offset + 4));
                    145: #endif
                    146:        return uint64Struct;
                    147: }
                    148: 
                    149: 
1.1.1.13  root      150: #ifndef TC_WINDOWS_BOOT
                    151: 
1.1.1.14  root      152: typedef struct
                    153: {
                    154:        char DerivedKey[MASTER_KEYDATA_SIZE];
                    155:        BOOL Free;
                    156:        LONG KeyReady;
                    157:        int Pkcs5Prf;
                    158: } KeyDerivationWorkItem;
                    159: 
                    160: 
1.1.1.15  root      161: BOOL ReadVolumeHeaderRecoveryMode = FALSE;
                    162: 
                    163: int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
1.1       root      164: {
1.1.1.14  root      165:        char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
1.1       root      166:        KEY_INFO keyInfo;
                    167:        PCRYPTO_INFO cryptoInfo;
1.1.1.12  root      168:        char dk[MASTER_KEYDATA_SIZE];
1.1.1.14  root      169:        int enqPkcs5Prf, pkcs5_prf;
1.1.1.16  root      170:        uint16 headerVersion;
1.1.1.15  root      171:        int status = ERR_PARAMETER_INCORRECT;
1.1.1.12  root      172:        int primaryKeyOffset;
1.1.1.6   root      173: 
1.1.1.14  root      174:        TC_EVENT keyDerivationCompletedEvent;
                    175:        TC_EVENT noOutstandingWorkItemEvent;
                    176:        KeyDerivationWorkItem *keyDerivationWorkItems;
                    177:        KeyDerivationWorkItem *item;
                    178:        int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1;
1.1.1.18  root      179:        size_t encryptionThreadCount = GetEncryptionThreadCount();
                    180:        size_t queuedWorkItems = 0;
1.1.1.14  root      181:        LONG outstandingWorkItemCount = 0;
                    182:        int i;
1.1.1.7   root      183: 
1.1.1.12  root      184:        if (retHeaderCryptoInfo != NULL)
                    185:        {
                    186:                cryptoInfo = retHeaderCryptoInfo;
                    187:        }
                    188:        else
                    189:        {
                    190:                cryptoInfo = *retInfo = crypto_open ();
                    191:                if (cryptoInfo == NULL)
                    192:                        return ERR_OUTOFMEMORY;
                    193:        }
1.1       root      194: 
1.1.1.14  root      195:        if (encryptionThreadCount > 1)
                    196:        {
                    197:                keyDerivationWorkItems = TCalloc (sizeof (KeyDerivationWorkItem) * pkcs5PrfCount);
                    198:                if (!keyDerivationWorkItems)
                    199:                        return ERR_OUTOFMEMORY;
                    200: 
                    201:                for (i = 0; i < pkcs5PrfCount; ++i)
                    202:                        keyDerivationWorkItems[i].Free = TRUE;
                    203: 
                    204: #ifdef DEVICE_DRIVER
                    205:                KeInitializeEvent (&keyDerivationCompletedEvent, SynchronizationEvent, FALSE);
                    206:                KeInitializeEvent (&noOutstandingWorkItemEvent, SynchronizationEvent, TRUE);
                    207: #else
                    208:                keyDerivationCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
                    209:                if (!keyDerivationCompletedEvent)
                    210:                {
                    211:                        TCfree (keyDerivationWorkItems);
                    212:                        return ERR_OUTOFMEMORY;
                    213:                }
                    214: 
                    215:                noOutstandingWorkItemEvent = CreateEvent (NULL, FALSE, TRUE, NULL);
                    216:                if (!noOutstandingWorkItemEvent)
                    217:                {
                    218:                        CloseHandle (keyDerivationCompletedEvent);
                    219:                        TCfree (keyDerivationWorkItems);
                    220:                        return ERR_OUTOFMEMORY;
                    221:                }
                    222: #endif
                    223:        }
                    224:                
                    225: #ifndef DEVICE_DRIVER
                    226:        VirtualLock (&keyInfo, sizeof (keyInfo));
                    227:        VirtualLock (&dk, sizeof (dk));
                    228: #endif
                    229: 
1.1.1.12  root      230:        crypto_loadkey (&keyInfo, password->Text, (int) password->Length);
1.1       root      231: 
1.1.1.12  root      232:        // PKCS5 is used to derive the primary header key(s) and secondary header key(s) (XTS mode) from the password
                    233:        memcpy (keyInfo.salt, encryptedHeader + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE);
1.1       root      234: 
1.1.1.3   root      235:        // Test all available PKCS5 PRFs
1.1.1.14  root      236:        for (enqPkcs5Prf = FIRST_PRF_ID; enqPkcs5Prf <= LAST_PRF_ID || queuedWorkItems > 0; ++enqPkcs5Prf)
1.1       root      237:        {
1.1.1.12  root      238:                BOOL lrw64InitDone = FALSE;             // Deprecated/legacy
                    239:                BOOL lrw128InitDone = FALSE;    // Deprecated/legacy
1.1.1.7   root      240: 
1.1.1.14  root      241:                if (encryptionThreadCount > 1)
                    242:                {
                    243:                        // Enqueue key derivation on thread pool
                    244:                        if (queuedWorkItems < encryptionThreadCount && enqPkcs5Prf <= LAST_PRF_ID)
                    245:                        {
                    246:                                for (i = 0; i < pkcs5PrfCount; ++i)
                    247:                                {
                    248:                                        item = &keyDerivationWorkItems[i];
                    249:                                        if (item->Free)
                    250:                                        {
                    251:                                                item->Free = FALSE;
                    252:                                                item->KeyReady = FALSE;
                    253:                                                item->Pkcs5Prf = enqPkcs5Prf;
                    254: 
                    255:                                                EncryptionThreadPoolBeginKeyDerivation (&keyDerivationCompletedEvent, &noOutstandingWorkItemEvent,
                    256:                                                        &item->KeyReady, &outstandingWorkItemCount, enqPkcs5Prf, keyInfo.userKey,
                    257:                                                        keyInfo.keyLength, keyInfo.salt, get_pkcs5_iteration_count (enqPkcs5Prf, bBoot), item->DerivedKey);
                    258:                                                
                    259:                                                ++queuedWorkItems;
                    260:                                                break;
                    261:                                        }
                    262:                                }
                    263: 
                    264:                                if (enqPkcs5Prf < LAST_PRF_ID)
                    265:                                        continue;
                    266:                        }
                    267:                        else
                    268:                                --enqPkcs5Prf;
                    269: 
                    270:                        // Wait for completion of a key derivation
                    271:                        while (queuedWorkItems > 0)
                    272:                        {
                    273:                                for (i = 0; i < pkcs5PrfCount; ++i)
                    274:                                {
                    275:                                        item = &keyDerivationWorkItems[i];
                    276:                                        if (!item->Free && InterlockedExchangeAdd (&item->KeyReady, 0) == TRUE)
                    277:                                        {
                    278:                                                pkcs5_prf = item->Pkcs5Prf;
                    279:                                                keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, bBoot);
                    280:                                                memcpy (dk, item->DerivedKey, sizeof (dk));
                    281: 
                    282:                                                item->Free = TRUE;
                    283:                                                --queuedWorkItems;
                    284:                                                goto KeyReady;
                    285:                                        }
                    286:                                }
1.1.1.6   root      287: 
1.1.1.14  root      288:                                if (queuedWorkItems > 0)
                    289:                                        TC_WAIT_EVENT (keyDerivationCompletedEvent);
                    290:                        }
                    291:                        continue;
                    292: KeyReady:      ;
                    293:                }
                    294:                else
1.1.1.3   root      295:                {
1.1.1.14  root      296:                        pkcs5_prf = enqPkcs5Prf;
                    297:                        keyInfo.noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, bBoot);
                    298: 
                    299:                        switch (pkcs5_prf)
                    300:                        {
                    301:                        case RIPEMD160:
                    302:                                derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
                    303:                                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
                    304:                                break;
                    305: 
                    306:                        case SHA512:
                    307:                                derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
                    308:                                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
                    309:                                break;
                    310: 
                    311:                        case SHA1:
                    312:                                // Deprecated/legacy
                    313:                                derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
                    314:                                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
                    315:                                break;
                    316: 
                    317:                        case WHIRLPOOL:
                    318:                                derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
                    319:                                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
                    320:                                break;
                    321: 
                    322:                        default:                
                    323:                                // Unknown/wrong ID
                    324:                                TC_THROW_FATAL_EXCEPTION;
                    325:                        } 
                    326:                }
1.1       root      327: 
1.1.1.12  root      328:                // Test all available modes of operation
                    329:                for (cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
                    330:                        cryptoInfo->mode <= LAST_MODE_OF_OPERATION;
                    331:                        cryptoInfo->mode++)
1.1.1.3   root      332:                {
1.1.1.12  root      333:                        switch (cryptoInfo->mode)
                    334:                        {
                    335:                        case LRW:
                    336:                        case CBC:
                    337:                        case INNER_CBC:
                    338:                        case OUTER_CBC:
                    339: 
                    340:                                // For LRW (deprecated/legacy), copy the tweak key 
                    341:                                // For CBC (deprecated/legacy), copy the IV/whitening seed 
                    342:                                memcpy (cryptoInfo->k2, dk, LEGACY_VOL_IV_SIZE);
                    343:                                primaryKeyOffset = LEGACY_VOL_IV_SIZE;
                    344:                                break;
1.1.1.13  root      345: 
1.1.1.12  root      346:                        default:
                    347:                                primaryKeyOffset = 0;
                    348:                        }
1.1.1.6   root      349: 
1.1.1.12  root      350:                        // Test all available encryption algorithms
                    351:                        for (cryptoInfo->ea = EAGetFirst ();
                    352:                                cryptoInfo->ea != 0;
                    353:                                cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
1.1.1.6   root      354:                        {
1.1.1.12  root      355:                                int blockSize;
                    356: 
                    357:                                if (!EAIsModeSupported (cryptoInfo->ea, cryptoInfo->mode))
                    358:                                        continue;       // This encryption algorithm has never been available with this mode of operation
1.1.1.7   root      359: 
1.1.1.12  root      360:                                blockSize = CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea));
                    361: 
                    362:                                status = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
                    363:                                if (status == ERR_CIPHER_INIT_FAILURE)
                    364:                                        goto err;
                    365: 
                    366:                                // Init objects related to the mode of operation
                    367: 
                    368:                                if (cryptoInfo->mode == XTS)
                    369:                                {
                    370:                                        // Copy the secondary key (if cascade, multiple concatenated)
                    371:                                        memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
                    372: 
                    373:                                        // Secondary key schedule
                    374:                                        if (!EAInitMode (cryptoInfo))
                    375:                                        {
                    376:                                                status = ERR_MODE_INIT_FAILED;
                    377:                                                goto err;
                    378:                                        }
                    379:                                }
                    380:                                else if (cryptoInfo->mode == LRW
1.1.1.7   root      381:                                        && (blockSize == 8 && !lrw64InitDone || blockSize == 16 && !lrw128InitDone))
                    382:                                {
1.1.1.12  root      383:                                        // Deprecated/legacy
                    384: 
1.1.1.7   root      385:                                        if (!EAInitMode (cryptoInfo))
                    386:                                        {
                    387:                                                status = ERR_MODE_INIT_FAILED;
                    388:                                                goto err;
                    389:                                        }
                    390: 
1.1.1.12  root      391:                                        if (blockSize == 8)
1.1.1.7   root      392:                                                lrw64InitDone = TRUE;
                    393:                                        else if (blockSize == 16)
                    394:                                                lrw128InitDone = TRUE;
                    395:                                }
                    396: 
1.1.1.12  root      397:                                // Copy the header for decryption
1.1.1.14  root      398:                                memcpy (header, encryptedHeader, sizeof (header));
1.1.1.7   root      399: 
                    400:                                // Try to decrypt header 
                    401: 
1.1.1.12  root      402:                                DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
1.1.1.7   root      403: 
                    404:                                // Magic 'TRUE'
1.1.1.12  root      405:                                if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x54525545)
1.1.1.7   root      406:                                        continue;
                    407: 
                    408:                                // Header version
1.1.1.12  root      409:                                headerVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION);
1.1.1.14  root      410:                                
1.1.1.16  root      411:                                if (headerVersion > VOLUME_HEADER_VERSION)
                    412:                                {
                    413:                                        status = ERR_NEW_VERSION_REQUIRED;
                    414:                                        goto err;
                    415:                                }
                    416: 
1.1.1.14  root      417:                                // Check CRC of the header fields
1.1.1.15  root      418:                                if (!ReadVolumeHeaderRecoveryMode
                    419:                                        && headerVersion >= 4
                    420:                                        && GetHeaderField32 (header, TC_HEADER_OFFSET_HEADER_CRC) != GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
1.1.1.14  root      421:                                        continue;
1.1.1.7   root      422: 
                    423:                                // Required program version
1.1.1.14  root      424:                                cryptoInfo->RequiredProgramVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_REQUIRED_VERSION);
                    425:                                cryptoInfo->LegacyVolume = cryptoInfo->RequiredProgramVersion < 0x600;
1.1.1.7   root      426: 
                    427:                                // Check CRC of the key set
1.1.1.15  root      428:                                if (!ReadVolumeHeaderRecoveryMode
                    429:                                        && GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
1.1.1.7   root      430:                                        continue;
                    431: 
                    432:                                // Now we have the correct password, cipher, hash algorithm, and volume type
                    433: 
                    434:                                // Check the version required to handle this volume
1.1.1.14  root      435:                                if (cryptoInfo->RequiredProgramVersion > VERSION_NUM)
1.1.1.7   root      436:                                {
                    437:                                        status = ERR_NEW_VERSION_REQUIRED;
                    438:                                        goto err;
                    439:                                }
                    440: 
1.1.1.16  root      441:                                // Header version
                    442:                                cryptoInfo->HeaderVersion = headerVersion;
                    443: 
1.1.1.14  root      444:                                // Volume creation time (legacy)
1.1.1.12  root      445:                                cryptoInfo->volume_creation_time = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_CREATION_TIME).Value;
1.1.1.7   root      446: 
1.1.1.14  root      447:                                // Header creation time (legacy)
1.1.1.12  root      448:                                cryptoInfo->header_creation_time = GetHeaderField64 (header, TC_HEADER_OFFSET_MODIFICATION_TIME).Value;
1.1.1.7   root      449: 
                    450:                                // Hidden volume size (if any)
1.1.1.12  root      451:                                cryptoInfo->hiddenVolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE).Value;
1.1.1.13  root      452: 
1.1.1.14  root      453:                                // Hidden volume status
                    454:                                cryptoInfo->hiddenVolume = (cryptoInfo->hiddenVolumeSize != 0);
                    455: 
1.1.1.12  root      456:                                // Volume size
                    457:                                cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);
                    458:                                
                    459:                                // Encrypted area size and length
                    460:                                cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
                    461:                                cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);
                    462: 
1.1.1.14  root      463:                                // Flags
                    464:                                cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);
                    465: 
1.1.1.20  root      466:                                // Sector size
                    467:                                if (headerVersion >= 5)
                    468:                                        cryptoInfo->SectorSize = GetHeaderField32 (header, TC_HEADER_OFFSET_SECTOR_SIZE);
                    469:                                else
                    470:                                        cryptoInfo->SectorSize = TC_SECTOR_SIZE_LEGACY;
                    471: 
                    472:                                if (cryptoInfo->SectorSize < TC_MIN_VOLUME_SECTOR_SIZE
                    473:                                        || cryptoInfo->SectorSize > TC_MAX_VOLUME_SECTOR_SIZE
                    474:                                        || cryptoInfo->SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
                    475:                                {
                    476:                                        status = ERR_PARAMETER_INCORRECT;
                    477:                                        goto err;
                    478:                                }
                    479: 
1.1.1.12  root      480:                                // Preserve scheduled header keys if requested                  
                    481:                                if (retHeaderCryptoInfo)
                    482:                                {
                    483:                                        if (retInfo == NULL)
                    484:                                        {
                    485:                                                cryptoInfo->pkcs5 = pkcs5_prf;
                    486:                                                cryptoInfo->noIterations = keyInfo.noIterations;
                    487:                                                goto ret;
                    488:                                        }
                    489: 
                    490:                                        cryptoInfo = *retInfo = crypto_open ();
                    491:                                        if (cryptoInfo == NULL)
                    492:                                        {
                    493:                                                status = ERR_OUTOFMEMORY;
                    494:                                                goto err;
                    495:                                        }
1.1.1.7   root      496: 
1.1.1.12  root      497:                                        memcpy (cryptoInfo, retHeaderCryptoInfo, sizeof (*cryptoInfo));
                    498:                                }
                    499: 
                    500:                                // Master key data
                    501:                                memcpy (keyInfo.master_keydata, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE);
                    502:                                memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
                    503: 
                    504:                                // PKCS #5
                    505:                                memcpy (cryptoInfo->salt, keyInfo.salt, PKCS5_SALT_SIZE);
                    506:                                cryptoInfo->pkcs5 = pkcs5_prf;
1.1.1.7   root      507:                                cryptoInfo->noIterations = keyInfo.noIterations;
                    508: 
1.1.1.15  root      509:                                // Init the cipher with the decrypted master key
1.1.1.12  root      510:                                status = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
1.1.1.7   root      511:                                if (status == ERR_CIPHER_INIT_FAILURE)
                    512:                                        goto err;
                    513: 
1.1.1.12  root      514:                                switch (cryptoInfo->mode)
                    515:                                {
                    516:                                case LRW:
                    517:                                case CBC:
                    518:                                case INNER_CBC:
                    519:                                case OUTER_CBC:
                    520: 
                    521:                                        // For LRW (deprecated/legacy), the tweak key
                    522:                                        // For CBC (deprecated/legacy), the IV/whitening seed
                    523:                                        memcpy (cryptoInfo->k2, keyInfo.master_keydata, LEGACY_VOL_IV_SIZE);
                    524:                                        break;
1.1.1.13  root      525: 
1.1.1.12  root      526:                                default:
                    527:                                        // The secondary master key (if cascade, multiple concatenated)
                    528:                                        memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
                    529: 
                    530:                                }
1.1.1.7   root      531: 
                    532:                                if (!EAInitMode (cryptoInfo))
                    533:                                {
                    534:                                        status = ERR_MODE_INIT_FAILED;
                    535:                                        goto err;
                    536:                                }
1.1.1.6   root      537: 
1.1.1.15  root      538:                                status = ERR_SUCCESS;
1.1.1.14  root      539:                                goto ret;
1.1.1.7   root      540:                        }
1.1.1.2   root      541:                }
1.1       root      542:        }
1.1.1.6   root      543:        status = ERR_PASSWORD_WRONG;
1.1       root      544: 
1.1.1.6   root      545: err:
1.1.1.12  root      546:        if (cryptoInfo != retHeaderCryptoInfo)
                    547:        {
                    548:                crypto_close(cryptoInfo);
                    549:                *retInfo = NULL; 
                    550:        }
                    551: 
1.1.1.14  root      552: ret:
1.1       root      553:        burn (&keyInfo, sizeof (keyInfo));
1.1.1.12  root      554:        burn (dk, sizeof(dk));
1.1.1.14  root      555: 
                    556: #ifndef DEVICE_DRIVER
                    557:        VirtualUnlock (&keyInfo, sizeof (keyInfo));
                    558:        VirtualUnlock (&dk, sizeof (dk));
                    559: #endif
                    560: 
                    561:        if (encryptionThreadCount > 1)
                    562:        {
                    563:                TC_WAIT_EVENT (noOutstandingWorkItemEvent);
                    564: 
                    565:                burn (keyDerivationWorkItems, sizeof (KeyDerivationWorkItem) * pkcs5PrfCount);
                    566:                TCfree (keyDerivationWorkItems);
                    567: 
                    568: #ifndef DEVICE_DRIVER
                    569:                CloseHandle (keyDerivationCompletedEvent);
                    570:                CloseHandle (noOutstandingWorkItemEvent);
                    571: #endif
                    572:        }
                    573: 
1.1.1.6   root      574:        return status;
1.1       root      575: }
                    576: 
1.1.1.13  root      577: #else // TC_WINDOWS_BOOT
                    578: 
1.1.1.15  root      579: int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
1.1.1.13  root      580: {
                    581: #ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
                    582:        char dk[32 * 2];                        // 2 * 256-bit key
                    583:        char masterKey[32 * 2];
                    584: #else
                    585:        char dk[32 * 2 * 3];            // 6 * 256-bit key
                    586:        char masterKey[32 * 2 * 3];
                    587: #endif
                    588: 
                    589:        PCRYPTO_INFO cryptoInfo;
                    590:        int status;
                    591: 
                    592:        if (retHeaderCryptoInfo != NULL)
                    593:                cryptoInfo = retHeaderCryptoInfo;
                    594:        else
                    595:                cryptoInfo = *retInfo = crypto_open ();
                    596: 
                    597:        // PKCS5 PRF
                    598:        derive_key_ripemd160 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
1.1.1.14  root      599:                PKCS5_SALT_SIZE, bBoot ? 1000 : 2000, dk, sizeof (dk));
1.1.1.13  root      600: 
                    601:        // Mode of operation
                    602:        cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
                    603: 
                    604:        // Test all available encryption algorithms
                    605:        for (cryptoInfo->ea = EAGetFirst (); cryptoInfo->ea != 0; cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
                    606:        {
                    607:                status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks);
                    608:                if (status == ERR_CIPHER_INIT_FAILURE)
                    609:                        goto err;
                    610: 
                    611:                // Secondary key schedule
                    612:                EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
                    613: 
                    614:                // Try to decrypt header 
                    615:                DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
                    616:                
1.1.1.14  root      617:                // Check magic 'TRUE' and CRC-32 of header fields and master keydata
1.1.1.13  root      618:                if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x54525545
1.1.1.14  root      619:                        || (GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION) >= 4 && GetHeaderField32 (header, TC_HEADER_OFFSET_HEADER_CRC) != GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
1.1.1.13  root      620:                        || GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
                    621:                {
                    622:                        EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
                    623:                        continue;
                    624:                }
                    625: 
                    626:                // Header decrypted
                    627:                status = 0;
                    628: 
1.1.1.14  root      629:                // Hidden volume status
                    630:                cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE);
                    631:                cryptoInfo->hiddenVolume = (cryptoInfo->VolumeSize.LowPart != 0 || cryptoInfo->VolumeSize.HighPart != 0);
                    632: 
1.1.1.13  root      633:                // Volume size
                    634:                cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);
                    635: 
                    636:                // Encrypted area size and length
                    637:                cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
                    638:                cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);
                    639: 
1.1.1.14  root      640:                // Flags
                    641:                cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);
                    642: 
1.1.1.13  root      643:                memcpy (masterKey, header + HEADER_MASTER_KEYDATA_OFFSET, sizeof (masterKey));
                    644:                EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
                    645: 
                    646:                if (retHeaderCryptoInfo)
                    647:                        goto ret;
                    648: 
                    649:                // Init the encryption algorithm with the decrypted master key
                    650:                status = EAInit (cryptoInfo->ea, masterKey, cryptoInfo->ks);
                    651:                if (status == ERR_CIPHER_INIT_FAILURE)
                    652:                        goto err;
                    653: 
                    654:                // The secondary master key (if cascade, multiple concatenated)
                    655:                EAInit (cryptoInfo->ea, masterKey + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
                    656:                goto ret;
                    657:        }
                    658: 
                    659:        status = ERR_PASSWORD_WRONG;
                    660: 
                    661: err:
                    662:        if (cryptoInfo != retHeaderCryptoInfo)
                    663:        {
                    664:                crypto_close(cryptoInfo);
                    665:                *retInfo = NULL; 
                    666:        }
                    667: 
                    668: ret:
                    669:        burn (dk, sizeof(dk));
                    670:        burn (masterKey, sizeof(masterKey));
                    671:        return status;
                    672: }
                    673: 
                    674: #endif // TC_WINDOWS_BOOT
                    675: 
                    676: 
1.1.1.12  root      677: #if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT)
1.1       root      678: 
                    679: #ifdef VOLFORMAT
1.1.1.15  root      680: #      include "../Format/TcFormat.h"
                    681: #      include "Dlgcode.h"
1.1       root      682: #endif
                    683: 
1.1.1.12  root      684: // Creates a volume header in memory
1.1.1.15  root      685: int CreateVolumeHeaderInMemory (BOOL bBoot, char *header, int ea, int mode, Password *password,
1.1.1.14  root      686:                   int pkcs5_prf, char *masterKeydata, PCRYPTO_INFO *retInfo,
1.1.1.12  root      687:                   unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize,
1.1.1.20  root      688:                   unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode)
1.1       root      689: {
                    690:        unsigned char *p = (unsigned char *) header;
1.1.1.6   root      691:        static KEY_INFO keyInfo;
1.1       root      692: 
1.1.1.6   root      693:        int nUserKeyLen = password->Length;
1.1       root      694:        PCRYPTO_INFO cryptoInfo = crypto_open ();
1.1.1.12  root      695:        static char dk[MASTER_KEYDATA_SIZE];
1.1       root      696:        int x;
1.1.1.6   root      697:        int retVal = 0;
1.1.1.12  root      698:        int primaryKeyOffset;
1.1       root      699: 
                    700:        if (cryptoInfo == NULL)
                    701:                return ERR_OUTOFMEMORY;
                    702: 
1.1.1.14  root      703:        memset (header, 0, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
1.1.1.8   root      704: 
1.1.1.2   root      705:        VirtualLock (&keyInfo, sizeof (keyInfo));
1.1.1.6   root      706:        VirtualLock (&dk, sizeof (dk));
1.1       root      707: 
1.1.1.6   root      708:        /* Encryption setup */
1.1       root      709: 
1.1.1.12  root      710:        if (masterKeydata == NULL)
1.1.1.7   root      711:        {
1.1.1.12  root      712:                // 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      713: 
1.1.1.12  root      714:                int bytesNeeded;
                    715: 
                    716:                switch (mode)
                    717:                {
                    718:                case LRW:
                    719:                case CBC:
                    720:                case INNER_CBC:
                    721:                case OUTER_CBC:
                    722: 
                    723:                        // Deprecated/legacy modes of operation
                    724:                        bytesNeeded = LEGACY_VOL_IV_SIZE + EAGetKeySize (ea);
                    725: 
1.1.1.20  root      726:                        // In fact, this should never be the case since volumes being newly created are not
                    727:                        // supposed to use any deprecated mode of operation.
                    728:                        TC_THROW_FATAL_EXCEPTION;
                    729:                        break;
1.1.1.12  root      730: 
                    731:                default:
                    732:                        bytesNeeded = EAGetKeySize (ea) * 2;    // Size of primary + secondary key(s)
                    733:                }
                    734: 
                    735:                if (!RandgetBytes (keyInfo.master_keydata, bytesNeeded, TRUE))
1.1.1.8   root      736:                        return ERR_CIPHER_INIT_WEAK_KEY;
1.1.1.7   root      737:        }
1.1.1.2   root      738:        else
1.1.1.12  root      739:        {
                    740:                // We already have existing master key data (the header is being re-encrypted)
                    741:                memcpy (keyInfo.master_keydata, masterKeydata, MASTER_KEYDATA_SIZE);
                    742:        }
1.1.1.2   root      743: 
1.1.1.6   root      744:        // User key 
                    745:        memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
1.1       root      746:        keyInfo.keyLength = nUserKeyLen;
1.1.1.12  root      747:        keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, bBoot);
1.1       root      748: 
                    749:        // User selected encryption algorithm
1.1.1.4   root      750:        cryptoInfo->ea = ea;
1.1       root      751: 
1.1.1.7   root      752:        // Mode of operation
                    753:        cryptoInfo->mode = mode;
                    754: 
1.1.1.8   root      755:        // Salt for header key derivation
1.1.1.12  root      756:        if (!RandgetBytes (keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
1.1.1.8   root      757:                return ERR_CIPHER_INIT_WEAK_KEY; 
1.1       root      758: 
1.1.1.12  root      759:        // PBKDF2 (PKCS5) is used to derive primary header key(s) and secondary header key(s) (XTS) from the password/keyfiles
                    760:        switch (pkcs5_prf)
1.1       root      761:        {
1.1.1.12  root      762:        case SHA512:
                    763:                derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
                    764:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
                    765:                break;
                    766: 
1.1.1.6   root      767:        case SHA1:
1.1.1.12  root      768:                // Deprecated/legacy
                    769:                derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
                    770:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
1.1.1.6   root      771:                break;
                    772: 
                    773:        case RIPEMD160:
1.1.1.12  root      774:                derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
                    775:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
1.1.1.6   root      776:                break;
                    777: 
                    778:        case WHIRLPOOL:
1.1.1.12  root      779:                derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
                    780:                        PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
1.1.1.6   root      781:                break;
1.1.1.7   root      782: 
1.1.1.12  root      783:        default:                
                    784:                // Unknown/wrong ID
                    785:                TC_THROW_FATAL_EXCEPTION;
                    786:        } 
1.1       root      787: 
1.1.1.6   root      788:        /* Header setup */
1.1       root      789: 
                    790:        // Salt
1.1.1.12  root      791:        mputBytes (p, keyInfo.salt, PKCS5_SALT_SIZE);   
1.1       root      792: 
                    793:        // Magic
1.1.1.8   root      794:        mputLong (p, 0x54525545);
1.1       root      795: 
                    796:        // Header version
1.1.1.16  root      797:        mputWord (p, VOLUME_HEADER_VERSION);
                    798:        cryptoInfo->HeaderVersion = VOLUME_HEADER_VERSION;
1.1       root      799: 
                    800:        // Required program version to handle this volume
1.1.1.12  root      801:        switch (mode)
                    802:        {
                    803:        case LRW:
                    804:                // Deprecated/legacy
                    805:                mputWord (p, 0x0410);
                    806:                break;
                    807:        case OUTER_CBC:
                    808:        case INNER_CBC:
                    809:                // Deprecated/legacy
                    810:                mputWord (p, 0x0300);
                    811:                break;
                    812:        case CBC:
                    813:                // Deprecated/legacy
                    814:                mputWord (p, hiddenVolumeSize > 0 ? 0x0300 : 0x0100);
                    815:                break;
                    816:        default:
1.1.1.14  root      817:                mputWord (p, requiredProgramVersion != 0 ? requiredProgramVersion : TC_VOLUME_MIN_REQUIRED_PROGRAM_VERSION);
1.1.1.12  root      818:        }
1.1       root      819: 
1.1.1.12  root      820:        // CRC of the master key data
                    821:        x = GetCrc32(keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
1.1       root      822:        mputLong (p, x);
                    823: 
1.1.1.14  root      824:        // Reserved fields
                    825:        p += 2 * 8;
1.1       root      826: 
1.1.1.12  root      827:        // Size of hidden volume (if any)
1.1.1.4   root      828:        cryptoInfo->hiddenVolumeSize = hiddenVolumeSize;
                    829:        mputInt64 (p, cryptoInfo->hiddenVolumeSize);
1.1.1.12  root      830: 
1.1.1.7   root      831:        cryptoInfo->hiddenVolume = cryptoInfo->hiddenVolumeSize != 0;
1.1.1.4   root      832: 
1.1.1.12  root      833:        // Volume size
                    834:        cryptoInfo->VolumeSize.Value = volumeSize;
                    835:        mputInt64 (p, volumeSize);
                    836: 
                    837:        // Encrypted area start
                    838:        cryptoInfo->EncryptedAreaStart.Value = encryptedAreaStart;
                    839:        mputInt64 (p, encryptedAreaStart);
                    840: 
                    841:        // Encrypted area size
                    842:        cryptoInfo->EncryptedAreaLength.Value = encryptedAreaLength;
                    843:        mputInt64 (p, encryptedAreaLength);
                    844: 
1.1.1.14  root      845:        // Flags
                    846:        cryptoInfo->HeaderFlags = headerFlags;
                    847:        mputLong (p, headerFlags);
                    848: 
1.1.1.20  root      849:        // Sector size
                    850:        if (sectorSize < TC_MIN_VOLUME_SECTOR_SIZE
                    851:                || sectorSize > TC_MAX_VOLUME_SECTOR_SIZE
                    852:                || sectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
                    853:        {
                    854:                TC_THROW_FATAL_EXCEPTION;
                    855:        }
                    856: 
                    857:        cryptoInfo->SectorSize = sectorSize;
                    858:        mputLong (p, sectorSize);
                    859: 
1.1.1.14  root      860:        // CRC of the header fields
                    861:        x = GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
                    862:        p = header + TC_HEADER_OFFSET_HEADER_CRC;
                    863:        mputLong (p, x);
                    864: 
1.1.1.12  root      865:        // The master key data
                    866:        memcpy (header + HEADER_MASTER_KEYDATA_OFFSET, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
1.1       root      867: 
                    868: 
1.1.1.6   root      869:        /* Header encryption */
1.1       root      870: 
1.1.1.12  root      871:        switch (mode)
                    872:        {
                    873:        case LRW:
                    874:        case CBC:
                    875:        case INNER_CBC:
                    876:        case OUTER_CBC:
                    877: 
                    878:                // For LRW (deprecated/legacy), the tweak key
                    879:                // For CBC (deprecated/legacy), the IV/whitening seed
                    880:                memcpy (cryptoInfo->k2, dk, LEGACY_VOL_IV_SIZE);
                    881:                primaryKeyOffset = LEGACY_VOL_IV_SIZE;
                    882:                break;
                    883: 
                    884:        default:
                    885:                // The secondary key (if cascade, multiple concatenated)
                    886:                memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
                    887:                primaryKeyOffset = 0;
                    888:        }
                    889: 
                    890:        retVal = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
                    891:        if (retVal != ERR_SUCCESS)
1.1.1.6   root      892:                return retVal;
1.1       root      893: 
1.1.1.7   root      894:        // Mode of operation
                    895:        if (!EAInitMode (cryptoInfo))
                    896:                return ERR_OUTOFMEMORY;
                    897: 
1.1.1.12  root      898: 
                    899:        // Encrypt the entire header (except the salt)
                    900:        EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET,
                    901:                HEADER_ENCRYPTED_DATA_SIZE,
1.1.1.7   root      902:                cryptoInfo);
1.1       root      903: 
                    904: 
1.1.1.6   root      905:        /* cryptoInfo setup for further use (disk format) */
1.1       root      906: 
1.1.1.12  root      907:        // Init with the master key(s) 
                    908:        retVal = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
                    909:        if (retVal != ERR_SUCCESS)
1.1.1.6   root      910:                return retVal;
1.1       root      911: 
1.1.1.12  root      912:        memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
                    913: 
                    914:        switch (cryptoInfo->mode)
                    915:        {
                    916:        case LRW:
                    917:        case CBC:
                    918:        case INNER_CBC:
                    919:        case OUTER_CBC:
                    920: 
                    921:                // For LRW (deprecated/legacy), the tweak key
                    922:                // For CBC (deprecated/legacy), the IV/whitening seed
                    923:                memcpy (cryptoInfo->k2, keyInfo.master_keydata, LEGACY_VOL_IV_SIZE);
                    924:                break;
                    925: 
                    926:        default:
                    927:                // The secondary master key (if cascade, multiple concatenated)
                    928:                memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
                    929:        }
1.1       root      930: 
1.1.1.7   root      931:        // Mode of operation
                    932:        if (!EAInitMode (cryptoInfo))
                    933:                return ERR_OUTOFMEMORY;
                    934: 
1.1.1.2   root      935: 
1.1       root      936: #ifdef VOLFORMAT
1.1.1.15  root      937:        if (showKeys && !bInPlaceEncNonSys)
1.1       root      938:        {
                    939:                BOOL dots3 = FALSE;
                    940:                int i, j;
                    941: 
1.1.1.4   root      942:                j = EAGetKeySize (ea);
1.1       root      943: 
1.1.1.6   root      944:                if (j > NBR_KEY_BYTES_TO_DISPLAY)
1.1       root      945:                {
                    946:                        dots3 = TRUE;
1.1.1.6   root      947:                        j = NBR_KEY_BYTES_TO_DISPLAY;
1.1       root      948:                }
                    949: 
1.1.1.12  root      950:                MasterKeyGUIView[0] = 0;
1.1       root      951:                for (i = 0; i < j; i++)
                    952:                {
1.1.1.12  root      953:                        char tmp2[8] = {0};
                    954:                        sprintf (tmp2, "%02X", (int) (unsigned char) keyInfo.master_keydata[i + primaryKeyOffset]);
                    955:                        strcat (MasterKeyGUIView, tmp2);
1.1       root      956:                }
                    957: 
1.1.1.12  root      958:                HeaderKeyGUIView[0] = 0;
1.1.1.6   root      959:                for (i = 0; i < NBR_KEY_BYTES_TO_DISPLAY; i++)
1.1       root      960:                {
                    961:                        char tmp2[8];
1.1.1.12  root      962:                        sprintf (tmp2, "%02X", (int) (unsigned char) dk[primaryKeyOffset + i]);
                    963:                        strcat (HeaderKeyGUIView, tmp2);
1.1       root      964:                }
                    965: 
1.1.1.6   root      966:                if (dots3)
1.1.1.3   root      967:                {
1.1.1.21  root      968:                        DisplayPortionsOfKeys (hHeaderKey, hMasterKey, HeaderKeyGUIView, MasterKeyGUIView, !showKeys);
                    969:                }
                    970:                else
                    971:                {
                    972:                        SendMessage (hMasterKey, WM_SETTEXT, 0, (LPARAM) MasterKeyGUIView);
                    973:                        SendMessage (hHeaderKey, WM_SETTEXT, 0, (LPARAM) HeaderKeyGUIView);
1.1.1.3   root      974:                }
1.1       root      975:        }
1.1.1.12  root      976: #endif // #ifdef VOLFORMAT
1.1       root      977: 
1.1.1.3   root      978:        burn (dk, sizeof(dk));
1.1       root      979:        burn (&keyInfo, sizeof (keyInfo));
                    980: 
                    981:        *retInfo = cryptoInfo;
                    982:        return 0;
                    983: }
                    984: 
1.1.1.15  root      985: 
1.1.1.20  root      986: BOOL ReadEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header, DWORD *bytesRead)
                    987: {
                    988: #if TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
                    989: #error TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
                    990: #endif
                    991: 
                    992:        byte sectorBuffer[TC_MAX_VOLUME_SECTOR_SIZE];
                    993:        DISK_GEOMETRY geometry;
                    994: 
                    995:        if (!device)
                    996:                return ReadFile (fileHandle, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE, bytesRead, NULL);
                    997: 
                    998:        if (!DeviceIoControl (fileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof (geometry), bytesRead, NULL))
                    999:                return FALSE;
                   1000: 
                   1001:        if (geometry.BytesPerSector > sizeof (sectorBuffer) || geometry.BytesPerSector < TC_MIN_VOLUME_SECTOR_SIZE)
                   1002:        {
                   1003:                SetLastError (ERROR_INVALID_PARAMETER);
                   1004:                return FALSE;
                   1005:        }
                   1006: 
                   1007:        if (!ReadFile (fileHandle, sectorBuffer, max (TC_VOLUME_HEADER_EFFECTIVE_SIZE, geometry.BytesPerSector), bytesRead, NULL))
                   1008:                return FALSE;
                   1009: 
                   1010:        memcpy (header, sectorBuffer, min (*bytesRead, TC_VOLUME_HEADER_EFFECTIVE_SIZE));
                   1011:        
                   1012:        if (*bytesRead > TC_VOLUME_HEADER_EFFECTIVE_SIZE)
                   1013:                *bytesRead = TC_VOLUME_HEADER_EFFECTIVE_SIZE;
                   1014: 
                   1015:        return TRUE;
                   1016: }
                   1017: 
                   1018: 
                   1019: BOOL WriteEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header)
                   1020: {
                   1021: #if TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
                   1022: #error TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE
                   1023: #endif
                   1024: 
                   1025:        byte sectorBuffer[TC_MAX_VOLUME_SECTOR_SIZE];
                   1026:        DWORD bytesDone;
                   1027:        DISK_GEOMETRY geometry;
                   1028: 
                   1029:        if (!device)
                   1030:        {
                   1031:                if (!WriteFile (fileHandle, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE, &bytesDone, NULL))
                   1032:                        return FALSE;
                   1033: 
                   1034:                if (bytesDone != TC_VOLUME_HEADER_EFFECTIVE_SIZE)
                   1035:                {
                   1036:                        SetLastError (ERROR_INVALID_PARAMETER);
                   1037:                        return FALSE;
                   1038:                }
                   1039: 
                   1040:                return TRUE;
                   1041:        }
                   1042: 
                   1043:        if (!DeviceIoControl (fileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof (geometry), &bytesDone, NULL))
                   1044:                return FALSE;
                   1045: 
                   1046:        if (geometry.BytesPerSector > sizeof (sectorBuffer) || geometry.BytesPerSector < TC_MIN_VOLUME_SECTOR_SIZE)
                   1047:        {
                   1048:                SetLastError (ERROR_INVALID_PARAMETER);
                   1049:                return FALSE;
                   1050:        }
                   1051: 
                   1052:        if (geometry.BytesPerSector != TC_VOLUME_HEADER_EFFECTIVE_SIZE)
                   1053:        {
                   1054:                LARGE_INTEGER seekOffset;
                   1055: 
                   1056:                if (!ReadFile (fileHandle, sectorBuffer, geometry.BytesPerSector, &bytesDone, NULL))
                   1057:                        return FALSE;
                   1058: 
                   1059:                if (bytesDone != geometry.BytesPerSector)
                   1060:                {
                   1061:                        SetLastError (ERROR_INVALID_PARAMETER);
                   1062:                        return FALSE;
                   1063:                }
                   1064: 
                   1065:                seekOffset.QuadPart = -(int) bytesDone;
                   1066:                if (!SetFilePointerEx (fileHandle, seekOffset, NULL, FILE_CURRENT))
                   1067:                        return FALSE;
                   1068:        }
                   1069: 
                   1070:        memcpy (sectorBuffer, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
                   1071: 
                   1072:        if (!WriteFile (fileHandle, sectorBuffer, geometry.BytesPerSector, &bytesDone, NULL))
                   1073:                return FALSE;
                   1074: 
                   1075:        if (bytesDone != geometry.BytesPerSector)
                   1076:        {
                   1077:                SetLastError (ERROR_INVALID_PARAMETER);
                   1078:                return FALSE;
                   1079:        }
                   1080: 
                   1081:        return TRUE;
                   1082: }
                   1083: 
                   1084: 
1.1.1.15  root     1085: // Writes randomly generated data to unused/reserved header areas.
                   1086: // When bPrimaryOnly is TRUE, then only the primary header area (not the backup header area) is filled with random data.
                   1087: // When bBackupOnly is TRUE, only the backup header area (not the primary header area) is filled with random data.
                   1088: int WriteRandomDataToReservedHeaderAreas (HANDLE dev, CRYPTO_INFO *cryptoInfo, uint64 dataAreaSize, BOOL bPrimaryOnly, BOOL bBackupOnly)
                   1089: {
                   1090:        char temporaryKey[MASTER_KEYDATA_SIZE];
                   1091:        char originalK2[MASTER_KEYDATA_SIZE];
                   1092: 
1.1.1.20  root     1093:        byte buf[TC_VOLUME_HEADER_GROUP_SIZE];
1.1.1.15  root     1094: 
                   1095:        LARGE_INTEGER offset;
                   1096:        int nStatus = ERR_SUCCESS;
                   1097:        DWORD dwError;
1.1.1.20  root     1098:        DWORD bytesDone;
1.1.1.15  root     1099:        BOOL backupHeaders = bBackupOnly;
                   1100: 
                   1101:        if (bPrimaryOnly && bBackupOnly)
                   1102:                TC_THROW_FATAL_EXCEPTION;
                   1103: 
                   1104:        memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2));
                   1105: 
                   1106:        while (TRUE)
                   1107:        {
                   1108:                // Temporary keys
1.1.1.16  root     1109:                if (!RandgetBytes (temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE)
1.1.1.15  root     1110:                        || !RandgetBytes (cryptoInfo->k2, sizeof (cryptoInfo->k2), FALSE))
                   1111:                {
                   1112:                        nStatus = ERR_PARAMETER_INCORRECT; 
                   1113:                        goto final_seq;
                   1114:                }
                   1115: 
                   1116:                nStatus = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks);
                   1117:                if (nStatus != ERR_SUCCESS)
                   1118:                        goto final_seq;
                   1119: 
                   1120:                if (!EAInitMode (cryptoInfo))
                   1121:                {
                   1122:                        nStatus = ERR_MODE_INIT_FAILED;
                   1123:                        goto final_seq;
                   1124:                }
                   1125: 
                   1126:                offset.QuadPart = backupHeaders ? dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE : TC_VOLUME_HEADER_OFFSET;
                   1127: 
                   1128:                if (!SetFilePointerEx (dev, offset, NULL, FILE_BEGIN))
                   1129:                {
                   1130:                        nStatus = ERR_OS_ERROR;
                   1131:                        goto final_seq;
                   1132:                }
                   1133: 
1.1.1.20  root     1134:                if (!ReadFile (dev, buf, sizeof (buf), &bytesDone, NULL))
                   1135:                {
                   1136:                        nStatus = ERR_OS_ERROR;
                   1137:                        goto final_seq;
                   1138:                }
1.1.1.15  root     1139: 
1.1.1.20  root     1140:                if (bytesDone < TC_VOLUME_HEADER_EFFECTIVE_SIZE)
1.1.1.15  root     1141:                {
1.1.1.20  root     1142:                        SetLastError (ERROR_INVALID_PARAMETER);
1.1.1.15  root     1143:                        nStatus = ERR_OS_ERROR;
                   1144:                        goto final_seq;
                   1145:                }
                   1146: 
1.1.1.20  root     1147:                EncryptBuffer (buf + TC_VOLUME_HEADER_EFFECTIVE_SIZE, sizeof (buf) - TC_VOLUME_HEADER_EFFECTIVE_SIZE, cryptoInfo);
                   1148: 
                   1149:                if (!SetFilePointerEx (dev, offset, NULL, FILE_BEGIN))
                   1150:                {
                   1151:                        nStatus = ERR_OS_ERROR;
                   1152:                        goto final_seq;
                   1153:                }
                   1154: 
                   1155:                if (!WriteFile (dev, buf, sizeof (buf), &bytesDone, NULL))
                   1156:                {
                   1157:                        nStatus = ERR_OS_ERROR;
                   1158:                        goto final_seq;
                   1159:                }
                   1160: 
                   1161:                if (bytesDone != sizeof (buf))
                   1162:                {
                   1163:                        nStatus = ERR_PARAMETER_INCORRECT;
                   1164:                        goto final_seq;
                   1165:                }
                   1166: 
1.1.1.15  root     1167:                if (backupHeaders || bPrimaryOnly)
                   1168:                        break;
                   1169: 
                   1170:                backupHeaders = TRUE;
                   1171:        }
                   1172: 
                   1173:        memcpy (cryptoInfo->k2, originalK2, sizeof (cryptoInfo->k2));
                   1174: 
                   1175:        nStatus = EAInit (cryptoInfo->ea, cryptoInfo->master_keydata, cryptoInfo->ks);
                   1176:        if (nStatus != ERR_SUCCESS)
                   1177:                goto final_seq;
                   1178: 
                   1179:        if (!EAInitMode (cryptoInfo))
                   1180:        {
                   1181:                nStatus = ERR_MODE_INIT_FAILED;
                   1182:                goto final_seq;
                   1183:        }
                   1184: 
                   1185: final_seq:
                   1186: 
                   1187:        dwError = GetLastError();
                   1188: 
                   1189:        burn (temporaryKey, sizeof (temporaryKey));
                   1190:        burn (originalK2, sizeof (originalK2));
                   1191: 
                   1192:        if (nStatus != ERR_SUCCESS)
                   1193:                SetLastError (dwError);
                   1194: 
                   1195:        return nStatus;
                   1196: }
                   1197: 
1.1.1.12  root     1198: #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.