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

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