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

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

unix.superglobalmegacorp.com

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