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

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

unix.superglobalmegacorp.com

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