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

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
1.1.1.15! root        8:  by the TrueCrypt License 2.5 the full text of which is contained in the
1.1.1.13  root        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"
                     17: #include <string.h>
1.1.1.15! root       18: #ifndef TC_WINDOWS_BOOT
        !            19: #include "EncryptionThreadPool.h"
        !            20: #endif
        !            21: #include "Volumes.h"
1.1.1.5   root       22: 
                     23: /* Update the following when adding a new cipher or EA:
                     24: 
                     25:    Crypto.h:
                     26:      ID #define
                     27:      MAX_EXPANDED_KEY #define
                     28: 
                     29:    Crypto.c:
                     30:      Ciphers[]
                     31:      EncryptionAlgorithms[]
                     32:      CipherInit()
                     33:      EncipherBlock()
                     34:      DecipherBlock()
1.1.1.7   root       35: 
1.1.1.5   root       36: */
                     37: 
1.1.1.14  root       38: #ifndef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
                     39: 
1.1.1.5   root       40: // Cipher configuration
                     41: static Cipher Ciphers[] =
                     42: {
1.1.1.7   root       43: //                                                             Block Size      Key Size        Key Schedule Size
                     44: //       ID            Name                    (Bytes)         (Bytes)         (Bytes)
1.1.1.13  root       45:        { AES,          "AES",                  16,                     32,                     AES_KS                          },
                     46:        { SERPENT,      "Serpent",              16,                     32,                     140*4                           },
                     47:        { TWOFISH,      "Twofish",              16,                     32,                     TWOFISH_KS                      },
                     48: #ifndef TC_WINDOWS_BOOT
1.1.1.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.14  root      123:                if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
1.1.1.7   root      124:                        return ERR_CIPHER_INIT_FAILURE;
                    125: 
1.1.1.14  root      126:                if (aes_decrypt_key256 (key, (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:                break;
                    133: 
                    134:        case SERPENT:
                    135:                serpent_set_key (key, CipherGetKeySize(SERPENT) * 8, ks);
                    136:                break;
                    137:                
                    138:        case TWOFISH:
                    139:                twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, CipherGetKeySize(TWOFISH) * 8);
                    140:                break;
1.1.1.7   root      141: 
1.1.1.13  root      142: #ifndef TC_WINDOWS_BOOT
                    143:                
                    144:        case BLOWFISH:
                    145:                /* Deprecated/legacy */
                    146:                BF_set_key ((BF_KEY *)ks, CipherGetKeySize(BLOWFISH), key);
1.1.1.5   root      147:                break;
                    148: 
1.1.1.7   root      149:        case DES56:             
1.1.1.12  root      150:                /* Deprecated/legacy */
1.1.1.7   root      151:                switch (des_key_sched ((des_cblock *) key, (struct des_ks_struct *) ks))
                    152:                {
                    153:                case -1:
                    154:                        return ERR_CIPHER_INIT_FAILURE;
                    155:                case -2:
                    156:                        retVal = ERR_CIPHER_INIT_WEAK_KEY;              // Non-fatal error
                    157:                        break;
                    158:                }
1.1.1.5   root      159:                break;
                    160: 
                    161:        case CAST:
1.1.1.12  root      162:                /* Deprecated/legacy */
1.1.1.5   root      163:                CAST_set_key((CAST_KEY *) ks, CipherGetKeySize(CAST), key);
                    164:                break;
                    165: 
                    166:        case TRIPLEDES:
1.1.1.12  root      167:                /* Deprecated/legacy */
1.1.1.7   root      168:                switch (des_key_sched ((des_cblock *) key, (struct des_ks_struct *) ks))
                    169:                {
                    170:                case -1:
                    171:                        return ERR_CIPHER_INIT_FAILURE;
                    172:                case -2:
                    173:                        retVal = ERR_CIPHER_INIT_WEAK_KEY;              // Non-fatal error
                    174:                        break;
                    175:                }
                    176:                switch (des_key_sched ((des_cblock *) ((char*)(key)+8), (struct des_ks_struct *) (ks + CipherGetKeyScheduleSize (DES56))))
                    177:                {
                    178:                case -1:
                    179:                        return ERR_CIPHER_INIT_FAILURE;
                    180:                case -2:
                    181:                        retVal = ERR_CIPHER_INIT_WEAK_KEY;              // Non-fatal error
                    182:                        break;
                    183:                }
                    184:                switch (des_key_sched ((des_cblock *) ((char*)(key)+16), (struct des_ks_struct *) (ks + CipherGetKeyScheduleSize (DES56) * 2)))
                    185:                {
                    186:                case -1:
                    187:                        return ERR_CIPHER_INIT_FAILURE;
                    188:                case -2:
                    189:                        retVal = ERR_CIPHER_INIT_WEAK_KEY;              // Non-fatal error
                    190:                        break;
                    191:                }
1.1.1.9   root      192: 
                    193:                // Verify whether all three DES keys are mutually different
1.1.1.10  root      194:                if (((*((__int64 *) key) ^ *((__int64 *) key+1)) & 0xFEFEFEFEFEFEFEFEULL) == 0
                    195:                || ((*((__int64 *) key+1) ^ *((__int64 *) key+2)) & 0xFEFEFEFEFEFEFEFEULL) == 0
                    196:                || ((*((__int64 *) key) ^ *((__int64 *) key+2)) & 0xFEFEFEFEFEFEFEFEULL) == 0)
1.1.1.9   root      197:                        retVal = ERR_CIPHER_INIT_WEAK_KEY;              // Non-fatal error
                    198: 
1.1.1.5   root      199:                break;
                    200: 
1.1.1.13  root      201: #endif // TC_WINDOWS_BOOT
1.1.1.5   root      202: 
1.1.1.13  root      203:        default:
                    204:                // Unknown/wrong cipher ID
                    205:                return ERR_CIPHER_INIT_FAILURE;
1.1.1.5   root      206:        }
1.1.1.13  root      207: 
1.1.1.7   root      208:        return retVal;
1.1.1.5   root      209: }
                    210: 
                    211: void EncipherBlock(int cipher, void *data, void *ks)
                    212: {
                    213:        switch (cipher)
                    214:        {
                    215:        case AES:                       aes_encrypt (data, data, ks); break;
1.1.1.13  root      216:        case TWOFISH:           twofish_encrypt (ks, data, data); break;
                    217:        case SERPENT:           serpent_encrypt (data, data, ks); break;
                    218: #ifndef TC_WINDOWS_BOOT
                    219:        case BLOWFISH:          BF_ecb_le_encrypt (data, data, ks, 1); break;   // Deprecated/legacy
1.1.1.12  root      220:        case DES56:                     des_encrypt (data, ks, 1); break;                               // Deprecated/legacy
                    221:        case CAST:                      CAST_ecb_encrypt (data, data, ks, 1); break;    // Deprecated/legacy
                    222:        case TRIPLEDES:         des_ecb3_encrypt (data, data, ks,                               // Deprecated/legacy
1.1.1.5   root      223:                                                (void*)((char*) ks + CipherGetKeyScheduleSize (DES56)), (void*)((char*) ks + CipherGetKeyScheduleSize (DES56) * 2), 1); break;
1.1.1.13  root      224: #endif
                    225:        default:                        TC_THROW_FATAL_EXCEPTION;       // Unknown/wrong ID
1.1.1.5   root      226:        }
                    227: }
                    228: 
                    229: void DecipherBlock(int cipher, void *data, void *ks)
                    230: {
                    231:        switch (cipher)
                    232:        {
1.1.1.13  root      233:        case SERPENT:   serpent_decrypt (data, data, ks); break;
                    234:        case TWOFISH:   twofish_decrypt (ks, data, data); break;
                    235: #ifndef TC_WINDOWS_BOOT
1.1.1.5   root      236:        case AES:               aes_decrypt (data, data, (void *) ((char *) ks + sizeof(aes_encrypt_ctx))); break;
1.1.1.13  root      237:        case BLOWFISH:  BF_ecb_le_encrypt (data, data, ks, 0); break;   // Deprecated/legacy
1.1.1.12  root      238:        case DES56:             des_encrypt (data, ks, 0); break;                               // Deprecated/legacy
                    239:        case CAST:              CAST_ecb_encrypt (data, data, ks,0); break;             // Deprecated/legacy
                    240:        case TRIPLEDES: des_ecb3_encrypt (data, data, ks,                               // Deprecated/legacy
1.1.1.5   root      241:                                        (void*)((char*) ks + CipherGetKeyScheduleSize (DES56)),
                    242:                                        (void*)((char*) ks + CipherGetKeyScheduleSize (DES56) * 2), 0); break;
1.1.1.13  root      243: #else
                    244:        case AES:               aes_decrypt (data, data, ks); break;
                    245: #endif
                    246:        default:                TC_THROW_FATAL_EXCEPTION;       // Unknown/wrong ID
1.1.1.5   root      247:        }
                    248: }
                    249: 
                    250: // Ciphers support
                    251: 
                    252: Cipher *CipherGet (int id)
                    253: {
                    254:        int i;
                    255:        for (i = 0; Ciphers[i].Id != 0; i++)
                    256:                if (Ciphers[i].Id == id)
                    257:                        return &Ciphers[i];
                    258: 
1.1.1.13  root      259:        return NULL;
1.1.1.5   root      260: }
                    261: 
                    262: char *CipherGetName (int cipherId)
                    263: {
                    264:        return CipherGet (cipherId) -> Name;
                    265: }
                    266: 
                    267: int CipherGetBlockSize (int cipherId)
                    268: {
                    269:        return CipherGet (cipherId) -> BlockSize;
                    270: }
                    271: 
                    272: int CipherGetKeySize (int cipherId)
                    273: {
                    274:        return CipherGet (cipherId) -> KeySize;
                    275: }
                    276: 
                    277: int CipherGetKeyScheduleSize (int cipherId)
                    278: {
                    279:        return CipherGet (cipherId) -> KeyScheduleSize;
                    280: }
                    281: 
                    282: 
                    283: // Encryption algorithms support
                    284: 
                    285: int EAGetFirst ()
                    286: {
                    287:        return 1;
                    288: }
                    289: 
                    290: // Returns number of EAs
                    291: int EAGetCount (void)
                    292: {
                    293:        int ea, count = 0;
                    294: 
                    295:        for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
                    296:        {
                    297:                count++;
                    298:        }
                    299:        return count;
                    300: }
                    301: 
                    302: int EAGetNext (int previousEA)
                    303: {
                    304:        int id = previousEA + 1;
                    305:        if (EncryptionAlgorithms[id].Ciphers[0] != 0) return id;
                    306:        return 0;
                    307: }
                    308: 
1.1.1.8   root      309: 
                    310: // Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal)
                    311: int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
1.1.1.5   root      312: {
1.1.1.10  root      313:        int c, retVal = ERR_SUCCESS;
                    314: 
                    315:        if (ea == 0)
                    316:                return ERR_CIPHER_INIT_FAILURE;
1.1.1.5   root      317: 
                    318:        for (c = EAGetFirstCipher (ea); c != 0; c = EAGetNextCipher (ea, c))
                    319:        {
1.1.1.7   root      320:                switch (CipherInit (c, key, ks))
                    321:                {
                    322:                case ERR_CIPHER_INIT_FAILURE:
                    323:                        return ERR_CIPHER_INIT_FAILURE;
                    324: 
                    325:                case ERR_CIPHER_INIT_WEAK_KEY:
                    326:                        retVal = ERR_CIPHER_INIT_WEAK_KEY;              // Non-fatal error
                    327:                        break;
                    328:                }
1.1.1.5   root      329: 
                    330:                key += CipherGetKeySize (c);
                    331:                ks += CipherGetKeyScheduleSize (c);
                    332:        }
1.1.1.7   root      333:        return retVal;
1.1.1.5   root      334: }
                    335: 
1.1.1.8   root      336: 
1.1.1.14  root      337: #ifndef TC_WINDOWS_BOOT
                    338: 
1.1.1.15! root      339: BOOL EAInitMode (PCRYPTO_INFO ci)
1.1.1.8   root      340: {
                    341:        switch (ci->mode)
                    342:        {
1.1.1.13  root      343:        case XTS:
                    344:                // Secondary key schedule
                    345:                if (EAInit (ci->ea, ci->k2, ci->ks2) != ERR_SUCCESS)
                    346:                        return FALSE;
                    347: 
                    348:                /* Note: XTS mode could potentially be initialized with a weak key causing all blocks in one data unit
                    349:                on the volume to be tweaked with zero tweaks (i.e. 512 bytes of the volume would be encrypted in ECB
                    350:                mode). However, to create a TrueCrypt volume with such a weak key, each human being on Earth would have
                    351:                to create approximately 11,378,125,361,078,862 (about eleven quadrillion) TrueCrypt volumes (provided 
                    352:                that the size of each of the volumes is 1024 terabytes). */
                    353:                break;
                    354: 
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: 
                    377:        default:                
                    378:                // Unknown/wrong ID
                    379:                TC_THROW_FATAL_EXCEPTION;
                    380:        }
1.1.1.8   root      381:        return TRUE;
                    382: }
                    383: 
                    384: 
1.1.1.5   root      385: // Returns name of EA, cascaded cipher names are separated by hyphens
                    386: char *EAGetName (char *buf, int ea)
                    387: {
                    388:        int i = EAGetLastCipher(ea);
1.1.1.10  root      389:        strcpy (buf, (i != 0) ? CipherGetName (i) : "?");
1.1.1.5   root      390: 
                    391:        while (i = EAGetPreviousCipher(ea, i))
                    392:        {
                    393:                strcat (buf, "-");
                    394:                strcat (buf, CipherGetName (i));
                    395:        }
                    396: 
                    397:        return buf;
                    398: }
                    399: 
1.1.1.8   root      400: 
                    401: int EAGetByName (char *name)
                    402: {
                    403:        int ea = EAGetFirst ();
                    404:        char n[128];
                    405: 
                    406:        do
                    407:        {
                    408:                EAGetName (n, ea);
                    409:                if (strcmp (n, name) == 0)
                    410:                        return ea;
                    411:        }
                    412:        while (ea = EAGetNext (ea));
                    413: 
                    414:        return 0;
                    415: }
                    416: 
1.1.1.13  root      417: #endif // TC_WINDOWS_BOOT
1.1.1.8   root      418: 
1.1.1.13  root      419: // Returns sum of key sizes of all ciphers of the EA (in bytes)
1.1.1.5   root      420: int EAGetKeySize (int ea)
                    421: {
1.1.1.8   root      422:        int i = EAGetFirstCipher (ea);
1.1.1.5   root      423:        int size = CipherGetKeySize (i);
                    424: 
1.1.1.8   root      425:        while (i = EAGetNextCipher (ea, i))
1.1.1.5   root      426:        {
                    427:                size += CipherGetKeySize (i);
                    428:        }
                    429: 
                    430:        return size;
                    431: }
                    432: 
1.1.1.8   root      433: 
                    434: // Returns the first mode of operation of EA
                    435: int EAGetFirstMode (int ea)
                    436: {
                    437:        return (EncryptionAlgorithms[ea].Modes[0]);
                    438: }
                    439: 
                    440: 
                    441: int EAGetNextMode (int ea, int previousModeId)
1.1.1.5   root      442: {
1.1.1.8   root      443:        int c, i = 0;
                    444:        while (c = EncryptionAlgorithms[ea].Modes[i++])
                    445:        {
                    446:                if (c == previousModeId) 
                    447:                        return EncryptionAlgorithms[ea].Modes[i];
                    448:        }
                    449: 
                    450:        return 0;
1.1.1.5   root      451: }
                    452: 
1.1.1.8   root      453: 
1.1.1.13  root      454: #ifndef TC_WINDOWS_BOOT
                    455: 
1.1.1.5   root      456: // Returns the name of the mode of operation of the whole EA
1.1.1.8   root      457: char *EAGetModeName (int ea, int mode, BOOL capitalLetters)
1.1.1.5   root      458: {
1.1.1.8   root      459:        switch (mode)
1.1.1.5   root      460:        {
1.1.1.13  root      461:        case XTS:
                    462: 
                    463:                return "XTS";
                    464: 
1.1.1.8   root      465:        case LRW:
1.1.1.13  root      466: 
                    467:                /* Deprecated/legacy */
                    468: 
1.1.1.8   root      469:                return "LRW";
                    470: 
1.1.1.5   root      471:        case CBC:
1.1.1.7   root      472:                {
1.1.1.8   root      473:                        /* Deprecated/legacy */
                    474: 
1.1.1.7   root      475:                        char eaName[100];
                    476:                        EAGetName (eaName, ea);
1.1.1.5   root      477: 
1.1.1.7   root      478:                        if (strcmp (eaName, "Triple DES") == 0)
                    479:                                return capitalLetters ? "Outer-CBC" : "outer-CBC";
1.1.1.5   root      480: 
1.1.1.7   root      481:                        return "CBC";
                    482:                }
1.1.1.5   root      483: 
                    484:        case OUTER_CBC:
1.1.1.8   root      485: 
                    486:                /* Deprecated/legacy */
                    487: 
1.1.1.7   root      488:                return  capitalLetters ? "Outer-CBC" : "outer-CBC";
1.1.1.5   root      489: 
                    490:        case INNER_CBC:
1.1.1.8   root      491: 
                    492:                /* Deprecated/legacy */
                    493: 
1.1.1.7   root      494:                return capitalLetters ? "Inner-CBC" : "inner-CBC";
1.1.1.5   root      495: 
                    496:        }
1.1.1.7   root      497:        return "[unknown]";
1.1.1.5   root      498: }
                    499: 
1.1.1.13  root      500: #endif // TC_WINDOWS_BOOT
1.1.1.8   root      501: 
1.1.1.13  root      502: 
                    503: // Returns sum of key schedule sizes of all ciphers of the EA
1.1.1.5   root      504: int EAGetKeyScheduleSize (int ea)
                    505: {
                    506:        int i = EAGetFirstCipher(ea);
                    507:        int size = CipherGetKeyScheduleSize (i);
                    508: 
                    509:        while (i = EAGetNextCipher(ea, i))
                    510:        {
                    511:                size += CipherGetKeyScheduleSize (i);
                    512:        }
                    513: 
                    514:        return size;
                    515: }
                    516: 
1.1.1.8   root      517: 
1.1.1.13  root      518: // Returns the largest key size needed by an EA for the specified mode of operation
                    519: int EAGetLargestKeyForMode (int mode)
                    520: {
                    521:        int ea, key = 0;
                    522: 
                    523:        for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
                    524:        {
                    525:                if (!EAIsModeSupported (ea, mode))
                    526:                        continue;
                    527: 
                    528:                if (EAGetKeySize (ea) >= key)
                    529:                        key = EAGetKeySize (ea);
                    530:        }
                    531:        return key;
                    532: }
                    533: 
                    534: 
                    535: // Returns the largest key needed by any EA for any mode
1.1.1.5   root      536: int EAGetLargestKey ()
                    537: {
                    538:        int ea, key = 0;
                    539: 
1.1.1.13  root      540:        for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
1.1.1.5   root      541:        {
                    542:                if (EAGetKeySize (ea) >= key)
                    543:                        key = EAGetKeySize (ea);
                    544:        }
                    545: 
                    546:        return key;
                    547: }
                    548: 
1.1.1.8   root      549: 
1.1.1.5   root      550: // Returns number of ciphers in EA
                    551: int EAGetCipherCount (int ea)
                    552: {
                    553:        int i = 0;
                    554:        while (EncryptionAlgorithms[ea].Ciphers[i++]);
                    555: 
                    556:        return i - 1;
                    557: }
                    558: 
                    559: 
                    560: int EAGetFirstCipher (int ea)
                    561: {
                    562:        return EncryptionAlgorithms[ea].Ciphers[0];
                    563: }
                    564: 
1.1.1.8   root      565: 
1.1.1.5   root      566: int EAGetLastCipher (int ea)
                    567: {
                    568:        int c, i = 0;
                    569:        while (c = EncryptionAlgorithms[ea].Ciphers[i++]);
                    570: 
                    571:        return EncryptionAlgorithms[ea].Ciphers[i - 2];
                    572: }
                    573: 
1.1.1.8   root      574: 
1.1.1.5   root      575: int EAGetNextCipher (int ea, int previousCipherId)
                    576: {
                    577:        int c, i = 0;
                    578:        while (c = EncryptionAlgorithms[ea].Ciphers[i++])
                    579:        {
                    580:                if (c == previousCipherId) 
                    581:                        return EncryptionAlgorithms[ea].Ciphers[i];
                    582:        }
                    583: 
                    584:        return 0;
                    585: }
                    586: 
1.1.1.8   root      587: 
1.1.1.5   root      588: int EAGetPreviousCipher (int ea, int previousCipherId)
                    589: {
                    590:        int c, i = 0;
                    591: 
                    592:        if (EncryptionAlgorithms[ea].Ciphers[i++] == previousCipherId)
                    593:                return 0;
                    594: 
                    595:        while (c = EncryptionAlgorithms[ea].Ciphers[i++])
                    596:        {
                    597:                if (c == previousCipherId) 
                    598:                        return EncryptionAlgorithms[ea].Ciphers[i - 2];
                    599:        }
                    600: 
                    601:        return 0;
                    602: }
                    603: 
1.1.1.8   root      604: 
1.1.1.11  root      605: int EAIsFormatEnabled (int ea)
                    606: {
                    607:        return EncryptionAlgorithms[ea].FormatEnabled;
                    608: }
                    609: 
                    610: 
1.1.1.13  root      611: // Returns TRUE if the mode of operation is supported for the encryption algorithm
                    612: BOOL EAIsModeSupported (int ea, int testedMode)
                    613: {
                    614:        int mode;
                    615: 
                    616:        for (mode = EAGetFirstMode (ea); mode != 0; mode = EAGetNextMode (ea, mode))
                    617:        {
                    618:                if (mode == testedMode)
                    619:                        return TRUE;
                    620:        }
                    621:        return FALSE;
                    622: }
                    623: 
                    624: 
1.1.1.9   root      625: Hash *HashGet (int id)
1.1.1.5   root      626: {
1.1.1.9   root      627:        int i;
                    628:        for (i = 0; Hashes[i].Id != 0; i++)
                    629:                if (Hashes[i].Id == id)
                    630:                        return &Hashes[i];
                    631: 
                    632:        return 0;
                    633: }
                    634: 
                    635: 
                    636: int HashGetIdByName (char *name)
                    637: {
                    638:        int i;
                    639:        for (i = 0; Hashes[i].Id != 0; i++)
                    640:                if (strcmp (Hashes[i].Name, name) == 0)
                    641:                        return Hashes[i].Id;
                    642: 
                    643:        return 0;
                    644: }
                    645: 
                    646: 
                    647: char *HashGetName (int hashId)
                    648: {
                    649:        return HashGet (hashId) -> Name;
1.1.1.5   root      650: }
                    651: 
1.1       root      652: 
1.1.1.13  root      653: BOOL HashIsDeprecated (int hashId)
                    654: {
                    655:        return HashGet (hashId) -> Deprecated;
                    656: }
                    657: 
                    658: 
1.1.1.14  root      659: #endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
                    660: 
                    661: 
1.1.1.13  root      662: #ifdef TC_WINDOWS_BOOT
                    663: 
                    664: static byte CryptoInfoBufferInUse = 0;
                    665: CRYPTO_INFO CryptoInfoBuffer;
                    666: 
                    667: #endif
                    668: 
                    669: PCRYPTO_INFO crypto_open ()
1.1       root      670: {
1.1.1.13  root      671: #ifndef TC_WINDOWS_BOOT
                    672: 
1.1       root      673:        /* Do the crt allocation */
1.1.1.9   root      674:        PCRYPTO_INFO cryptoInfo = (PCRYPTO_INFO) TCalloc (sizeof (CRYPTO_INFO));
                    675:        memset (cryptoInfo, 0, sizeof (CRYPTO_INFO));
                    676: 
1.1.1.2   root      677: #ifndef DEVICE_DRIVER
                    678:        VirtualLock (cryptoInfo, sizeof (CRYPTO_INFO));
                    679: #endif
                    680: 
1.1       root      681:        if (cryptoInfo == NULL)
                    682:                return NULL;
                    683: 
1.1.1.5   root      684:        cryptoInfo->ea = -1;
1.1       root      685:        return cryptoInfo;
1.1.1.13  root      686: 
                    687: #else // TC_WINDOWS_BOOT
                    688: 
                    689: #if 0
                    690:        if (CryptoInfoBufferInUse)
                    691:                TC_THROW_FATAL_EXCEPTION;
                    692: #endif
                    693:        CryptoInfoBufferInUse = 1;
                    694:        return &CryptoInfoBuffer;
                    695: 
                    696: #endif // TC_WINDOWS_BOOT
1.1       root      697: }
                    698: 
1.1.1.13  root      699: void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen)
1.1       root      700: {
                    701:        keyInfo->keyLength = nUserKeyLen;
                    702:        burn (keyInfo->userKey, sizeof (keyInfo->userKey));
                    703:        memcpy (keyInfo->userKey, lpszUserKey, nUserKeyLen);
                    704: }
                    705: 
1.1.1.13  root      706: void crypto_close (PCRYPTO_INFO cryptoInfo)
1.1       root      707: {
1.1.1.13  root      708: #ifndef TC_WINDOWS_BOOT
                    709: 
1.1.1.7   root      710:        if (cryptoInfo != NULL)
                    711:        {
                    712:                burn (cryptoInfo, sizeof (CRYPTO_INFO));
1.1.1.2   root      713: #ifndef DEVICE_DRIVER
1.1.1.7   root      714:                VirtualUnlock (cryptoInfo, sizeof (CRYPTO_INFO));
                    715: #endif
                    716:                TCfree (cryptoInfo);
                    717:        }
1.1.1.13  root      718: 
                    719: #else // TC_WINDOWS_BOOT
                    720: 
                    721:        burn (&CryptoInfoBuffer, sizeof (CryptoInfoBuffer));
                    722:        CryptoInfoBufferInUse = FALSE;
                    723: 
                    724: #endif // TC_WINDOWS_BOOT
                    725: }
                    726: 
                    727: 
1.1.1.14  root      728: #ifndef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
                    729: 
                    730: 
1.1.1.13  root      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)
1.1.1.15! root     1172: void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
1.1.1.8   root     1173: {
1.1.1.13  root     1174:        switch (cryptoInfo->mode)
1.1.1.8   root     1175:        {
1.1.1.13  root     1176:        case XTS:
1.1.1.8   root     1177:                {
1.1.1.13  root     1178:                        unsigned __int8 *ks = cryptoInfo->ks;
                   1179:                        unsigned __int8 *ks2 = cryptoInfo->ks2;
                   1180:                        UINT64_STRUCT dataUnitNo;
                   1181:                        int cipher;
                   1182: 
                   1183:                        // When encrypting/decrypting a buffer (typically a volume header) the sequential number
                   1184:                        // of the first XTS data unit in the buffer is always 0 and the start of the buffer is
                   1185:                        // always considered aligned with the start of a data unit.
                   1186:                        dataUnitNo.LowPart = 0;
                   1187:                        dataUnitNo.HighPart = 0;
                   1188: 
1.1.1.8   root     1189:                        for (cipher = EAGetFirstCipher (cryptoInfo->ea);
                   1190:                                cipher != 0;
                   1191:                                cipher = EAGetNextCipher (cryptoInfo->ea, cipher))
                   1192:                        {
1.1.1.13  root     1193:                                EncryptBufferXTS (buf, len, &dataUnitNo, 0, ks, ks2, cipher);
1.1.1.8   root     1194: 
1.1.1.13  root     1195:                                ks += CipherGetKeyScheduleSize (cipher);
                   1196:                                ks2 += CipherGetKeyScheduleSize (cipher);
1.1.1.8   root     1197:                        }
                   1198:                }
1.1.1.13  root     1199:                break;
1.1.1.8   root     1200: 
1.1.1.13  root     1201: #ifndef TC_NO_COMPILER_INT64
                   1202:        case LRW:
1.1.1.5   root     1203: 
1.1.1.13  root     1204:                /* Deprecated/legacy */
1.1.1.5   root     1205: 
1.1.1.8   root     1206:                switch (CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea)))
                   1207:                {
                   1208:                case 8:
1.1.1.13  root     1209:                        EncryptBufferLRW64 ((unsigned __int8 *)buf, (unsigned __int64) len, 1, cryptoInfo);
1.1.1.8   root     1210:                        break;
                   1211: 
                   1212:                case 16:
1.1.1.13  root     1213:                        EncryptBufferLRW128 ((unsigned __int8 *)buf, (unsigned __int64) len, 1, cryptoInfo);
1.1.1.8   root     1214:                        break;
1.1.1.13  root     1215: 
                   1216:                default:
                   1217:                        TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root     1218:                }
                   1219:                break;
                   1220: 
1.1.1.5   root     1221:        case CBC:
                   1222:        case INNER_CBC:
                   1223:                {
1.1.1.8   root     1224:                        /* Deprecated/legacy */
1.1.1.5   root     1225: 
1.1.1.8   root     1226:                        unsigned __int8 *ks = cryptoInfo->ks;
                   1227:                        int cipher;
1.1.1.13  root     1228: 
1.1.1.8   root     1229:                        for (cipher = EAGetFirstCipher (cryptoInfo->ea);
                   1230:                                cipher != 0;
                   1231:                                cipher = EAGetNextCipher (cryptoInfo->ea, cipher))
                   1232:                        {
1.1.1.13  root     1233:                                EncryptBufferCBC ((unsigned __int32 *) buf,
1.1.1.8   root     1234:                                        (unsigned int) len,
                   1235:                                        ks,
1.1.1.13  root     1236:                                        (unsigned __int32 *) cryptoInfo->k2,
                   1237:                                        (unsigned __int32 *) &cryptoInfo->k2[8],
1.1.1.8   root     1238:                                        0,
                   1239:                                        cipher);
1.1.1.5   root     1240: 
1.1.1.8   root     1241:                                ks += CipherGetKeyScheduleSize (cipher);
                   1242:                        }
                   1243:                }
1.1.1.5   root     1244:                break;
                   1245: 
                   1246:        case OUTER_CBC:
                   1247: 
1.1.1.8   root     1248:                /* Deprecated/legacy */
                   1249: 
1.1.1.13  root     1250:                EncryptBufferCBC ((unsigned __int32 *) buf,
1.1.1.7   root     1251:                        (unsigned int) len,
1.1.1.8   root     1252:                        cryptoInfo->ks,
1.1.1.13  root     1253:                        (unsigned __int32 *) cryptoInfo->k2,
                   1254:                        (unsigned __int32 *) &cryptoInfo->k2[8],
1.1.1.8   root     1255:                        cryptoInfo->ea,
1.1.1.5   root     1256:                        0);
                   1257: 
                   1258:                break;
1.1.1.13  root     1259: #endif // #ifndef TC_NO_COMPILER_INT64
                   1260: 
                   1261:        default:                
                   1262:                // Unknown/wrong ID
                   1263:                TC_THROW_FATAL_EXCEPTION;
1.1.1.5   root     1264:        }
                   1265: }
                   1266: 
1.1.1.13  root     1267: #ifndef TC_NO_COMPILER_INT64
                   1268: // Converts a data unit number to the index of the first LRW block in the data unit.
1.1.1.8   root     1269: // Note that the maximum supported volume size is 8589934592 GB  (i.e., 2^63 bytes).
1.1.1.13  root     1270: unsigned __int64 DataUnit2LRWIndex (unsigned __int64 dataUnit, int blockSize, PCRYPTO_INFO ci)
1.1.1.8   root     1271: {
1.1.1.13  root     1272:        /* Deprecated/legacy */
                   1273: 
1.1.1.8   root     1274:        if (ci->hiddenVolume)
1.1.1.13  root     1275:                dataUnit -= ci->hiddenVolumeOffset / ENCRYPTION_DATA_UNIT_SIZE;
1.1.1.8   root     1276:        else
1.1.1.15! root     1277:                dataUnit -= TC_VOLUME_HEADER_SIZE_LEGACY / ENCRYPTION_DATA_UNIT_SIZE;   // Compensate for the volume header size
1.1.1.8   root     1278: 
                   1279:        switch (blockSize)
                   1280:        {
                   1281:        case 8:
1.1.1.13  root     1282:                return (dataUnit << 6) | 1;
1.1.1.8   root     1283: 
                   1284:        case 16:
1.1.1.13  root     1285:                return (dataUnit << 5) | 1;
                   1286: 
                   1287:        default:
                   1288:                TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root     1289:        }
                   1290: 
                   1291:        return 0;
                   1292: }
1.1.1.13  root     1293: #endif // #ifndef TC_NO_COMPILER_INT64
1.1.1.8   root     1294: 
                   1295: 
1.1.1.5   root     1296: // buf:                        data to be encrypted
1.1.1.13  root     1297: // unitNo:             sequential number of the data unit with which the buffer starts
                   1298: // nbrUnits:   number of data units in the buffer
                   1299: void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
1.1.1.15! root     1300: #ifndef TC_WINDOWS_BOOT
        !          1301: {
        !          1302:        EncryptionThreadPoolDoWork (EncryptDataUnitsWork, buf, structUnitNo, nbrUnits, ci);
        !          1303: }
        !          1304: 
        !          1305: void EncryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
        !          1306: #endif // !TC_WINDOWS_BOOT
1.1.1.8   root     1307: {
                   1308:        int ea = ci->ea;
                   1309:        unsigned __int8 *ks = ci->ks;
1.1.1.13  root     1310:        unsigned __int8 *ks2 = ci->ks2;
1.1.1.5   root     1311:        int cipher;
                   1312: 
1.1.1.13  root     1313: #ifndef TC_NO_COMPILER_INT64
                   1314:        void *iv = ci->k2;                                                                      // Deprecated/legacy
                   1315:        unsigned __int64 unitNo = structUnitNo->Value;
                   1316:        unsigned __int64 *iv64 = (unsigned __int64 *) iv;       // Deprecated/legacy
                   1317:        unsigned __int32 sectorIV[4];                                           // Deprecated/legacy
                   1318:        unsigned __int32 secWhitening[2];                                       // Deprecated/legacy
                   1319: #endif
                   1320: 
1.1.1.8   root     1321:        switch (ci->mode)
1.1.1.5   root     1322:        {
1.1.1.13  root     1323:        case XTS:
                   1324:                for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
                   1325:                {
                   1326:                        EncryptBufferXTS (buf,
                   1327:                                nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1328:                                structUnitNo,
                   1329:                                0,
                   1330:                                ks,
                   1331:                                ks2,
                   1332:                                cipher);
                   1333: 
                   1334:                        ks += CipherGetKeyScheduleSize (cipher);
                   1335:                        ks2 += CipherGetKeyScheduleSize (cipher);
                   1336:                }
                   1337:                break;
                   1338: 
                   1339: #ifndef TC_NO_COMPILER_INT64
1.1.1.8   root     1340:        case LRW:
1.1.1.13  root     1341: 
                   1342:                /* Deprecated/legacy */
                   1343: 
                   1344:                switch (CipherGetBlockSize (EAGetFirstCipher (ea)))
1.1.1.8   root     1345:                {
1.1.1.13  root     1346:                case 8:
                   1347:                        EncryptBufferLRW64 (buf,
                   1348:                                (unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1349:                                DataUnit2LRWIndex (unitNo, 8, ci),
                   1350:                                ci);
                   1351:                        break;
                   1352: 
                   1353:                case 16:
                   1354:                        EncryptBufferLRW128 (buf,
                   1355:                                (unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1356:                                DataUnit2LRWIndex (unitNo, 16, ci),
                   1357:                                ci);
                   1358:                        break;
                   1359: 
                   1360:                default:
                   1361:                        TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root     1362:                }
                   1363:                break;
                   1364: 
1.1.1.5   root     1365:        case CBC:
                   1366:        case INNER_CBC:
                   1367: 
1.1.1.8   root     1368:                /* Deprecated/legacy */
                   1369: 
1.1.1.13  root     1370:                while (nbrUnits--)
1.1.1.5   root     1371:                {
                   1372:                        for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
                   1373:                        {
1.1.1.13  root     1374:                                InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (cipher), sectorIV, iv64, secWhitening);
1.1.1.5   root     1375: 
1.1.1.13  root     1376:                                EncryptBufferCBC ((unsigned __int32 *) buf,
                   1377:                                        ENCRYPTION_DATA_UNIT_SIZE,
1.1.1.5   root     1378:                                        ks,
                   1379:                                        sectorIV,
                   1380:                                        secWhitening,
                   1381:                                        0,
                   1382:                                        cipher);
                   1383: 
                   1384:                                ks += CipherGetKeyScheduleSize (cipher);
                   1385:                        }
                   1386:                        ks -= EAGetKeyScheduleSize (ea);
1.1.1.13  root     1387:                        buf += ENCRYPTION_DATA_UNIT_SIZE;
                   1388:                        unitNo++;
1.1.1.5   root     1389:                }
                   1390:                break;
                   1391: 
                   1392:        case OUTER_CBC:
                   1393: 
1.1.1.8   root     1394:                /* Deprecated/legacy */
                   1395: 
1.1.1.13  root     1396:                while (nbrUnits--)
1.1.1.5   root     1397:                {
1.1.1.13  root     1398:                        InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (EAGetFirstCipher (ea)), sectorIV, iv64, secWhitening);
1.1.1.5   root     1399: 
1.1.1.13  root     1400:                        EncryptBufferCBC ((unsigned __int32 *) buf,
                   1401:                                ENCRYPTION_DATA_UNIT_SIZE,
1.1.1.5   root     1402:                                ks,
                   1403:                                sectorIV,
                   1404:                                secWhitening,
                   1405:                                ea,
                   1406:                                0);
                   1407: 
1.1.1.13  root     1408:                        buf += ENCRYPTION_DATA_UNIT_SIZE;
                   1409:                        unitNo++;
1.1.1.5   root     1410:                }
                   1411:                break;
1.1.1.13  root     1412: #endif // #ifndef TC_NO_COMPILER_INT64
                   1413: 
                   1414:        default:                
                   1415:                // Unknown/wrong ID
                   1416:                TC_THROW_FATAL_EXCEPTION;
1.1.1.5   root     1417:        }
                   1418: }
                   1419: 
                   1420: // DecryptBuffer
                   1421: //
                   1422: // buf:                        data to be decrypted
                   1423: // len:                        number of bytes to decrypt; must be divisible by the block size (for cascaded
                   1424: //              ciphers divisible by the largest block size used within the cascade)
1.1.1.15! root     1425: void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
1.1.1.5   root     1426: {
1.1.1.8   root     1427:        switch (cryptoInfo->mode)
1.1.1.5   root     1428:        {
1.1.1.13  root     1429:        case XTS:
                   1430:                {
                   1431:                        unsigned __int8 *ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);
                   1432:                        unsigned __int8 *ks2 = cryptoInfo->ks2 + EAGetKeyScheduleSize (cryptoInfo->ea);
                   1433:                        UINT64_STRUCT dataUnitNo;
                   1434:                        int cipher;
                   1435: 
                   1436:                        // When encrypting/decrypting a buffer (typically a volume header) the sequential number
                   1437:                        // of the first XTS data unit in the buffer is always 0 and the start of the buffer is
                   1438:                        // always considered aligned with the start of the data unit 0.
                   1439:                        dataUnitNo.LowPart = 0;
                   1440:                        dataUnitNo.HighPart = 0;
                   1441: 
                   1442:                        for (cipher = EAGetLastCipher (cryptoInfo->ea);
                   1443:                                cipher != 0;
                   1444:                                cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
                   1445:                        {
                   1446:                                ks -= CipherGetKeyScheduleSize (cipher);
                   1447:                                ks2 -= CipherGetKeyScheduleSize (cipher);
                   1448: 
                   1449:                                DecryptBufferXTS (buf, len, &dataUnitNo, 0, ks, ks2, cipher);
                   1450:                        }
                   1451:                }
                   1452:                break;
                   1453: 
                   1454: #ifndef TC_NO_COMPILER_INT64
1.1.1.8   root     1455:        case LRW:
1.1.1.13  root     1456: 
                   1457:                /* Deprecated/legacy */
                   1458: 
1.1.1.8   root     1459:                switch (CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea)))
                   1460:                {
                   1461:                case 8:
1.1.1.13  root     1462:                        DecryptBufferLRW64 (buf, (unsigned __int64) len, 1, cryptoInfo);
1.1.1.8   root     1463:                        break;
                   1464: 
                   1465:                case 16:
1.1.1.13  root     1466:                        DecryptBufferLRW128 (buf, (unsigned __int64) len, 1, cryptoInfo);
1.1.1.8   root     1467:                        break;
1.1.1.13  root     1468: 
                   1469:                default:
                   1470:                        TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root     1471:                }
                   1472:                break;
                   1473: 
1.1.1.5   root     1474:        case CBC:
                   1475:        case INNER_CBC:
                   1476:                {
1.1.1.8   root     1477:                        /* Deprecated/legacy */
                   1478: 
                   1479:                        unsigned __int8 *ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);
                   1480:                        int cipher;
                   1481:                        for (cipher = EAGetLastCipher (cryptoInfo->ea);
                   1482:                                cipher != 0;
                   1483:                                cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
                   1484:                        {
                   1485:                                ks -= CipherGetKeyScheduleSize (cipher);
                   1486: 
1.1.1.13  root     1487:                                DecryptBufferCBC ((unsigned __int32 *) buf,
1.1.1.8   root     1488:                                        (unsigned int) len,
                   1489:                                        ks,
1.1.1.13  root     1490:                                        (unsigned __int32 *) cryptoInfo->k2,
                   1491:                                        (unsigned __int32 *) &cryptoInfo->k2[8],
1.1.1.8   root     1492:                                        0,
                   1493:                                        cipher);
                   1494:                        }
1.1.1.5   root     1495:                }
                   1496:                break;
                   1497: 
                   1498:        case OUTER_CBC:
                   1499: 
1.1.1.8   root     1500:                /* Deprecated/legacy */
                   1501: 
1.1.1.13  root     1502:                DecryptBufferCBC ((unsigned __int32 *) buf,
1.1.1.7   root     1503:                        (unsigned int) len,
1.1.1.8   root     1504:                        cryptoInfo->ks,
1.1.1.13  root     1505:                        (unsigned __int32 *) cryptoInfo->k2,
                   1506:                        (unsigned __int32 *) &cryptoInfo->k2[8],
1.1.1.8   root     1507:                        cryptoInfo->ea,
1.1.1.5   root     1508:                        0);
                   1509: 
                   1510:                break;
1.1.1.13  root     1511: #endif // #ifndef TC_NO_COMPILER_INT64
                   1512: 
                   1513:        default:                
                   1514:                // Unknown/wrong ID
                   1515:                TC_THROW_FATAL_EXCEPTION;
1.1.1.5   root     1516:        }
                   1517: }
                   1518: 
                   1519: // buf:                        data to be decrypted
1.1.1.13  root     1520: // unitNo:             sequential number of the data unit with which the buffer starts
                   1521: // nbrUnits:   number of data units in the buffer
                   1522: void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
1.1.1.15! root     1523: #ifndef TC_WINDOWS_BOOT
        !          1524: {
        !          1525:        EncryptionThreadPoolDoWork (DecryptDataUnitsWork, buf, structUnitNo, nbrUnits, ci);
        !          1526: }
        !          1527: 
        !          1528: void DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
        !          1529: #endif // !TC_WINDOWS_BOOT
1.1.1.8   root     1530: {
                   1531:        int ea = ci->ea;
                   1532:        unsigned __int8 *ks = ci->ks;
1.1.1.13  root     1533:        unsigned __int8 *ks2 = ci->ks2;
1.1.1.5   root     1534:        int cipher;
                   1535: 
1.1.1.13  root     1536: #ifndef TC_NO_COMPILER_INT64
                   1537:        void *iv = ci->k2;                                                                      // Deprecated/legacy
                   1538:        unsigned __int64 unitNo = structUnitNo->Value;
                   1539:        unsigned __int64 *iv64 = (unsigned __int64 *) iv;       // Deprecated/legacy
                   1540:        unsigned __int32 sectorIV[4];                                           // Deprecated/legacy
                   1541:        unsigned __int32 secWhitening[2];                                       // Deprecated/legacy
                   1542: #endif // #ifndef TC_NO_COMPILER_INT64
                   1543: 
                   1544: 
1.1.1.8   root     1545:        switch (ci->mode)
1.1.1.5   root     1546:        {
1.1.1.13  root     1547:        case XTS:
                   1548:                ks += EAGetKeyScheduleSize (ea);
                   1549:                ks2 += EAGetKeyScheduleSize (ea);
                   1550: 
                   1551:                for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
                   1552:                {
                   1553:                        ks -= CipherGetKeyScheduleSize (cipher);
                   1554:                        ks2 -= CipherGetKeyScheduleSize (cipher);
                   1555: 
                   1556:                        DecryptBufferXTS (buf,
                   1557:                                nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1558:                                structUnitNo,
                   1559:                                0,
                   1560:                                ks,
                   1561:                                ks2,
                   1562:                                cipher);
                   1563:                }
                   1564:                break;
                   1565: 
                   1566: #ifndef TC_NO_COMPILER_INT64
1.1.1.8   root     1567:        case LRW:
1.1.1.13  root     1568: 
                   1569:                /* Deprecated/legacy */
                   1570: 
                   1571:                switch (CipherGetBlockSize (EAGetFirstCipher (ea)))
1.1.1.8   root     1572:                {
1.1.1.13  root     1573:                case 8:
                   1574:                        DecryptBufferLRW64 (buf,
                   1575:                                (unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1576:                                DataUnit2LRWIndex (unitNo, 8, ci),
                   1577:                                ci);
                   1578:                        break;
                   1579: 
                   1580:                case 16:
                   1581:                        DecryptBufferLRW128 (buf,
                   1582:                                (unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
                   1583:                                DataUnit2LRWIndex (unitNo, 16, ci),
                   1584:                                ci);
                   1585:                        break;
                   1586: 
                   1587:                default:
                   1588:                        TC_THROW_FATAL_EXCEPTION;
1.1.1.8   root     1589:                }
                   1590:                break;
                   1591: 
1.1.1.5   root     1592:        case CBC:
                   1593:        case INNER_CBC:
                   1594: 
1.1.1.8   root     1595:                /* Deprecated/legacy */
                   1596: 
1.1.1.13  root     1597:                while (nbrUnits--)
1.1.1.5   root     1598:                {
                   1599:                        ks += EAGetKeyScheduleSize (ea);
                   1600:                        for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
                   1601:                        {
1.1.1.13  root     1602:                                InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (cipher), sectorIV, iv64, secWhitening);
1.1.1.5   root     1603: 
                   1604:                                ks -= CipherGetKeyScheduleSize (cipher);
                   1605: 
1.1.1.13  root     1606:                                DecryptBufferCBC ((unsigned __int32 *) buf,
                   1607:                                        ENCRYPTION_DATA_UNIT_SIZE,
1.1.1.5   root     1608:                                        ks,
                   1609:                                        sectorIV,
                   1610:                                        secWhitening,
                   1611:                                        0,
                   1612:                                        cipher);
                   1613:                        }
1.1.1.13  root     1614:                        buf += ENCRYPTION_DATA_UNIT_SIZE;
                   1615:                        unitNo++;
1.1.1.5   root     1616:                }
                   1617:                break;
                   1618: 
                   1619:        case OUTER_CBC:
                   1620: 
1.1.1.8   root     1621:                /* Deprecated/legacy */
                   1622: 
1.1.1.13  root     1623:                while (nbrUnits--)
1.1.1.5   root     1624:                {
1.1.1.13  root     1625:                        InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (EAGetFirstCipher (ea)), sectorIV, iv64, secWhitening);
1.1.1.5   root     1626: 
1.1.1.13  root     1627:                        DecryptBufferCBC ((unsigned __int32 *) buf,
                   1628:                                ENCRYPTION_DATA_UNIT_SIZE,
1.1.1.5   root     1629:                                ks,
                   1630:                                sectorIV,
                   1631:                                secWhitening,
                   1632:                                ea,
                   1633:                                0);
                   1634: 
1.1.1.13  root     1635:                        buf += ENCRYPTION_DATA_UNIT_SIZE;
                   1636:                        unitNo++;
1.1.1.5   root     1637:                }
                   1638:                break;
1.1.1.13  root     1639: #endif // #ifndef TC_NO_COMPILER_INT64
                   1640: 
                   1641:        default:                
                   1642:                // Unknown/wrong ID
                   1643:                TC_THROW_FATAL_EXCEPTION;
1.1.1.5   root     1644:        }
                   1645: }
                   1646: 
1.1.1.13  root     1647: 
                   1648: // Returns the maximum number of bytes necessary to be generated by the PBKDF2 (PKCS #5)
                   1649: int GetMaxPkcs5OutSize (void)
                   1650: {
                   1651:        int size = 32;
                   1652: 
                   1653:        size = max (size, EAGetLargestKeyForMode (XTS) * 2);    // Sizes of primary + secondary keys
                   1654: 
                   1655: #ifndef TC_WINDOWS_BOOT
                   1656:        size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (LRW));           // Deprecated/legacy
                   1657:        size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (CBC));           // Deprecated/legacy
                   1658:        size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (OUTER_CBC));     // Deprecated/legacy
                   1659:        size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (INNER_CBC));     // Deprecated/legacy
                   1660: #endif
                   1661: 
                   1662:        return size;
                   1663: }
1.1.1.14  root     1664: 
                   1665: 
                   1666: #else // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
                   1667: 
                   1668: 
                   1669: #if !defined (TC_WINDOWS_BOOT_AES) && !defined (TC_WINDOWS_BOOT_SERPENT) && !defined (TC_WINDOWS_BOOT_TWOFISH)
                   1670: #error No cipher defined
                   1671: #endif
                   1672: 
                   1673: void EncipherBlock(int cipher, void *data, void *ks)
                   1674: {
                   1675: #ifdef TC_WINDOWS_BOOT_AES
                   1676:        aes_encrypt (data, data, ks); 
                   1677: #elif defined (TC_WINDOWS_BOOT_SERPENT)
                   1678:        serpent_encrypt (data, data, ks);
                   1679: #elif defined (TC_WINDOWS_BOOT_TWOFISH)
                   1680:        twofish_encrypt (ks, data, data);
                   1681: #endif
                   1682: }
                   1683: 
                   1684: void DecipherBlock(int cipher, void *data, void *ks)
                   1685: {
                   1686: #ifdef TC_WINDOWS_BOOT_AES
                   1687:        aes_decrypt (data, data, (aes_decrypt_ctx *) ((byte *) ks + sizeof(aes_encrypt_ctx))); 
                   1688: #elif defined (TC_WINDOWS_BOOT_SERPENT)
                   1689:        serpent_decrypt (data, data, ks);
                   1690: #elif defined (TC_WINDOWS_BOOT_TWOFISH)
                   1691:        twofish_decrypt (ks, data, data);
                   1692: #endif
                   1693: }
                   1694: 
                   1695: int EAGetFirst ()
                   1696: {
                   1697:        return 1;
                   1698: }
                   1699: 
                   1700: int EAGetNext (int previousEA)
                   1701: {
                   1702:        return 0;
                   1703: }
                   1704: 
                   1705: int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
                   1706: {
                   1707: #ifdef TC_WINDOWS_BOOT_AES
                   1708: 
                   1709:        aes_init();
                   1710: 
                   1711:        if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
                   1712:                return ERR_CIPHER_INIT_FAILURE;
                   1713:        if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS)
                   1714:                return ERR_CIPHER_INIT_FAILURE;
                   1715: 
                   1716: #elif defined (TC_WINDOWS_BOOT_SERPENT)
                   1717:        serpent_set_key (key, 32 * 8, ks);
                   1718: #elif defined (TC_WINDOWS_BOOT_TWOFISH)
                   1719:        twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, 32 * 8);
                   1720: #endif
                   1721:        return ERR_SUCCESS;
                   1722: }
                   1723: 
                   1724: int EAGetKeySize (int ea)
                   1725: {
                   1726:        return 32;
                   1727: }
                   1728: 
                   1729: int EAGetFirstCipher (int ea)
                   1730: {
                   1731:        return 1;
                   1732: }
                   1733: 
                   1734: void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
                   1735: {
                   1736:        UINT64_STRUCT dataUnitNo;
                   1737:        dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0;
                   1738:        EncryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1);
                   1739: }
                   1740: 
                   1741: void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
                   1742: {
                   1743:        EncryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1);
                   1744: }
                   1745: 
                   1746: void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
                   1747: {
                   1748:        UINT64_STRUCT dataUnitNo;
                   1749:        dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0;
                   1750:        DecryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1);
                   1751: }
                   1752: 
                   1753: void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
                   1754: {
                   1755:        DecryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1);
                   1756: }
                   1757: 
                   1758: #endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE

unix.superglobalmegacorp.com

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