Annotation of truecrypt/common/crypto.c, revision 1.1.1.21

1.1.1.11  root        1: /*
1.1.1.13  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.20  root        6:  the original source code (contained in this file) and all other portions
1.1.1.21! 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.20  root        9:  contained in the file License.txt included in TrueCrypt binary and source
                     10:  code distribution packages. */
1.1.1.7   root       11: 
                     12: #include "Tcdefs.h"
                     13: #include "Crypto.h"
1.1.1.13  root       14: #include "Xts.h"
1.1.1.7   root       15: #include "Crc.h"
1.1.1.11  root       16: #include "Common/Endian.h"
                     17: #include <string.h>
1.1.1.15  root       18: #ifndef TC_WINDOWS_BOOT
                     19: #include "EncryptionThreadPool.h"
                     20: #endif
                     21: #include "Volumes.h"
1.1.1.5   root       22: 
                     23: /* Update the following when adding a new cipher or EA:
                     24: 
                     25:    Crypto.h:
                     26:      ID #define
                     27:      MAX_EXPANDED_KEY #define
                     28: 
                     29:    Crypto.c:
                     30:      Ciphers[]
                     31:      EncryptionAlgorithms[]
                     32:      CipherInit()
                     33:      EncipherBlock()
                     34:      DecipherBlock()
1.1.1.7   root       35: 
1.1.1.5   root       36: */
                     37: 
1.1.1.14  root       38: #ifndef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
                     39: 
1.1.1.5   root       40: // Cipher configuration
                     41: static Cipher Ciphers[] =
                     42: {
1.1.1.7   root       43: //                                                             Block Size      Key Size        Key Schedule Size
                     44: //       ID            Name                    (Bytes)         (Bytes)         (Bytes)
1.1.1.13  root       45:        { AES,          "AES",                  16,                     32,                     AES_KS                          },
                     46:        { SERPENT,      "Serpent",              16,                     32,                     140*4                           },
                     47:        { TWOFISH,      "Twofish",              16,                     32,                     TWOFISH_KS                      },
                     48: #ifndef TC_WINDOWS_BOOT
1.1.1.16  root       49:        { BLOWFISH,     "Blowfish",             8,                      56,                     sizeof (BF_KEY)         },      // Deprecated/legacy
                     50:        { CAST,         "CAST5",                8,                      16,                     sizeof (CAST_KEY)       },      // Deprecated/legacy
                     51:        { TRIPLEDES,"Triple DES",       8,                      8*3,            sizeof (TDES_KEY)       },      // Deprecated/legacy
1.1.1.13  root       52: #endif
1.1.1.12  root       53:        { 0,            0,                              0,                      0,                      0                                       }
1.1.1.5   root       54: };
                     55: 
1.1.1.13  root       56: 
1.1.1.5   root       57: // Encryption algorithm configuration
1.1.1.13  root       58: // The following modes have been deprecated (legacy): LRW, CBC, INNER_CBC, OUTER_CBC
1.1.1.5   root       59: static EncryptionAlgorithm EncryptionAlgorithms[] =
                     60: {
1.1.1.13  root       61:        //  Cipher(s)                     Modes                                         FormatEnabled
                     62: 
                     63: #ifndef TC_WINDOWS_BOOT
                     64: 
                     65:        { { 0,                                          0 }, { 0, 0, 0, 0 },                            0 },    // Must be all-zero
                     66:        { { AES,                                        0 }, { XTS, LRW, CBC, 0 },                      1 },
                     67:        { { SERPENT,                            0 }, { XTS, LRW, CBC, 0 },                      1 },
                     68:        { { TWOFISH,                            0 }, { XTS, LRW, CBC, 0 },                      1 },
                     69:        { { TWOFISH, AES,                       0 }, { XTS, LRW, OUTER_CBC, 0 },        1 },
                     70:        { { SERPENT, TWOFISH, AES,      0 }, { XTS, LRW, OUTER_CBC, 0 },        1 },
                     71:        { { AES, SERPENT,                       0 }, { XTS, LRW, OUTER_CBC, 0 },        1 },
                     72:        { { AES, TWOFISH, SERPENT,      0 }, { XTS, LRW, OUTER_CBC, 0 },        1 },
                     73:        { { SERPENT, TWOFISH,           0 }, { XTS, LRW, OUTER_CBC, 0 },        1 },
                     74:        { { BLOWFISH,                           0 }, { LRW, CBC, 0, 0 },                        0 },    // Deprecated/legacy
                     75:        { { CAST,                                       0 }, { LRW, CBC, 0, 0 },                        0 },    // Deprecated/legacy
                     76:        { { TRIPLEDES,                          0 }, { LRW, CBC, 0, 0 },                        0 },    // Deprecated/legacy
                     77:        { { BLOWFISH, AES,                      0 }, { INNER_CBC, 0, 0, 0 },            0 },    // Deprecated/legacy
                     78:        { { SERPENT, BLOWFISH, AES,     0 }, { INNER_CBC, 0, 0, 0 },            0 },    // Deprecated/legacy
                     79:        { { 0,                                          0 }, { 0, 0, 0, 0 },                            0 }             // Must be all-zero
                     80: 
                     81: #else // TC_WINDOWS_BOOT
                     82: 
                     83:        // Encryption algorithms available for boot drive encryption
                     84:        { { 0,                                          0 }, { 0, 0 },          0 },    // Must be all-zero
                     85:        { { AES,                                        0 }, { XTS, 0 },        1 },
                     86:        { { SERPENT,                            0 }, { XTS, 0 },        1 },
                     87:        { { TWOFISH,                            0 }, { XTS, 0 },        1 },
                     88:        { { TWOFISH, AES,                       0 }, { XTS, 0 },        1 },
                     89:        { { SERPENT, TWOFISH, AES,      0 }, { XTS, 0 },        1 },
                     90:        { { AES, SERPENT,                       0 }, { XTS, 0 },        1 },
                     91:        { { AES, TWOFISH, SERPENT,      0 }, { XTS, 0 },        1 },
                     92:        { { SERPENT, TWOFISH,           0 }, { XTS, 0 },        1 },
                     93:        { { 0,                                          0 }, { 0, 0 },          0 },    // Must be all-zero
                     94: 
                     95: #endif
                     96: 
1.1.1.5   root       97: };
                     98: 
1.1.1.13  root       99: 
                    100: 
1.1.1.9   root      101: // Hash algorithms
                    102: static Hash Hashes[] =
1.1.1.13  root      103: {      // ID                   Name                    Deprecated              System Encryption
                    104:        { RIPEMD160,    "RIPEMD-160",   FALSE,                  TRUE },
                    105: #ifndef TC_WINDOWS_BOOT
                    106:        { SHA512,               "SHA-512",              FALSE,                  FALSE },
                    107:        { WHIRLPOOL,    "Whirlpool",    FALSE,                  FALSE },
                    108:        { SHA1,                 "SHA-1",                TRUE,                   FALSE },        // Deprecated/legacy
                    109: #endif
                    110:        { 0, 0, 0 }
1.1.1.9   root      111: };
1.1.1.8   root      112: 
1.1.1.7   root      113: /* Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal) */
1.1.1.8   root      114: int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks)
1.1.1.5   root      115: {
1.1.1.10  root      116:        int retVal = ERR_SUCCESS;
1.1.1.7   root      117: 
1.1.1.5   root      118:        switch (cipher)
                    119:        {
                    120:        case AES:
1.1.1.13  root      121: #ifndef TC_WINDOWS_BOOT
1.1.1.14  root      122:                if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
1.1.1.7   root      123:                        return ERR_CIPHER_INIT_FAILURE;
                    124: 
1.1.1.14  root      125:                if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof(aes_encrypt_ctx))) != EXIT_SUCCESS)
1.1.1.7   root      126:                        return ERR_CIPHER_INIT_FAILURE;
1.1.1.13  root      127: #else
                    128:                if (aes_set_key (key, (length_type) CipherGetKeySize(AES), (aes_context *) ks) != 0)
                    129:                        return ERR_CIPHER_INIT_FAILURE;
                    130: #endif
                    131:                break;
                    132: 
                    133:        case SERPENT:
                    134:                serpent_set_key (key, CipherGetKeySize(SERPENT) * 8, ks);
                    135:                break;
                    136:                
                    137:        case TWOFISH:
                    138:                twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, CipherGetKeySize(TWOFISH) * 8);
                    139:                break;
1.1.1.7   root      140: 
1.1.1.13  root      141: #ifndef TC_WINDOWS_BOOT
                    142:                
                    143:        case BLOWFISH:
                    144:                /* Deprecated/legacy */
1.1.1.16  root      145:                BlowfishSetKey ((BF_KEY *)ks, CipherGetKeySize(BLOWFISH), key);
1.1.1.5   root      146:                break;
                    147: 
                    148:        case CAST:
1.1.1.12  root      149:                /* Deprecated/legacy */
1.1.1.16  root      150:                Cast5SetKey ((CAST_KEY *) ks, CipherGetKeySize(CAST), key);
1.1.1.5   root      151:                break;
                    152: 
                    153:        case TRIPLEDES:
1.1.1.12  root      154:                /* Deprecated/legacy */
1.1.1.16  root      155:                TripleDesSetKey (key, CipherGetKeySize (TRIPLEDES), (TDES_KEY *) ks);
1.1.1.9   root      156: 
                    157:                // Verify whether all three DES keys are mutually different
1.1.1.10  root      158:                if (((*((__int64 *) key) ^ *((__int64 *) key+1)) & 0xFEFEFEFEFEFEFEFEULL) == 0
                    159:                || ((*((__int64 *) key+1) ^ *((__int64 *) key+2)) & 0xFEFEFEFEFEFEFEFEULL) == 0
                    160:                || ((*((__int64 *) key) ^ *((__int64 *) key+2)) & 0xFEFEFEFEFEFEFEFEULL) == 0)
1.1.1.9   root      161:                        retVal = ERR_CIPHER_INIT_WEAK_KEY;              // Non-fatal error
                    162: 
1.1.1.5   root      163:                break;
                    164: 
1.1.1.13  root      165: #endif // TC_WINDOWS_BOOT
1.1.1.5   root      166: 
1.1.1.13  root      167:        default:
                    168:                // Unknown/wrong cipher ID
                    169:                return ERR_CIPHER_INIT_FAILURE;
1.1.1.5   root      170:        }
1.1.1.13  root      171: 
1.1.1.7   root      172:        return retVal;
1.1.1.5   root      173: }
                    174: 
                    175: void EncipherBlock(int cipher, void *data, void *ks)
                    176: {
                    177:        switch (cipher)
                    178:        {
1.1.1.21! root      179:        case AES:       
        !           180:                // In 32-bit kernel mode, due to KeSaveFloatingPointState() overhead, AES instructions can be used only when processing the whole data unit.
        !           181: #if (defined (_WIN64) || !defined (TC_WINDOWS_DRIVER)) && !defined (TC_WINDOWS_BOOT)
        !           182:                if (IsAesHwCpuSupported())
        !           183:                        aes_hw_cpu_encrypt (ks, data);
        !           184:                else
        !           185: #endif
        !           186:                        aes_encrypt (data, data, ks);
        !           187:                break;
        !           188: 
1.1.1.13  root      189:        case TWOFISH:           twofish_encrypt (ks, data, data); break;
                    190:        case SERPENT:           serpent_encrypt (data, data, ks); break;
                    191: #ifndef TC_WINDOWS_BOOT
1.1.1.16  root      192:        case BLOWFISH:          BlowfishEncryptLE (data, data, ks, 1); break;   // Deprecated/legacy
                    193:        case CAST:                      Cast5Encrypt (data, data, ks); break;                   // Deprecated/legacy
                    194:        case TRIPLEDES:         TripleDesEncrypt (data, data, ks, 1); break;    // Deprecated/legacy
1.1.1.13  root      195: #endif
                    196:        default:                        TC_THROW_FATAL_EXCEPTION;       // Unknown/wrong ID
1.1.1.5   root      197:        }
                    198: }
                    199: 
1.1.1.21! root      200: #ifndef TC_WINDOWS_BOOT
        !           201: 
        !           202: void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
        !           203: {
        !           204:        byte *data = dataPtr;
        !           205: #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
        !           206:        KFLOATING_SAVE floatingPointState;
        !           207: #endif
        !           208: 
        !           209:        if (cipher == AES
        !           210:                && (blockCount & (32 - 1)) == 0
        !           211:                && IsAesHwCpuSupported()
        !           212: #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
        !           213:                && NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))
        !           214: #endif
        !           215:                )
        !           216:        {
        !           217:                while (blockCount > 0)
        !           218:                {
        !           219:                        aes_hw_cpu_encrypt_32_blocks (ks, data);
        !           220: 
        !           221:                        data += 32 * 16;
        !           222:                        blockCount -= 32;
        !           223:                }
        !           224: 
        !           225: #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
        !           226:                KeRestoreFloatingPointState (&floatingPointState);
        !           227: #endif
        !           228:        }
        !           229:        else
        !           230:        {
        !           231:                size_t blockSize = CipherGetBlockSize (cipher);
        !           232:                while (blockCount-- > 0)
        !           233:                {
        !           234:                        EncipherBlock (cipher, data, ks);
        !           235:                        data += blockSize;
        !           236:                }
        !           237:        }
        !           238: }
        !           239: 
        !           240: #endif // !TC_WINDOWS_BOOT
        !           241: 
1.1.1.5   root      242: void DecipherBlock(int cipher, void *data, void *ks)
                    243: {
                    244:        switch (cipher)
                    245:        {
1.1.1.13  root      246:        case SERPENT:   serpent_decrypt (data, data, ks); break;
                    247:        case TWOFISH:   twofish_decrypt (ks, data, data); break;
                    248: #ifndef TC_WINDOWS_BOOT
1.1.1.21! root      249: 
        !           250:        case AES:
        !           251: #if defined (_WIN64) || !defined (TC_WINDOWS_DRIVER)
        !           252:                if (IsAesHwCpuSupported())
        !           253:                        aes_hw_cpu_decrypt ((byte *) ks + sizeof (aes_encrypt_ctx), data);
        !           254:                else
        !           255: #endif
        !           256:                        aes_decrypt (data, data, (void *) ((char *) ks + sizeof(aes_encrypt_ctx)));
        !           257:                break;
        !           258: 
1.1.1.16  root      259:        case BLOWFISH:  BlowfishEncryptLE (data, data, ks, 0); break;   // Deprecated/legacy
                    260:        case CAST:              Cast5Decrypt (data, data, ks); break;                   // Deprecated/legacy
                    261:        case TRIPLEDES: TripleDesEncrypt (data, data, ks, 0); break;    // Deprecated/legacy
1.1.1.13  root      262: #else
                    263:        case AES:               aes_decrypt (data, data, ks); break;
                    264: #endif
                    265:        default:                TC_THROW_FATAL_EXCEPTION;       // Unknown/wrong ID
1.1.1.5   root      266:        }
                    267: }
                    268: 
1.1.1.21! root      269: #ifndef TC_WINDOWS_BOOT
        !           270: 
        !           271: void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
        !           272: {
        !           273:        byte *data = dataPtr;
        !           274: #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
        !           275:        KFLOATING_SAVE floatingPointState;
        !           276: #endif
        !           277: 
        !           278:        if (cipher == AES
        !           279:                && (blockCount & (32 - 1)) == 0
        !           280:                && IsAesHwCpuSupported()
        !           281: #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
        !           282:                && NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))
        !           283: #endif
        !           284:                )
        !           285:        {
        !           286:                while (blockCount > 0)
        !           287:                {
        !           288:                        aes_hw_cpu_decrypt_32_blocks ((byte *) ks + sizeof (aes_encrypt_ctx), data);
        !           289: 
        !           290:                        data += 32 * 16;
        !           291:                        blockCount -= 32;
        !           292:                }
        !           293: 
        !           294: #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
        !           295:                KeRestoreFloatingPointState (&floatingPointState);
        !           296: #endif
        !           297:        }
        !           298:        else
        !           299:        {
        !           300:                size_t blockSize = CipherGetBlockSize (cipher);
        !           301:                while (blockCount-- > 0)
        !           302:                {
        !           303:                        DecipherBlock (cipher, data, ks);
        !           304:                        data += blockSize;
        !           305:                }
        !           306:        }
        !           307: }
        !           308: 
        !           309: #endif // !TC_WINDOWS_BOOT
        !           310: 
        !           311: 
1.1.1.5   root      312: // Ciphers support
                    313: 
                    314: Cipher *CipherGet (int id)
                    315: {
                    316:        int i;
                    317:        for (i = 0; Ciphers[i].Id != 0; i++)
                    318:                if (Ciphers[i].Id == id)
                    319:                        return &Ciphers[i];
                    320: 
1.1.1.13  root      321:        return NULL;
1.1.1.5   root      322: }
                    323: 
                    324: char *CipherGetName (int cipherId)
                    325: {
                    326:        return CipherGet (cipherId) -> Name;
                    327: }
                    328: 
                    329: int CipherGetBlockSize (int cipherId)
                    330: {
                    331:        return CipherGet (cipherId) -> BlockSize;
                    332: }
                    333: 
                    334: int CipherGetKeySize (int cipherId)
                    335: {
                    336:        return CipherGet (cipherId) -> KeySize;
                    337: }
                    338: 
                    339: int CipherGetKeyScheduleSize (int cipherId)
                    340: {
                    341:        return CipherGet (cipherId) -> KeyScheduleSize;
                    342: }
                    343: 
1.1.1.21! root      344: #ifndef TC_WINDOWS_BOOT
        !           345: 
        !           346: BOOL CipherSupportsIntraDataUnitParallelization (int cipher)
        !           347: {
        !           348:        return cipher == AES && IsAesHwCpuSupported();
        !           349: }
        !           350: 
        !           351: #endif
        !           352: 
1.1.1.5   root      353: 
                    354: // Encryption algorithms support
                    355: 
                    356: int EAGetFirst ()
                    357: {
                    358:        return 1;
                    359: }
                    360: 
                    361: // Returns number of EAs
                    362: int EAGetCount (void)
                    363: {
                    364:        int ea, count = 0;
                    365: 
                    366:        for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
                    367:        {
                    368:                count++;
                    369:        }
                    370:        return count;
                    371: }
                    372: 
                    373: int EAGetNext (int previousEA)
                    374: {
                    375:        int id = previousEA + 1;
                    376:        if (EncryptionAlgorithms[id].Ciphers[0] != 0) return id;
                    377:        return 0;
                    378: }
                    379: 
1.1.1.8   root      380: 
                    381: // Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal)
                    382: int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
1.1.1.5   root      383: {
1.1.1.10  root      384:        int c, retVal = ERR_SUCCESS;
                    385: 
                    386:        if (ea == 0)
                    387:                return ERR_CIPHER_INIT_FAILURE;
1.1.1.5   root      388: 
                    389:        for (c = EAGetFirstCipher (ea); c != 0; c = EAGetNextCipher (ea, c))
                    390:        {
1.1.1.7   root      391:                switch (CipherInit (c, key, ks))
                    392:                {
                    393:                case ERR_CIPHER_INIT_FAILURE:
                    394:                        return ERR_CIPHER_INIT_FAILURE;
                    395: 
                    396:                case ERR_CIPHER_INIT_WEAK_KEY:
                    397:                        retVal = ERR_CIPHER_INIT_WEAK_KEY;              // Non-fatal error
                    398:                        break;
                    399:                }
1.1.1.5   root      400: 
                    401:                key += CipherGetKeySize (c);
                    402:                ks += CipherGetKeyScheduleSize (c);
                    403:        }
1.1.1.7   root      404:        return retVal;
1.1.1.5   root      405: }
                    406: 
1.1.1.8   root      407: 
1.1.1.14  root      408: #ifndef TC_WINDOWS_BOOT
                    409: 
1.1.1.15  root      410: BOOL EAInitMode (PCRYPTO_INFO ci)
1.1.1.8   root      411: {
                    412:        switch (ci->mode)
                    413:        {
1.1.1.13  root      414:        case XTS:
                    415:                // Secondary key schedule
                    416:                if (EAInit (ci->ea, ci->k2, ci->ks2) != ERR_SUCCESS)
                    417:                        return FALSE;
                    418: 
                    419:                /* Note: XTS mode could potentially be initialized with a weak key causing all blocks in one data unit
                    420:                on the volume to be tweaked with zero tweaks (i.e. 512 bytes of the volume would be encrypted in ECB
                    421:                mode). However, to create a TrueCrypt volume with such a weak key, each human being on Earth would have
                    422:                to create approximately 11,378,125,361,078,862 (about eleven quadrillion) TrueCrypt volumes (provided 
                    423:                that the size of each of the volumes is 1024 terabytes). */
                    424:                break;
                    425: 
1.1.1.8   root      426:        case LRW:
                    427:                switch (CipherGetBlockSize (EAGetFirstCipher (ci->ea)))
                    428:                {
                    429:                case 8:
1.1.1.12  root      430:                        /* Deprecated/legacy */
1.1.1.13  root      431:                        return Gf64TabInit (ci->k2, &ci->gf_ctx);
1.1.1.8   root      432: 
                    433:                case 16:
1.1.1.13  root      434:                        return Gf128Tab64Init (ci->k2, &ci->gf_ctx);
1.1.1.8   root      435: 
                    436:                default:
1.1.1.13  root      437:                        TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root      438:                }
                    439: 
1.1.1.13  root      440:                break;
                    441: 
                    442:        case CBC:
                    443:        case INNER_CBC:
                    444:        case OUTER_CBC:
                    445:                // The mode does not need to be initialized or is initialized elsewhere 
                    446:                return TRUE;
                    447: 
                    448:        default:                
                    449:                // Unknown/wrong ID
                    450:                TC_THROW_FATAL_EXCEPTION;
                    451:        }
1.1.1.8   root      452:        return TRUE;
                    453: }
                    454: 
                    455: 
1.1.1.5   root      456: // Returns name of EA, cascaded cipher names are separated by hyphens
                    457: char *EAGetName (char *buf, int ea)
                    458: {
                    459:        int i = EAGetLastCipher(ea);
1.1.1.10  root      460:        strcpy (buf, (i != 0) ? CipherGetName (i) : "?");
1.1.1.5   root      461: 
                    462:        while (i = EAGetPreviousCipher(ea, i))
                    463:        {
                    464:                strcat (buf, "-");
                    465:                strcat (buf, CipherGetName (i));
                    466:        }
                    467: 
                    468:        return buf;
                    469: }
                    470: 
1.1.1.8   root      471: 
                    472: int EAGetByName (char *name)
                    473: {
                    474:        int ea = EAGetFirst ();
                    475:        char n[128];
                    476: 
                    477:        do
                    478:        {
                    479:                EAGetName (n, ea);
                    480:                if (strcmp (n, name) == 0)
                    481:                        return ea;
                    482:        }
                    483:        while (ea = EAGetNext (ea));
                    484: 
                    485:        return 0;
                    486: }
                    487: 
1.1.1.13  root      488: #endif // TC_WINDOWS_BOOT
1.1.1.8   root      489: 
1.1.1.13  root      490: // Returns sum of key sizes of all ciphers of the EA (in bytes)
1.1.1.5   root      491: int EAGetKeySize (int ea)
                    492: {
1.1.1.8   root      493:        int i = EAGetFirstCipher (ea);
1.1.1.5   root      494:        int size = CipherGetKeySize (i);
                    495: 
1.1.1.8   root      496:        while (i = EAGetNextCipher (ea, i))
1.1.1.5   root      497:        {
                    498:                size += CipherGetKeySize (i);
                    499:        }
                    500: 
                    501:        return size;
                    502: }
                    503: 
1.1.1.8   root      504: 
                    505: // Returns the first mode of operation of EA
                    506: int EAGetFirstMode (int ea)
                    507: {
                    508:        return (EncryptionAlgorithms[ea].Modes[0]);
                    509: }
                    510: 
                    511: 
                    512: int EAGetNextMode (int ea, int previousModeId)
1.1.1.5   root      513: {
1.1.1.8   root      514:        int c, i = 0;
                    515:        while (c = EncryptionAlgorithms[ea].Modes[i++])
                    516:        {
                    517:                if (c == previousModeId) 
                    518:                        return EncryptionAlgorithms[ea].Modes[i];
                    519:        }
                    520: 
                    521:        return 0;
1.1.1.5   root      522: }
                    523: 
1.1.1.8   root      524: 
1.1.1.13  root      525: #ifndef TC_WINDOWS_BOOT
                    526: 
1.1.1.5   root      527: // Returns the name of the mode of operation of the whole EA
1.1.1.8   root      528: char *EAGetModeName (int ea, int mode, BOOL capitalLetters)
1.1.1.5   root      529: {
1.1.1.8   root      530:        switch (mode)
1.1.1.5   root      531:        {
1.1.1.13  root      532:        case XTS:
                    533: 
                    534:                return "XTS";
                    535: 
1.1.1.8   root      536:        case LRW:
1.1.1.13  root      537: 
                    538:                /* Deprecated/legacy */
                    539: 
1.1.1.8   root      540:                return "LRW";
                    541: 
1.1.1.5   root      542:        case CBC:
1.1.1.7   root      543:                {
1.1.1.8   root      544:                        /* Deprecated/legacy */
                    545: 
1.1.1.7   root      546:                        char eaName[100];
                    547:                        EAGetName (eaName, ea);
1.1.1.5   root      548: 
1.1.1.7   root      549:                        if (strcmp (eaName, "Triple DES") == 0)
                    550:                                return capitalLetters ? "Outer-CBC" : "outer-CBC";
1.1.1.5   root      551: 
1.1.1.7   root      552:                        return "CBC";
                    553:                }
1.1.1.5   root      554: 
                    555:        case OUTER_CBC:
1.1.1.8   root      556: 
                    557:                /* Deprecated/legacy */
                    558: 
1.1.1.7   root      559:                return  capitalLetters ? "Outer-CBC" : "outer-CBC";
1.1.1.5   root      560: 
                    561:        case INNER_CBC:
1.1.1.8   root      562: 
                    563:                /* Deprecated/legacy */
                    564: 
1.1.1.7   root      565:                return capitalLetters ? "Inner-CBC" : "inner-CBC";
1.1.1.5   root      566: 
                    567:        }
1.1.1.7   root      568:        return "[unknown]";
1.1.1.5   root      569: }
                    570: 
1.1.1.13  root      571: #endif // TC_WINDOWS_BOOT
1.1.1.8   root      572: 
1.1.1.13  root      573: 
                    574: // Returns sum of key schedule sizes of all ciphers of the EA
1.1.1.5   root      575: int EAGetKeyScheduleSize (int ea)
                    576: {
                    577:        int i = EAGetFirstCipher(ea);
                    578:        int size = CipherGetKeyScheduleSize (i);
                    579: 
                    580:        while (i = EAGetNextCipher(ea, i))
                    581:        {
                    582:                size += CipherGetKeyScheduleSize (i);
                    583:        }
                    584: 
                    585:        return size;
                    586: }
                    587: 
1.1.1.8   root      588: 
1.1.1.13  root      589: // Returns the largest key size needed by an EA for the specified mode of operation
                    590: int EAGetLargestKeyForMode (int mode)
                    591: {
                    592:        int ea, key = 0;
                    593: 
                    594:        for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
                    595:        {
                    596:                if (!EAIsModeSupported (ea, mode))
                    597:                        continue;
                    598: 
                    599:                if (EAGetKeySize (ea) >= key)
                    600:                        key = EAGetKeySize (ea);
                    601:        }
                    602:        return key;
                    603: }
                    604: 
                    605: 
                    606: // Returns the largest key needed by any EA for any mode
1.1.1.5   root      607: int EAGetLargestKey ()
                    608: {
                    609:        int ea, key = 0;
                    610: 
1.1.1.13  root      611:        for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
1.1.1.5   root      612:        {
                    613:                if (EAGetKeySize (ea) >= key)
                    614:                        key = EAGetKeySize (ea);
                    615:        }
                    616: 
                    617:        return key;
                    618: }
                    619: 
1.1.1.8   root      620: 
1.1.1.5   root      621: // Returns number of ciphers in EA
                    622: int EAGetCipherCount (int ea)
                    623: {
                    624:        int i = 0;
                    625:        while (EncryptionAlgorithms[ea].Ciphers[i++]);
                    626: 
                    627:        return i - 1;
                    628: }
                    629: 
                    630: 
                    631: int EAGetFirstCipher (int ea)
                    632: {
                    633:        return EncryptionAlgorithms[ea].Ciphers[0];
                    634: }
                    635: 
1.1.1.8   root      636: 
1.1.1.5   root      637: int EAGetLastCipher (int ea)
                    638: {
                    639:        int c, i = 0;
                    640:        while (c = EncryptionAlgorithms[ea].Ciphers[i++]);
                    641: 
                    642:        return EncryptionAlgorithms[ea].Ciphers[i - 2];
                    643: }
                    644: 
1.1.1.8   root      645: 
1.1.1.5   root      646: int EAGetNextCipher (int ea, int previousCipherId)
                    647: {
                    648:        int c, i = 0;
                    649:        while (c = EncryptionAlgorithms[ea].Ciphers[i++])
                    650:        {
                    651:                if (c == previousCipherId) 
                    652:                        return EncryptionAlgorithms[ea].Ciphers[i];
                    653:        }
                    654: 
                    655:        return 0;
                    656: }
                    657: 
1.1.1.8   root      658: 
1.1.1.5   root      659: int EAGetPreviousCipher (int ea, int previousCipherId)
                    660: {
                    661:        int c, i = 0;
                    662: 
                    663:        if (EncryptionAlgorithms[ea].Ciphers[i++] == previousCipherId)
                    664:                return 0;
                    665: 
                    666:        while (c = EncryptionAlgorithms[ea].Ciphers[i++])
                    667:        {
                    668:                if (c == previousCipherId) 
                    669:                        return EncryptionAlgorithms[ea].Ciphers[i - 2];
                    670:        }
                    671: 
                    672:        return 0;
                    673: }
                    674: 
1.1.1.8   root      675: 
1.1.1.11  root      676: int EAIsFormatEnabled (int ea)
                    677: {
                    678:        return EncryptionAlgorithms[ea].FormatEnabled;
                    679: }
                    680: 
                    681: 
1.1.1.13  root      682: // Returns TRUE if the mode of operation is supported for the encryption algorithm
                    683: BOOL EAIsModeSupported (int ea, int testedMode)
                    684: {
                    685:        int mode;
                    686: 
                    687:        for (mode = EAGetFirstMode (ea); mode != 0; mode = EAGetNextMode (ea, mode))
                    688:        {
                    689:                if (mode == testedMode)
                    690:                        return TRUE;
                    691:        }
                    692:        return FALSE;
                    693: }
                    694: 
                    695: 
1.1.1.9   root      696: Hash *HashGet (int id)
1.1.1.5   root      697: {
1.1.1.9   root      698:        int i;
                    699:        for (i = 0; Hashes[i].Id != 0; i++)
                    700:                if (Hashes[i].Id == id)
                    701:                        return &Hashes[i];
                    702: 
                    703:        return 0;
                    704: }
                    705: 
                    706: 
                    707: int HashGetIdByName (char *name)
                    708: {
                    709:        int i;
                    710:        for (i = 0; Hashes[i].Id != 0; i++)
                    711:                if (strcmp (Hashes[i].Name, name) == 0)
                    712:                        return Hashes[i].Id;
                    713: 
                    714:        return 0;
                    715: }
                    716: 
                    717: 
                    718: char *HashGetName (int hashId)
                    719: {
                    720:        return HashGet (hashId) -> Name;
1.1.1.5   root      721: }
                    722: 
1.1       root      723: 
1.1.1.13  root      724: BOOL HashIsDeprecated (int hashId)
                    725: {
                    726:        return HashGet (hashId) -> Deprecated;
                    727: }
                    728: 
                    729: 
1.1.1.14  root      730: #endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
                    731: 
                    732: 
1.1.1.13  root      733: #ifdef TC_WINDOWS_BOOT
                    734: 
                    735: static byte CryptoInfoBufferInUse = 0;
                    736: CRYPTO_INFO CryptoInfoBuffer;
                    737: 
                    738: #endif
                    739: 
                    740: PCRYPTO_INFO crypto_open ()
1.1       root      741: {
1.1.1.13  root      742: #ifndef TC_WINDOWS_BOOT
                    743: 
1.1       root      744:        /* Do the crt allocation */
1.1.1.9   root      745:        PCRYPTO_INFO cryptoInfo = (PCRYPTO_INFO) TCalloc (sizeof (CRYPTO_INFO));
                    746:        memset (cryptoInfo, 0, sizeof (CRYPTO_INFO));
                    747: 
1.1.1.2   root      748: #ifndef DEVICE_DRIVER
                    749:        VirtualLock (cryptoInfo, sizeof (CRYPTO_INFO));
                    750: #endif
                    751: 
1.1       root      752:        if (cryptoInfo == NULL)
                    753:                return NULL;
                    754: 
1.1.1.5   root      755:        cryptoInfo->ea = -1;
1.1       root      756:        return cryptoInfo;
1.1.1.13  root      757: 
                    758: #else // TC_WINDOWS_BOOT
                    759: 
                    760: #if 0
                    761:        if (CryptoInfoBufferInUse)
                    762:                TC_THROW_FATAL_EXCEPTION;
                    763: #endif
                    764:        CryptoInfoBufferInUse = 1;
                    765:        return &CryptoInfoBuffer;
                    766: 
                    767: #endif // TC_WINDOWS_BOOT
1.1       root      768: }
                    769: 
1.1.1.13  root      770: void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen)
1.1       root      771: {
                    772:        keyInfo->keyLength = nUserKeyLen;
                    773:        burn (keyInfo->userKey, sizeof (keyInfo->userKey));
                    774:        memcpy (keyInfo->userKey, lpszUserKey, nUserKeyLen);
                    775: }
                    776: 
1.1.1.13  root      777: void crypto_close (PCRYPTO_INFO cryptoInfo)
1.1       root      778: {
1.1.1.13  root      779: #ifndef TC_WINDOWS_BOOT
                    780: 
1.1.1.7   root      781:        if (cryptoInfo != NULL)
                    782:        {
                    783:                burn (cryptoInfo, sizeof (CRYPTO_INFO));
1.1.1.2   root      784: #ifndef DEVICE_DRIVER
1.1.1.7   root      785:                VirtualUnlock (cryptoInfo, sizeof (CRYPTO_INFO));
                    786: #endif
                    787:                TCfree (cryptoInfo);
                    788:        }
1.1.1.13  root      789: 
                    790: #else // TC_WINDOWS_BOOT
                    791: 
                    792:        burn (&CryptoInfoBuffer, sizeof (CryptoInfoBuffer));
                    793:        CryptoInfoBufferInUse = FALSE;
                    794: 
                    795: #endif // TC_WINDOWS_BOOT
                    796: }
                    797: 
                    798: 
1.1.1.14  root      799: #ifndef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
                    800: 
                    801: 
1.1.1.13  root      802: #ifndef TC_NO_COMPILER_INT64
                    803: void Xor128 (unsigned __int64 *a, unsigned __int64 *b)
                    804: {
                    805:        *a++ ^= *b++;
                    806:        *a ^= *b;
                    807: }
                    808: 
                    809: 
                    810: void Xor64 (unsigned __int64 *a, unsigned __int64 *b)
                    811: {
                    812:        *a ^= *b;
1.1       root      813: }
1.1.1.9   root      814: 
                    815: 
1.1.1.17  root      816: void EncryptBufferLRW128 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo)
1.1.1.9   root      817: {
1.1.1.13  root      818:        /* Deprecated/legacy */
                    819: 
                    820:        int cipher = EAGetFirstCipher (cryptoInfo->ea);
                    821:        int cipherCount = EAGetCipherCount (cryptoInfo->ea);
                    822:        unsigned __int8 *p = buffer;
                    823:        unsigned __int8 *ks = cryptoInfo->ks;
                    824:        unsigned __int8 i[8];
                    825:        unsigned __int8 t[16];
                    826:        unsigned __int64 b;
1.1.1.9   root      827: 
1.1.1.13  root      828:        *(unsigned __int64 *)i = BE64(blockIndex);
                    829: 
                    830:        if (length % 16)
                    831:                TC_THROW_FATAL_EXCEPTION;
                    832: 
                    833:        // Note that the maximum supported volume size is 8589934592 GB  (i.e., 2^63 bytes).
1.1.1.9   root      834: 
1.1.1.13  root      835:        for (b = 0; b < length >> 4; b++)
1.1.1.9   root      836:        {
1.1.1.13  root      837:                Gf128MulBy64Tab (i, t, &cryptoInfo->gf_ctx);
                    838:                Xor128 ((unsigned __int64 *)p, (unsigned __int64 *)t);
                    839: 
                    840:                if (cipherCount > 1)
1.1.1.9   root      841:                {
1.1.1.13  root      842:                        // Cipher cascade
                    843:                        for (cipher = EAGetFirstCipher (cryptoInfo->ea);
                    844:                                cipher != 0;
                    845:                                cipher = EAGetNextCipher (cryptoInfo->ea, cipher))
1.1.1.9   root      846:                        {
1.1.1.13  root      847:                                EncipherBlock (cipher, p, ks);
                    848:                                ks += CipherGetKeyScheduleSize (cipher);
1.1.1.9   root      849:                        }
1.1.1.13  root      850:                        ks = cryptoInfo->ks;
                    851:                }
                    852:                else
                    853:                {
                    854:                        EncipherBlock (cipher, p, ks);
1.1.1.9   root      855:                }
                    856: 
1.1.1.13  root      857:                Xor128 ((unsigned __int64 *)p, (unsigned __int64 *)t);
1.1.1.9   root      858: 
1.1.1.13  root      859:                p += 16;
                    860: 
                    861:                if (i[7] != 0xff)
                    862:                        i[7]++;
                    863:                else
                    864:                        *(unsigned __int64 *)i = BE64 ( BE64(*(unsigned __int64 *)i) + 1 );
                    865:        }
                    866: 
                    867:        FAST_ERASE64 (t, sizeof(t));
1.1.1.9   root      868: }
                    869: 
1.1       root      870: 
1.1.1.17  root      871: void EncryptBufferLRW64 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo)
1.1       root      872: {
1.1.1.13  root      873:        /* Deprecated/legacy */
1.1.1.8   root      874: 
1.1.1.13  root      875:        int cipher = EAGetFirstCipher (cryptoInfo->ea);
                    876:        unsigned __int8 *p = buffer;
                    877:        unsigned __int8 *ks = cryptoInfo->ks;
                    878:        unsigned __int8 i[8];
                    879:        unsigned __int8 t[8];
                    880:        unsigned __int64 b;
1.1.1.5   root      881: 
1.1.1.13  root      882:        *(unsigned __int64 *)i = BE64(blockIndex);
1.1.1.5   root      883: 
1.1.1.13  root      884:        if (length % 8)
                    885:                TC_THROW_FATAL_EXCEPTION;
1.1.1.5   root      886: 
1.1.1.13  root      887:        for (b = 0; b < length >> 3; b++)
1.1.1.5   root      888:        {
1.1.1.13  root      889:                Gf64MulTab (i, t, &cryptoInfo->gf_ctx);
                    890:                Xor64 ((unsigned __int64 *)p, (unsigned __int64 *)t);
1.1.1.5   root      891: 
1.1.1.13  root      892:                EncipherBlock (cipher, p, ks);
1.1.1.5   root      893: 
1.1.1.13  root      894:                Xor64 ((unsigned __int64 *)p, (unsigned __int64 *)t);
1.1.1.5   root      895: 
1.1.1.13  root      896:                p += 8;
1.1.1.5   root      897: 
1.1.1.13  root      898:                if (i[7] != 0xff)
                    899:                        i[7]++;
                    900:                else
                    901:                        *(unsigned __int64 *)i = BE64 ( BE64(*(unsigned __int64 *)i) + 1 );
1.1       root      902:        }
                    903: 
1.1.1.13  root      904:        FAST_ERASE64 (t, sizeof(t));
                    905: }
1.1.1.5   root      906: 
                    907: 
1.1.1.17  root      908: void DecryptBufferLRW128 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo)
1.1       root      909: {
1.1.1.13  root      910:        /* Deprecated/legacy */
1.1.1.8   root      911: 
1.1.1.13  root      912:        int cipher = EAGetFirstCipher (cryptoInfo->ea);
                    913:        int cipherCount = EAGetCipherCount (cryptoInfo->ea);
                    914:        unsigned __int8 *p = buffer;
                    915:        unsigned __int8 *ks = cryptoInfo->ks;
                    916:        unsigned __int8 i[8];
                    917:        unsigned __int8 t[16];
                    918:        unsigned __int64 b;
1.1.1.5   root      919: 
1.1.1.13  root      920:        *(unsigned __int64 *)i = BE64(blockIndex);
                    921: 
                    922:        if (length % 16)
                    923:                TC_THROW_FATAL_EXCEPTION;
                    924: 
                    925:        // Note that the maximum supported volume size is 8589934592 GB  (i.e., 2^63 bytes).
                    926: 
                    927:        for (b = 0; b < length >> 4; b++)
                    928:        {
                    929:                Gf128MulBy64Tab (i, t, &cryptoInfo->gf_ctx);
                    930:                Xor128 ((unsigned __int64 *)p, (unsigned __int64 *)t);
                    931: 
                    932:                if (cipherCount > 1)
                    933:                {
                    934:                        // Cipher cascade
                    935:                        ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);
                    936: 
                    937:                        for (cipher = EAGetLastCipher (cryptoInfo->ea);
                    938:                                cipher != 0;
                    939:                                cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
                    940:                        {
                    941:                                ks -= CipherGetKeyScheduleSize (cipher);
                    942:                                DecipherBlock (cipher, p, ks);
                    943:                        }
                    944:                }
                    945:                else
                    946:                {
                    947:                        DecipherBlock (cipher, p, ks);
                    948:                }
                    949: 
                    950:                Xor128 ((unsigned __int64 *)p, (unsigned __int64 *)t);
                    951: 
                    952:                p += 16;
                    953: 
                    954:                if (i[7] != 0xff)
                    955:                        i[7]++;
                    956:                else
                    957:                        *(unsigned __int64 *)i = BE64 ( BE64(*(unsigned __int64 *)i) + 1 );
                    958:        }
                    959: 
                    960:        FAST_ERASE64 (t, sizeof(t));
                    961: }
                    962: 
                    963: 
                    964: 
1.1.1.17  root      965: void DecryptBufferLRW64 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo)
1.1.1.13  root      966: {
                    967:        /* Deprecated/legacy */
                    968: 
                    969:        int cipher = EAGetFirstCipher (cryptoInfo->ea);
                    970:        unsigned __int8 *p = buffer;
                    971:        unsigned __int8 *ks = cryptoInfo->ks;
                    972:        unsigned __int8 i[8];
                    973:        unsigned __int8 t[8];
                    974:        unsigned __int64 b;
                    975: 
                    976:        *(unsigned __int64 *)i = BE64(blockIndex);
                    977: 
                    978:        if (length % 8)
                    979:                TC_THROW_FATAL_EXCEPTION;
                    980: 
                    981:        for (b = 0; b < length >> 3; b++)
                    982:        {
                    983:                Gf64MulTab (i, t, &cryptoInfo->gf_ctx);
                    984:                Xor64 ((unsigned __int64 *)p, (unsigned __int64 *)t);
                    985: 
                    986:                DecipherBlock (cipher, p, ks);
                    987: 
                    988:                Xor64 ((unsigned __int64 *)p, (unsigned __int64 *)t);
                    989: 
                    990:                p += 8;
                    991: 
                    992:                if (i[7] != 0xff)
                    993:                        i[7]++;
                    994:                else
                    995:                        *(unsigned __int64 *)i = BE64 ( BE64(*(unsigned __int64 *)i) + 1 );
                    996:        }
                    997: 
                    998:        FAST_ERASE64 (t, sizeof(t));
                    999: }
                   1000: 
                   1001: 
                   1002: // Initializes IV and whitening values for sector encryption/decryption in CBC mode.
                   1003: // IMPORTANT: This function has been deprecated (legacy).
                   1004: static void 
                   1005: InitSectorIVAndWhitening (unsigned __int64 unitNo,
                   1006:        int blockSize,
                   1007:        unsigned __int32 *iv,
                   1008:        unsigned __int64 *ivSeed,
                   1009:        unsigned __int32 *whitening)
                   1010: {
                   1011: 
                   1012:        /* IMPORTANT: This function has been deprecated (legacy) */
                   1013: 
                   1014:        unsigned __int64 iv64[4];
                   1015:        unsigned __int32 *iv32 = (unsigned __int32 *) iv64;
                   1016: 
                   1017:        iv64[0] = ivSeed[0] ^ LE64(unitNo);
                   1018:        iv64[1] = ivSeed[1] ^ LE64(unitNo);
                   1019:        iv64[2] = ivSeed[2] ^ LE64(unitNo);
                   1020:        if (blockSize == 16)
                   1021:        {
                   1022:                iv64[3] = ivSeed[3] ^ LE64(unitNo);
                   1023:        }
                   1024: 
                   1025:        iv[0] = iv32[0];
                   1026:        iv[1] = iv32[1];
                   1027: 
                   1028:        switch (blockSize)
                   1029:        {
                   1030:        case 16:
                   1031: 
                   1032:                // 128-bit block
                   1033: 
                   1034:                iv[2] = iv32[2];
                   1035:                iv[3] = iv32[3];
                   1036: 
                   1037:                whitening[0] = LE32( crc32int ( &iv32[4] ) ^ crc32int ( &iv32[7] ) );
                   1038:                whitening[1] = LE32( crc32int ( &iv32[5] ) ^ crc32int ( &iv32[6] ) );
                   1039:                break;
                   1040: 
                   1041:        case 8:
                   1042: 
                   1043:                // 64-bit block
                   1044: 
                   1045:                whitening[0] = LE32( crc32int ( &iv32[2] ) ^ crc32int ( &iv32[5] ) );
                   1046:                whitening[1] = LE32( crc32int ( &iv32[3] ) ^ crc32int ( &iv32[4] ) );
                   1047:                break;
                   1048: 
                   1049:        default:
                   1050:                TC_THROW_FATAL_EXCEPTION;
                   1051:        }
                   1052: }
                   1053: 
                   1054: 
                   1055: // EncryptBufferCBC    (deprecated/legacy)
                   1056: //
                   1057: // data:               data to be encrypted
                   1058: // len:                        number of bytes to encrypt (must be divisible by the largest cipher block size)
                   1059: // ks:                 scheduled key
                   1060: // iv:                 IV
                   1061: // whitening:  whitening constants
                   1062: // ea:                 outer-CBC cascade ID (0 = CBC/inner-CBC)
                   1063: // cipher:             CBC/inner-CBC cipher ID (0 = outer-CBC)
                   1064: 
                   1065: static void
                   1066: EncryptBufferCBC (unsigned __int32 *data, 
                   1067:                 unsigned int len,
                   1068:                 unsigned __int8 *ks,
                   1069:                 unsigned __int32 *iv,
                   1070:                 unsigned __int32 *whitening,
                   1071:                 int ea,
                   1072:                 int cipher)
                   1073: {
                   1074:        /* IMPORTANT: This function has been deprecated (legacy) */
                   1075: 
                   1076:        unsigned __int32 bufIV[4];
                   1077:        unsigned __int64 i;
                   1078:        int blockSize = CipherGetBlockSize (ea != 0 ? EAGetFirstCipher (ea) : cipher);
                   1079: 
                   1080:        if (len % blockSize)
                   1081:                TC_THROW_FATAL_EXCEPTION;
                   1082: 
                   1083:        //  IV
                   1084:        bufIV[0] = iv[0];
                   1085:        bufIV[1] = iv[1];
                   1086:        if (blockSize == 16)
                   1087:        {
                   1088:                bufIV[2] = iv[2];
1.1.1.5   root     1089:                bufIV[3] = iv[3];
                   1090:        }
                   1091: 
                   1092:        // Encrypt each block
                   1093:        for (i = 0; i < len/blockSize; i++)
                   1094:        {
                   1095:                // CBC
                   1096:                data[0] ^= bufIV[0];
                   1097:                data[1] ^= bufIV[1];
                   1098:                if (blockSize == 16)
                   1099:                {
                   1100:                        data[2] ^= bufIV[2];
                   1101:                        data[3] ^= bufIV[3];
                   1102:                }
                   1103: 
                   1104:                if (ea != 0)
                   1105:                {
                   1106:                        // Outer-CBC
                   1107:                        for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
                   1108:                        {
                   1109:                                EncipherBlock (cipher, data, ks);
                   1110:                                ks += CipherGetKeyScheduleSize (cipher);
                   1111:                        }
                   1112:                        ks -= EAGetKeyScheduleSize (ea);
                   1113:                }
                   1114:                else
                   1115:                {
                   1116:                        // CBC/inner-CBC
                   1117:                        EncipherBlock (cipher, data, ks);
                   1118:                }
                   1119: 
                   1120:                // CBC
                   1121:                bufIV[0] = data[0];
                   1122:                bufIV[1] = data[1];
                   1123:                if (blockSize == 16)
                   1124:                {
                   1125:                        bufIV[2] = data[2];
                   1126:                        bufIV[3] = data[3];
                   1127:                }
                   1128: 
                   1129:                // Whitening
                   1130:                data[0] ^= whitening[0];
                   1131:                data[1] ^= whitening[1];
                   1132:                if (blockSize == 16)
                   1133:                {
                   1134:                        data[2] ^= whitening[0];
                   1135:                        data[3] ^= whitening[1];
                   1136:                }
                   1137: 
1.1.1.7   root     1138:                data += blockSize / sizeof(*data);
1.1.1.5   root     1139:        }
1.1       root     1140: }
                   1141: 
1.1.1.5   root     1142: 
1.1.1.8   root     1143: // DecryptBufferCBC  (deprecated/legacy)
1.1.1.5   root     1144: //
                   1145: // data:               data to be decrypted
                   1146: // len:                        number of bytes to decrypt (must be divisible by the largest cipher block size)
                   1147: // ks:                 scheduled key
                   1148: // iv:                 IV
                   1149: // whitening:  whitening constants
                   1150: // ea:                 outer-CBC cascade ID (0 = CBC/inner-CBC)
                   1151: // cipher:             CBC/inner-CBC cipher ID (0 = outer-CBC)
                   1152: 
                   1153: static void
1.1.1.7   root     1154: DecryptBufferCBC (unsigned __int32 *data,
                   1155:                 unsigned int len,
1.1.1.8   root     1156:                 unsigned __int8 *ks,
1.1.1.7   root     1157:                 unsigned __int32 *iv,
                   1158:                 unsigned __int32 *whitening,
1.1.1.5   root     1159:                 int ea,
                   1160:                 int cipher)
1.1       root     1161: {
1.1.1.8   root     1162: 
                   1163:        /* IMPORTANT: This function has been deprecated (legacy) */
                   1164: 
1.1.1.7   root     1165:        unsigned __int32 bufIV[4];
1.1.1.5   root     1166:        unsigned __int64 i;
1.1.1.7   root     1167:        unsigned __int32 ct[4];
1.1.1.5   root     1168:        int blockSize = CipherGetBlockSize (ea != 0 ? EAGetFirstCipher (ea) : cipher);
                   1169: 
1.1.1.13  root     1170:        if (len % blockSize)
                   1171:                TC_THROW_FATAL_EXCEPTION;
                   1172: 
1.1.1.5   root     1173:        //  IV
                   1174:        bufIV[0] = iv[0];
                   1175:        bufIV[1] = iv[1];
                   1176:        if (blockSize == 16)
1.1       root     1177:        {
1.1.1.5   root     1178:                bufIV[2] = iv[2];
                   1179:                bufIV[3] = iv[3];
                   1180:        }
                   1181: 
                   1182:        // Decrypt each block
                   1183:        for (i = 0; i < len/blockSize; i++)
                   1184:        {
                   1185:                // Dewhitening
                   1186:                data[0] ^= whitening[0];
                   1187:                data[1] ^= whitening[1];
                   1188:                if (blockSize == 16)
                   1189:                {
                   1190:                        data[2] ^= whitening[0];
                   1191:                        data[3] ^= whitening[1];
                   1192:                }
                   1193: 
                   1194:                // CBC
                   1195:                ct[0] = data[0];
                   1196:                ct[1] = data[1];
                   1197:                if (blockSize == 16)
                   1198:                {
                   1199:                        ct[2] = data[2];
                   1200:                        ct[3] = data[3];
                   1201:                }
                   1202: 
                   1203:                if (ea != 0)
                   1204:                {
                   1205:                        // Outer-CBC
                   1206:                        ks += EAGetKeyScheduleSize (ea);
                   1207:                        for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
                   1208:                        {
                   1209:                                ks -= CipherGetKeyScheduleSize (cipher);
                   1210:                                DecipherBlock (cipher, data, ks);
                   1211:                        }
                   1212:                }
                   1213:                else
                   1214:                {
                   1215:                        // CBC/inner-CBC
                   1216:                        DecipherBlock (cipher, data, ks);
                   1217:                }
                   1218: 
                   1219:                // CBC
                   1220:                data[0] ^= bufIV[0];
                   1221:                data[1] ^= bufIV[1];
                   1222:                bufIV[0] = ct[0];
                   1223:                bufIV[1] = ct[1];
                   1224:                if (blockSize == 16)
                   1225:                {
                   1226:                        data[2] ^= bufIV[2];
                   1227:                        data[3] ^= bufIV[3];
                   1228:                        bufIV[2] = ct[2];
                   1229:                        bufIV[3] = ct[3];
                   1230:                }
                   1231: 
1.1.1.7   root     1232:                data += blockSize / sizeof(*data);
1.1       root     1233:        }
                   1234: }
1.1.1.13  root     1235: #endif // #ifndef TC_NO_COMPILER_INT64
1.1.1.5   root     1236: 
                   1237: 
1.1.1.13  root     1238: // EncryptBuffer
                   1239: //
1.1.1.16  root     1240: // buf:  data to be encrypted; the start of the buffer is assumed to be aligned with the start of a data unit.
                   1241: // len:  number of bytes to encrypt; must be divisible by the block size (for cascaded ciphers, divisible 
                   1242: //       by the largest block size used within the cascade)
1.1.1.15  root     1243: void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
1.1.1.8   root     1244: {
1.1.1.13  root     1245:        switch (cryptoInfo->mode)
1.1.1.8   root     1246:        {
1.1.1.13  root     1247:        case XTS:
1.1.1.8   root     1248:                {
1.1.1.13  root     1249:                        unsigned __int8 *ks = cryptoInfo->ks;
                   1250:                        unsigned __int8 *ks2 = cryptoInfo->ks2;
                   1251:                        UINT64_STRUCT dataUnitNo;
                   1252:                        int cipher;
                   1253: 
                   1254:                        // When encrypting/decrypting a buffer (typically a volume header) the sequential number
                   1255:                        // of the first XTS data unit in the buffer is always 0 and the start of the buffer is
1.1.1.16  root     1256:                        // always assumed to be aligned with the start of a data unit.
1.1.1.13  root     1257:                        dataUnitNo.LowPart = 0;
                   1258:                        dataUnitNo.HighPart = 0;
                   1259: 
1.1.1.8   root     1260:                        for (cipher = EAGetFirstCipher (cryptoInfo->ea);
                   1261:                                cipher != 0;
                   1262:                                cipher = EAGetNextCipher (cryptoInfo->ea, cipher))
                   1263:                        {
1.1.1.13  root     1264:                                EncryptBufferXTS (buf, len, &dataUnitNo, 0, ks, ks2, cipher);
1.1.1.8   root     1265: 
1.1.1.13  root     1266:                                ks += CipherGetKeyScheduleSize (cipher);
                   1267:                                ks2 += CipherGetKeyScheduleSize (cipher);
1.1.1.8   root     1268:                        }
                   1269:                }
1.1.1.13  root     1270:                break;
1.1.1.8   root     1271: 
1.1.1.13  root     1272: #ifndef TC_NO_COMPILER_INT64
                   1273:        case LRW:
1.1.1.5   root     1274: 
1.1.1.13  root     1275:                /* Deprecated/legacy */
1.1.1.5   root     1276: 
1.1.1.8   root     1277:                switch (CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea)))
                   1278:                {
                   1279:                case 8:
1.1.1.13  root     1280:                        EncryptBufferLRW64 ((unsigned __int8 *)buf, (unsigned __int64) len, 1, cryptoInfo);
1.1.1.8   root     1281:                        break;
                   1282: 
                   1283:                case 16:
1.1.1.13  root     1284:                        EncryptBufferLRW128 ((unsigned __int8 *)buf, (unsigned __int64) len, 1, cryptoInfo);
1.1.1.8   root     1285:                        break;
1.1.1.13  root     1286: 
                   1287:                default:
                   1288:                        TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root     1289:                }
                   1290:                break;
                   1291: 
1.1.1.5   root     1292:        case CBC:
                   1293:        case INNER_CBC:
                   1294:                {
1.1.1.8   root     1295:                        /* Deprecated/legacy */
1.1.1.5   root     1296: 
1.1.1.8   root     1297:                        unsigned __int8 *ks = cryptoInfo->ks;
                   1298:                        int cipher;
1.1.1.13  root     1299: 
1.1.1.8   root     1300:                        for (cipher = EAGetFirstCipher (cryptoInfo->ea);
                   1301:                                cipher != 0;
                   1302:                                cipher = EAGetNextCipher (cryptoInfo->ea, cipher))
                   1303:                        {
1.1.1.13  root     1304:                                EncryptBufferCBC ((unsigned __int32 *) buf,
1.1.1.8   root     1305:                                        (unsigned int) len,
                   1306:                                        ks,
1.1.1.13  root     1307:                                        (unsigned __int32 *) cryptoInfo->k2,
                   1308:                                        (unsigned __int32 *) &cryptoInfo->k2[8],
1.1.1.8   root     1309:                                        0,
                   1310:                                        cipher);
1.1.1.5   root     1311: 
1.1.1.8   root     1312:                                ks += CipherGetKeyScheduleSize (cipher);
                   1313:                        }
                   1314:                }
1.1.1.5   root     1315:                break;
                   1316: 
                   1317:        case OUTER_CBC:
                   1318: 
1.1.1.8   root     1319:                /* Deprecated/legacy */
                   1320: 
1.1.1.13  root     1321:                EncryptBufferCBC ((unsigned __int32 *) buf,
1.1.1.7   root     1322:                        (unsigned int) len,
1.1.1.8   root     1323:                        cryptoInfo->ks,
1.1.1.13  root     1324:                        (unsigned __int32 *) cryptoInfo->k2,
                   1325:                        (unsigned __int32 *) &cryptoInfo->k2[8],
1.1.1.8   root     1326:                        cryptoInfo->ea,
1.1.1.5   root     1327:                        0);
                   1328: 
                   1329:                break;
1.1.1.13  root     1330: #endif // #ifndef TC_NO_COMPILER_INT64
                   1331: 
                   1332:        default:                
                   1333:                // Unknown/wrong ID
                   1334:                TC_THROW_FATAL_EXCEPTION;
1.1.1.5   root     1335:        }
                   1336: }
                   1337: 
1.1.1.13  root     1338: #ifndef TC_NO_COMPILER_INT64
                   1339: // Converts a data unit number to the index of the first LRW block in the data unit.
1.1.1.8   root     1340: // Note that the maximum supported volume size is 8589934592 GB  (i.e., 2^63 bytes).
1.1.1.17  root     1341: uint64 DataUnit2LRWIndex (uint64 dataUnit, int blockSize, PCRYPTO_INFO ci)
1.1.1.8   root     1342: {
1.1.1.13  root     1343:        /* Deprecated/legacy */
                   1344: 
1.1.1.8   root     1345:        if (ci->hiddenVolume)
1.1.1.13  root     1346:                dataUnit -= ci->hiddenVolumeOffset / ENCRYPTION_DATA_UNIT_SIZE;
1.1.1.8   root     1347:        else
1.1.1.15  root     1348:                dataUnit -= TC_VOLUME_HEADER_SIZE_LEGACY / ENCRYPTION_DATA_UNIT_SIZE;   // Compensate for the volume header size
1.1.1.8   root     1349: 
                   1350:        switch (blockSize)
                   1351:        {
                   1352:        case 8:
1.1.1.13  root     1353:                return (dataUnit << 6) | 1;
1.1.1.8   root     1354: 
                   1355:        case 16:
1.1.1.13  root     1356:                return (dataUnit << 5) | 1;
                   1357: 
                   1358:        default:
                   1359:                TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root     1360:        }
                   1361: 
                   1362:        return 0;
                   1363: }
1.1.1.13  root     1364: #endif // #ifndef TC_NO_COMPILER_INT64
1.1.1.8   root     1365: 
                   1366: 
1.1.1.5   root     1367: // buf:                        data to be encrypted
1.1.1.13  root     1368: // unitNo:             sequential number of the data unit with which the buffer starts
                   1369: // nbrUnits:   number of data units in the buffer
1.1.1.19  root     1370: void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci)
1.1.1.15  root     1371: #ifndef TC_WINDOWS_BOOT
                   1372: {
                   1373:        EncryptionThreadPoolDoWork (EncryptDataUnitsWork, buf, structUnitNo, nbrUnits, ci);
                   1374: }
                   1375: 
                   1376: void EncryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
                   1377: #endif // !TC_WINDOWS_BOOT
1.1.1.8   root     1378: {
                   1379:        int ea = ci->ea;
                   1380:        unsigned __int8 *ks = ci->ks;
1.1.1.13  root     1381:        unsigned __int8 *ks2 = ci->ks2;
1.1.1.5   root     1382:        int cipher;
                   1383: 
1.1.1.13  root     1384: #ifndef TC_NO_COMPILER_INT64
                   1385:        void *iv = ci->k2;                                                                      // Deprecated/legacy
                   1386:        unsigned __int64 unitNo = structUnitNo->Value;
                   1387:        unsigned __int64 *iv64 = (unsigned __int64 *) iv;       // Deprecated/legacy
                   1388:        unsigned __int32 sectorIV[4];                                           // Deprecated/legacy
                   1389:        unsigned __int32 secWhitening[2];                                       // Deprecated/legacy
                   1390: #endif
                   1391: 
1.1.1.8   root     1392:        switch (ci->mode)
1.1.1.5   root     1393:        {
1.1.1.13  root     1394:        case XTS:
                   1395:                for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
                   1396:                {
                   1397:                        EncryptBufferXTS (buf,
                   1398:                                nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1399:                                structUnitNo,
                   1400:                                0,
                   1401:                                ks,
                   1402:                                ks2,
                   1403:                                cipher);
                   1404: 
                   1405:                        ks += CipherGetKeyScheduleSize (cipher);
                   1406:                        ks2 += CipherGetKeyScheduleSize (cipher);
                   1407:                }
                   1408:                break;
                   1409: 
                   1410: #ifndef TC_NO_COMPILER_INT64
1.1.1.8   root     1411:        case LRW:
1.1.1.13  root     1412: 
                   1413:                /* Deprecated/legacy */
                   1414: 
                   1415:                switch (CipherGetBlockSize (EAGetFirstCipher (ea)))
1.1.1.8   root     1416:                {
1.1.1.13  root     1417:                case 8:
                   1418:                        EncryptBufferLRW64 (buf,
                   1419:                                (unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1420:                                DataUnit2LRWIndex (unitNo, 8, ci),
                   1421:                                ci);
                   1422:                        break;
                   1423: 
                   1424:                case 16:
                   1425:                        EncryptBufferLRW128 (buf,
                   1426:                                (unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1427:                                DataUnit2LRWIndex (unitNo, 16, ci),
                   1428:                                ci);
                   1429:                        break;
                   1430: 
                   1431:                default:
                   1432:                        TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root     1433:                }
                   1434:                break;
                   1435: 
1.1.1.5   root     1436:        case CBC:
                   1437:        case INNER_CBC:
                   1438: 
1.1.1.8   root     1439:                /* Deprecated/legacy */
                   1440: 
1.1.1.13  root     1441:                while (nbrUnits--)
1.1.1.5   root     1442:                {
                   1443:                        for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
                   1444:                        {
1.1.1.13  root     1445:                                InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (cipher), sectorIV, iv64, secWhitening);
1.1.1.5   root     1446: 
1.1.1.13  root     1447:                                EncryptBufferCBC ((unsigned __int32 *) buf,
                   1448:                                        ENCRYPTION_DATA_UNIT_SIZE,
1.1.1.5   root     1449:                                        ks,
                   1450:                                        sectorIV,
                   1451:                                        secWhitening,
                   1452:                                        0,
                   1453:                                        cipher);
                   1454: 
                   1455:                                ks += CipherGetKeyScheduleSize (cipher);
                   1456:                        }
                   1457:                        ks -= EAGetKeyScheduleSize (ea);
1.1.1.13  root     1458:                        buf += ENCRYPTION_DATA_UNIT_SIZE;
                   1459:                        unitNo++;
1.1.1.5   root     1460:                }
                   1461:                break;
                   1462: 
                   1463:        case OUTER_CBC:
                   1464: 
1.1.1.8   root     1465:                /* Deprecated/legacy */
                   1466: 
1.1.1.13  root     1467:                while (nbrUnits--)
1.1.1.5   root     1468:                {
1.1.1.13  root     1469:                        InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (EAGetFirstCipher (ea)), sectorIV, iv64, secWhitening);
1.1.1.5   root     1470: 
1.1.1.13  root     1471:                        EncryptBufferCBC ((unsigned __int32 *) buf,
                   1472:                                ENCRYPTION_DATA_UNIT_SIZE,
1.1.1.5   root     1473:                                ks,
                   1474:                                sectorIV,
                   1475:                                secWhitening,
                   1476:                                ea,
                   1477:                                0);
                   1478: 
1.1.1.13  root     1479:                        buf += ENCRYPTION_DATA_UNIT_SIZE;
                   1480:                        unitNo++;
1.1.1.5   root     1481:                }
                   1482:                break;
1.1.1.13  root     1483: #endif // #ifndef TC_NO_COMPILER_INT64
                   1484: 
                   1485:        default:                
                   1486:                // Unknown/wrong ID
                   1487:                TC_THROW_FATAL_EXCEPTION;
1.1.1.5   root     1488:        }
                   1489: }
                   1490: 
                   1491: // DecryptBuffer
                   1492: //
1.1.1.16  root     1493: // buf:  data to be decrypted; the start of the buffer is assumed to be aligned with the start of a data unit.
                   1494: // len:  number of bytes to decrypt; must be divisible by the block size (for cascaded ciphers, divisible 
                   1495: //       by the largest block size used within the cascade)
1.1.1.15  root     1496: void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
1.1.1.5   root     1497: {
1.1.1.8   root     1498:        switch (cryptoInfo->mode)
1.1.1.5   root     1499:        {
1.1.1.13  root     1500:        case XTS:
                   1501:                {
                   1502:                        unsigned __int8 *ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);
                   1503:                        unsigned __int8 *ks2 = cryptoInfo->ks2 + EAGetKeyScheduleSize (cryptoInfo->ea);
                   1504:                        UINT64_STRUCT dataUnitNo;
                   1505:                        int cipher;
                   1506: 
                   1507:                        // When encrypting/decrypting a buffer (typically a volume header) the sequential number
                   1508:                        // of the first XTS data unit in the buffer is always 0 and the start of the buffer is
1.1.1.16  root     1509:                        // always assumed to be aligned with the start of the data unit 0.
1.1.1.13  root     1510:                        dataUnitNo.LowPart = 0;
                   1511:                        dataUnitNo.HighPart = 0;
                   1512: 
                   1513:                        for (cipher = EAGetLastCipher (cryptoInfo->ea);
                   1514:                                cipher != 0;
                   1515:                                cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
                   1516:                        {
                   1517:                                ks -= CipherGetKeyScheduleSize (cipher);
                   1518:                                ks2 -= CipherGetKeyScheduleSize (cipher);
                   1519: 
                   1520:                                DecryptBufferXTS (buf, len, &dataUnitNo, 0, ks, ks2, cipher);
                   1521:                        }
                   1522:                }
                   1523:                break;
                   1524: 
                   1525: #ifndef TC_NO_COMPILER_INT64
1.1.1.8   root     1526:        case LRW:
1.1.1.13  root     1527: 
                   1528:                /* Deprecated/legacy */
                   1529: 
1.1.1.8   root     1530:                switch (CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea)))
                   1531:                {
                   1532:                case 8:
1.1.1.13  root     1533:                        DecryptBufferLRW64 (buf, (unsigned __int64) len, 1, cryptoInfo);
1.1.1.8   root     1534:                        break;
                   1535: 
                   1536:                case 16:
1.1.1.13  root     1537:                        DecryptBufferLRW128 (buf, (unsigned __int64) len, 1, cryptoInfo);
1.1.1.8   root     1538:                        break;
1.1.1.13  root     1539: 
                   1540:                default:
                   1541:                        TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root     1542:                }
                   1543:                break;
                   1544: 
1.1.1.5   root     1545:        case CBC:
                   1546:        case INNER_CBC:
                   1547:                {
1.1.1.8   root     1548:                        /* Deprecated/legacy */
                   1549: 
                   1550:                        unsigned __int8 *ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);
                   1551:                        int cipher;
                   1552:                        for (cipher = EAGetLastCipher (cryptoInfo->ea);
                   1553:                                cipher != 0;
                   1554:                                cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
                   1555:                        {
                   1556:                                ks -= CipherGetKeyScheduleSize (cipher);
                   1557: 
1.1.1.13  root     1558:                                DecryptBufferCBC ((unsigned __int32 *) buf,
1.1.1.8   root     1559:                                        (unsigned int) len,
                   1560:                                        ks,
1.1.1.13  root     1561:                                        (unsigned __int32 *) cryptoInfo->k2,
                   1562:                                        (unsigned __int32 *) &cryptoInfo->k2[8],
1.1.1.8   root     1563:                                        0,
                   1564:                                        cipher);
                   1565:                        }
1.1.1.5   root     1566:                }
                   1567:                break;
                   1568: 
                   1569:        case OUTER_CBC:
                   1570: 
1.1.1.8   root     1571:                /* Deprecated/legacy */
                   1572: 
1.1.1.13  root     1573:                DecryptBufferCBC ((unsigned __int32 *) buf,
1.1.1.7   root     1574:                        (unsigned int) len,
1.1.1.8   root     1575:                        cryptoInfo->ks,
1.1.1.13  root     1576:                        (unsigned __int32 *) cryptoInfo->k2,
                   1577:                        (unsigned __int32 *) &cryptoInfo->k2[8],
1.1.1.8   root     1578:                        cryptoInfo->ea,
1.1.1.5   root     1579:                        0);
                   1580: 
                   1581:                break;
1.1.1.13  root     1582: #endif // #ifndef TC_NO_COMPILER_INT64
                   1583: 
                   1584:        default:                
                   1585:                // Unknown/wrong ID
                   1586:                TC_THROW_FATAL_EXCEPTION;
1.1.1.5   root     1587:        }
                   1588: }
                   1589: 
                   1590: // buf:                        data to be decrypted
1.1.1.13  root     1591: // unitNo:             sequential number of the data unit with which the buffer starts
                   1592: // nbrUnits:   number of data units in the buffer
1.1.1.19  root     1593: void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci)
1.1.1.15  root     1594: #ifndef TC_WINDOWS_BOOT
                   1595: {
                   1596:        EncryptionThreadPoolDoWork (DecryptDataUnitsWork, buf, structUnitNo, nbrUnits, ci);
                   1597: }
                   1598: 
                   1599: void DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
                   1600: #endif // !TC_WINDOWS_BOOT
1.1.1.8   root     1601: {
                   1602:        int ea = ci->ea;
                   1603:        unsigned __int8 *ks = ci->ks;
1.1.1.13  root     1604:        unsigned __int8 *ks2 = ci->ks2;
1.1.1.5   root     1605:        int cipher;
                   1606: 
1.1.1.13  root     1607: #ifndef TC_NO_COMPILER_INT64
                   1608:        void *iv = ci->k2;                                                                      // Deprecated/legacy
                   1609:        unsigned __int64 unitNo = structUnitNo->Value;
                   1610:        unsigned __int64 *iv64 = (unsigned __int64 *) iv;       // Deprecated/legacy
                   1611:        unsigned __int32 sectorIV[4];                                           // Deprecated/legacy
                   1612:        unsigned __int32 secWhitening[2];                                       // Deprecated/legacy
                   1613: #endif // #ifndef TC_NO_COMPILER_INT64
                   1614: 
                   1615: 
1.1.1.8   root     1616:        switch (ci->mode)
1.1.1.5   root     1617:        {
1.1.1.13  root     1618:        case XTS:
                   1619:                ks += EAGetKeyScheduleSize (ea);
                   1620:                ks2 += EAGetKeyScheduleSize (ea);
                   1621: 
                   1622:                for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
                   1623:                {
                   1624:                        ks -= CipherGetKeyScheduleSize (cipher);
                   1625:                        ks2 -= CipherGetKeyScheduleSize (cipher);
                   1626: 
                   1627:                        DecryptBufferXTS (buf,
                   1628:                                nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1629:                                structUnitNo,
                   1630:                                0,
                   1631:                                ks,
                   1632:                                ks2,
                   1633:                                cipher);
                   1634:                }
                   1635:                break;
                   1636: 
                   1637: #ifndef TC_NO_COMPILER_INT64
1.1.1.8   root     1638:        case LRW:
1.1.1.13  root     1639: 
                   1640:                /* Deprecated/legacy */
                   1641: 
                   1642:                switch (CipherGetBlockSize (EAGetFirstCipher (ea)))
1.1.1.8   root     1643:                {
1.1.1.13  root     1644:                case 8:
                   1645:                        DecryptBufferLRW64 (buf,
                   1646:                                (unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1647:                                DataUnit2LRWIndex (unitNo, 8, ci),
                   1648:                                ci);
                   1649:                        break;
                   1650: 
                   1651:                case 16:
                   1652:                        DecryptBufferLRW128 (buf,
                   1653:                                (unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1654:                                DataUnit2LRWIndex (unitNo, 16, ci),
                   1655:                                ci);
                   1656:                        break;
                   1657: 
                   1658:                default:
                   1659:                        TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root     1660:                }
                   1661:                break;
                   1662: 
1.1.1.5   root     1663:        case CBC:
                   1664:        case INNER_CBC:
                   1665: 
1.1.1.8   root     1666:                /* Deprecated/legacy */
                   1667: 
1.1.1.13  root     1668:                while (nbrUnits--)
1.1.1.5   root     1669:                {
                   1670:                        ks += EAGetKeyScheduleSize (ea);
                   1671:                        for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
                   1672:                        {
1.1.1.13  root     1673:                                InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (cipher), sectorIV, iv64, secWhitening);
1.1.1.5   root     1674: 
                   1675:                                ks -= CipherGetKeyScheduleSize (cipher);
                   1676: 
1.1.1.13  root     1677:                                DecryptBufferCBC ((unsigned __int32 *) buf,
                   1678:                                        ENCRYPTION_DATA_UNIT_SIZE,
1.1.1.5   root     1679:                                        ks,
                   1680:                                        sectorIV,
                   1681:                                        secWhitening,
                   1682:                                        0,
                   1683:                                        cipher);
                   1684:                        }
1.1.1.13  root     1685:                        buf += ENCRYPTION_DATA_UNIT_SIZE;
                   1686:                        unitNo++;
1.1.1.5   root     1687:                }
                   1688:                break;
                   1689: 
                   1690:        case OUTER_CBC:
                   1691: 
1.1.1.8   root     1692:                /* Deprecated/legacy */
                   1693: 
1.1.1.13  root     1694:                while (nbrUnits--)
1.1.1.5   root     1695:                {
1.1.1.13  root     1696:                        InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (EAGetFirstCipher (ea)), sectorIV, iv64, secWhitening);
1.1.1.5   root     1697: 
1.1.1.13  root     1698:                        DecryptBufferCBC ((unsigned __int32 *) buf,
                   1699:                                ENCRYPTION_DATA_UNIT_SIZE,
1.1.1.5   root     1700:                                ks,
                   1701:                                sectorIV,
                   1702:                                secWhitening,
                   1703:                                ea,
                   1704:                                0);
                   1705: 
1.1.1.13  root     1706:                        buf += ENCRYPTION_DATA_UNIT_SIZE;
                   1707:                        unitNo++;
1.1.1.5   root     1708:                }
                   1709:                break;
1.1.1.13  root     1710: #endif // #ifndef TC_NO_COMPILER_INT64
                   1711: 
                   1712:        default:                
                   1713:                // Unknown/wrong ID
                   1714:                TC_THROW_FATAL_EXCEPTION;
1.1.1.5   root     1715:        }
                   1716: }
                   1717: 
1.1.1.13  root     1718: 
                   1719: // Returns the maximum number of bytes necessary to be generated by the PBKDF2 (PKCS #5)
                   1720: int GetMaxPkcs5OutSize (void)
                   1721: {
                   1722:        int size = 32;
                   1723: 
                   1724:        size = max (size, EAGetLargestKeyForMode (XTS) * 2);    // Sizes of primary + secondary keys
                   1725: 
                   1726: #ifndef TC_WINDOWS_BOOT
                   1727:        size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (LRW));           // Deprecated/legacy
                   1728:        size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (CBC));           // Deprecated/legacy
                   1729:        size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (OUTER_CBC));     // Deprecated/legacy
                   1730:        size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (INNER_CBC));     // Deprecated/legacy
                   1731: #endif
                   1732: 
                   1733:        return size;
                   1734: }
1.1.1.14  root     1735: 
                   1736: 
                   1737: #else // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
                   1738: 
                   1739: 
                   1740: #if !defined (TC_WINDOWS_BOOT_AES) && !defined (TC_WINDOWS_BOOT_SERPENT) && !defined (TC_WINDOWS_BOOT_TWOFISH)
                   1741: #error No cipher defined
                   1742: #endif
                   1743: 
                   1744: void EncipherBlock(int cipher, void *data, void *ks)
                   1745: {
                   1746: #ifdef TC_WINDOWS_BOOT_AES
1.1.1.21! root     1747:        if (IsAesHwCpuSupported())
        !          1748:                aes_hw_cpu_encrypt ((byte *) ks, data);
        !          1749:        else
        !          1750:                aes_encrypt (data, data, ks); 
1.1.1.14  root     1751: #elif defined (TC_WINDOWS_BOOT_SERPENT)
                   1752:        serpent_encrypt (data, data, ks);
                   1753: #elif defined (TC_WINDOWS_BOOT_TWOFISH)
                   1754:        twofish_encrypt (ks, data, data);
                   1755: #endif
                   1756: }
                   1757: 
                   1758: void DecipherBlock(int cipher, void *data, void *ks)
                   1759: {
                   1760: #ifdef TC_WINDOWS_BOOT_AES
1.1.1.21! root     1761:        if (IsAesHwCpuSupported())
        !          1762:                aes_hw_cpu_decrypt ((byte *) ks + sizeof (aes_encrypt_ctx) + 14 * 16, data);
        !          1763:        else
        !          1764:                aes_decrypt (data, data, (aes_decrypt_ctx *) ((byte *) ks + sizeof(aes_encrypt_ctx))); 
1.1.1.14  root     1765: #elif defined (TC_WINDOWS_BOOT_SERPENT)
                   1766:        serpent_decrypt (data, data, ks);
                   1767: #elif defined (TC_WINDOWS_BOOT_TWOFISH)
                   1768:        twofish_decrypt (ks, data, data);
                   1769: #endif
                   1770: }
                   1771: 
                   1772: int EAGetFirst ()
                   1773: {
                   1774:        return 1;
                   1775: }
                   1776: 
                   1777: int EAGetNext (int previousEA)
                   1778: {
                   1779:        return 0;
                   1780: }
                   1781: 
                   1782: int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
                   1783: {
                   1784: #ifdef TC_WINDOWS_BOOT_AES
                   1785: 
                   1786:        aes_init();
                   1787: 
                   1788:        if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
                   1789:                return ERR_CIPHER_INIT_FAILURE;
                   1790:        if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS)
                   1791:                return ERR_CIPHER_INIT_FAILURE;
                   1792: 
                   1793: #elif defined (TC_WINDOWS_BOOT_SERPENT)
                   1794:        serpent_set_key (key, 32 * 8, ks);
                   1795: #elif defined (TC_WINDOWS_BOOT_TWOFISH)
                   1796:        twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, 32 * 8);
                   1797: #endif
                   1798:        return ERR_SUCCESS;
                   1799: }
                   1800: 
                   1801: int EAGetKeySize (int ea)
                   1802: {
                   1803:        return 32;
                   1804: }
                   1805: 
                   1806: int EAGetFirstCipher (int ea)
                   1807: {
                   1808:        return 1;
                   1809: }
                   1810: 
                   1811: void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
                   1812: {
                   1813:        UINT64_STRUCT dataUnitNo;
                   1814:        dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0;
                   1815:        EncryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1);
                   1816: }
                   1817: 
                   1818: void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
                   1819: {
                   1820:        EncryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1);
                   1821: }
                   1822: 
                   1823: void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
                   1824: {
                   1825:        UINT64_STRUCT dataUnitNo;
                   1826:        dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0;
                   1827:        DecryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1);
                   1828: }
                   1829: 
                   1830: void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
                   1831: {
                   1832:        DecryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1);
                   1833: }
                   1834: 
                   1835: #endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
1.1.1.21! root     1836: 
        !          1837: 
        !          1838: #if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_AES)
        !          1839: 
        !          1840: static BOOL HwEncryptionDisabled = FALSE;
        !          1841: 
        !          1842: BOOL IsAesHwCpuSupported ()
        !          1843: {
        !          1844:        static BOOL state = FALSE;
        !          1845:        static BOOL stateValid = FALSE;
        !          1846: 
        !          1847:        if (!stateValid)
        !          1848:        {
        !          1849:                state = is_aes_hw_cpu_supported() ? TRUE : FALSE;
        !          1850:                stateValid = TRUE;
        !          1851:        }
        !          1852: 
        !          1853:        return state && !HwEncryptionDisabled;
        !          1854: }
        !          1855: 
        !          1856: void EnableHwEncryption (BOOL enable)
        !          1857: {
        !          1858: #if defined (TC_WINDOWS_BOOT)
        !          1859:        if (enable)
        !          1860:                aes_hw_cpu_enable_sse();
        !          1861: #endif
        !          1862: 
        !          1863:        HwEncryptionDisabled = !enable;
        !          1864: }
        !          1865: 
        !          1866: BOOL IsHwEncryptionEnabled ()
        !          1867: {
        !          1868:        return !HwEncryptionDisabled;
        !          1869: }
        !          1870: 
        !          1871: #endif // !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.