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

1.1.1.3   root        1: /* The source code contained in this file has been derived from the source code
                      2:    of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and
1.1.1.6 ! root        3:    additions to that source code contained in this file are Copyright (c) 2004-2005
1.1.1.5   root        4:    TrueCrypt Foundation and Copyright (c) 2004 TrueCrypt Team. Unmodified
1.1.1.3   root        5:    parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation
                      6:    release. Please see the file license.txt for full license details. */
1.1       root        7: 
                      8: #include "TCdefs.h"
                      9: #include "crypto.h"
                     10: #include "random.h"
1.1.1.5   root       11: #include "crc.h"
                     12: 
                     13: /* Update the following when adding a new cipher or EA:
                     14: 
                     15:    Crypto.h:
                     16:      ID #define
                     17:      MAX_EXPANDED_KEY #define
                     18: 
                     19:    Crypto.c:
                     20:      Ciphers[]
                     21:      EncryptionAlgorithms[]
                     22:      CipherInit()
                     23:      EncipherBlock()
                     24:      DecipherBlock()
                     25: */
                     26: 
                     27: // Cipher configuration
                     28: static Cipher Ciphers[] =
                     29: {
                     30: //       ID            Name                    Block size      Key size        Key schedule size
                     31:        { AES,          "AES",                  16,                     32,                     sizeof(aes_encrypt_ctx)+sizeof(aes_decrypt_ctx) },
                     32:        { BLOWFISH,     "Blowfish",             8,                      56,                     4168                                                                                    },
                     33:        { CAST,         "CAST5",                8,                      16,                     128                                                                                             },
                     34:        { DES56,        "DES",                  8,                      7,                      128                                                                                             },
                     35:        { SERPENT,      "Serpent",              16,                     32,                     140*4                                                                                   },
                     36:        { TRIPLEDES,"Triple DES",       8,                      7*3,            128*3                                                                                   },
                     37:        { TWOFISH,      "Twofish",              16,                     32,                     TWOFISH_KS                                                                              },
                     38:        { 0,            0,                              0,                      0,                      0                                                                                               }
                     39: };
                     40: 
                     41: // Encryption algorithm configuration
                     42: static EncryptionAlgorithm EncryptionAlgorithms[] =
                     43: {
                     44:        //  Cipher(s)                     Mode
                     45:        { { 0,                                          0 } , 0                 },      // (must be null)
                     46:        { { AES,                                        0 } , CBC               },      // AES
                     47:        { { BLOWFISH,                           0 } , CBC               },      // Blowfish
                     48:        { { CAST,                                       0 } , CBC               },      // CAST5
                     49:        { { SERPENT,                            0 } , CBC               },      // Serpent
                     50:        { { TRIPLEDES,                          0 } , CBC               },      // Triple DES
                     51:        { { TWOFISH,                            0 } , CBC               },      // Twofish
                     52:        { { BLOWFISH, AES,                      0 } , INNER_CBC },      // AES-Blowfish
                     53:        { { SERPENT, BLOWFISH, AES,     0 } , INNER_CBC },      // AES-Blowfish-Serpent
                     54:        { { TWOFISH, AES,                       0 } , OUTER_CBC },      // AES-Twofish
                     55:        { { SERPENT, TWOFISH, AES,      0 } , OUTER_CBC },      // AES-Twofish-Serpent
                     56:        { { AES, SERPENT,                       0 } , OUTER_CBC },      // Serpent-AES
                     57:        { { AES, TWOFISH, SERPENT,      0 } , OUTER_CBC },      // Serpent-Twofish-AES
                     58:        { { SERPENT, TWOFISH,           0 } , OUTER_CBC },      // Twofish-Serpent
                     59:        { { 0,                                          0 } , 0                 }       // (must be null)
                     60: };
                     61: 
                     62: 
                     63: void CipherInit (int cipher, unsigned char *key, unsigned char *ks)
                     64: {
                     65:        switch (cipher)
                     66:        {
                     67:        case BLOWFISH:
                     68:                BF_set_key ((BF_KEY *)ks, CipherGetKeySize(BLOWFISH), key);
                     69:                break;
                     70: 
                     71:        case AES:
                     72:                aes_encrypt_key(key, CipherGetKeySize(AES), (aes_encrypt_ctx *) ks);
                     73:                aes_decrypt_key(key, CipherGetKeySize(AES), (aes_decrypt_ctx *) (ks + sizeof(aes_encrypt_ctx)));
                     74:                break;
                     75: 
                     76:        case DES56:
                     77:                des_key_sched ((des_cblock *) key, (struct des_ks_struct *) ks);
                     78:                break;
                     79: 
                     80:        case CAST:
                     81:                CAST_set_key((CAST_KEY *) ks, CipherGetKeySize(CAST), key);
                     82:                break;
                     83: 
                     84:        case SERPENT:
                     85:                serpent_set_key (key, CipherGetKeySize(SERPENT) * 8, ks);
                     86:                break;
                     87: 
                     88:        case TRIPLEDES:
                     89:                des_key_sched ((des_cblock *) key, (struct des_ks_struct *) ks);
                     90:                des_key_sched ((des_cblock *) ((char*)(key)+8), (struct des_ks_struct *) (ks + CipherGetKeyScheduleSize (DES56)));
                     91:                des_key_sched ((des_cblock *) ((char*)(key)+16), (struct des_ks_struct *) (ks + CipherGetKeyScheduleSize (DES56) * 2));
                     92:                break;
                     93: 
                     94:        case TWOFISH:
                     95:                twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, CipherGetKeySize(TWOFISH) * 8);
                     96:                break;
                     97: 
                     98:        }
                     99: }
                    100: 
                    101: void EncipherBlock(int cipher, void *data, void *ks)
                    102: {
                    103:        switch (cipher)
                    104:        {
                    105:        case BLOWFISH:          BF_encrypt (data, ks); break;
                    106:        case AES:                       aes_encrypt (data, data, ks); break;
                    107:        case DES56:                     des_encrypt (data, ks, 1); break;
                    108:        case CAST:                      CAST_ecb_encrypt (data, data, ks, 1); break;
                    109:        case SERPENT:           serpent_encrypt (data, data, ks); break;
                    110:        case TRIPLEDES:         des_ecb3_encrypt (data, data, ks,
                    111:                                                (void*)((char*) ks + CipherGetKeyScheduleSize (DES56)), (void*)((char*) ks + CipherGetKeyScheduleSize (DES56) * 2), 1); break;
                    112:        case TWOFISH:           twofish_encrypt (ks, data, data); break;
                    113:        }
                    114: }
                    115: 
                    116: void DecipherBlock(int cipher, void *data, void *ks)
                    117: {
                    118:        switch (cipher)
                    119:        {
                    120:        case BLOWFISH:  BF_decrypt (data, ks); break;
                    121:        case AES:               aes_decrypt (data, data, (void *) ((char *) ks + sizeof(aes_encrypt_ctx))); break;
                    122:        case DES56:             des_encrypt (data, ks, 0); break;
                    123:        case CAST:              CAST_ecb_encrypt (data, data, ks,0); break;
                    124:        case SERPENT:   serpent_decrypt (data, data, ks); break;
                    125:        case TRIPLEDES: des_ecb3_encrypt (data, data, ks,
                    126:                                        (void*)((char*) ks + CipherGetKeyScheduleSize (DES56)),
                    127:                                        (void*)((char*) ks + CipherGetKeyScheduleSize (DES56) * 2), 0); break;
                    128:        case TWOFISH:   twofish_decrypt (ks, data, data); break;
                    129:        }
                    130: }
                    131: 
                    132: // Ciphers support
                    133: 
                    134: Cipher *CipherGet (int id)
                    135: {
                    136:        int i;
                    137:        for (i = 0; Ciphers[i].Id != 0; i++)
                    138:                if (Ciphers[i].Id == id)
                    139:                        return &Ciphers[i];
                    140: 
                    141:        return 0;
                    142: }
                    143: 
                    144: char *CipherGetName (int cipherId)
                    145: {
                    146:        return CipherGet (cipherId) -> Name;
                    147: }
                    148: 
                    149: int CipherGetBlockSize (int cipherId)
                    150: {
                    151:        return CipherGet (cipherId) -> BlockSize;
                    152: }
                    153: 
                    154: int CipherGetKeySize (int cipherId)
                    155: {
                    156:        return CipherGet (cipherId) -> KeySize;
                    157: }
                    158: 
                    159: int CipherGetKeyScheduleSize (int cipherId)
                    160: {
                    161:        return CipherGet (cipherId) -> KeyScheduleSize;
                    162: }
                    163: 
                    164: 
                    165: // Encryption algorithms support
                    166: 
                    167: int EAGetFirst ()
                    168: {
                    169:        return 1;
                    170: }
                    171: 
                    172: // Returns number of EAs
                    173: int EAGetCount (void)
                    174: {
                    175:        int ea, count = 0;
                    176: 
                    177:        for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
                    178:        {
                    179:                count++;
                    180:        }
                    181:        return count;
                    182: }
                    183: 
                    184: int EAGetNext (int previousEA)
                    185: {
                    186:        int id = previousEA + 1;
                    187:        if (EncryptionAlgorithms[id].Ciphers[0] != 0) return id;
                    188:        return 0;
                    189: }
                    190: 
                    191: void EAInit (int ea, unsigned char *key, unsigned char *ks)
                    192: {
                    193:        int i = 0, c;
                    194: 
                    195:        for (c = EAGetFirstCipher (ea); c != 0; c = EAGetNextCipher (ea, c))
                    196:        {
                    197:                CipherInit (c, key, ks);
                    198: 
                    199:                key += CipherGetKeySize (c);
                    200:                ks += CipherGetKeyScheduleSize (c);
                    201:        }
                    202: }
                    203: 
                    204: // Returns name of EA, cascaded cipher names are separated by hyphens
                    205: char *EAGetName (char *buf, int ea)
                    206: {
                    207:        int i = EAGetLastCipher(ea);
                    208:        strcpy (buf, CipherGetName (i));
                    209: 
                    210:        while (i = EAGetPreviousCipher(ea, i))
                    211:        {
                    212:                strcat (buf, "-");
                    213:                strcat (buf, CipherGetName (i));
                    214:        }
                    215: 
                    216:        return buf;
                    217: }
                    218: 
                    219: // Returns sum of key sizes of all EA ciphers
                    220: int EAGetKeySize (int ea)
                    221: {
                    222:        int i = EAGetFirstCipher(ea);
                    223:        int size = CipherGetKeySize (i);
                    224: 
                    225:        while (i = EAGetNextCipher(ea, i))
                    226:        {
                    227:                size += CipherGetKeySize (i);
                    228:        }
                    229: 
                    230:        return size;
                    231: }
                    232: 
                    233: // Returns the mode of operation of the whole EA
                    234: int EAGetMode (int ea)
                    235: {
                    236:        return (EncryptionAlgorithms[ea].Mode);
                    237: }
                    238: 
                    239: // Returns the name of the mode of operation of the whole EA
                    240: char *EAGetModeName (char *name, int ea, BOOL capitalLetters)
                    241: {
                    242:        char eaName[100];
                    243: 
                    244:        switch (EncryptionAlgorithms[ea].Mode)
                    245:        {
                    246:        case CBC:
                    247:                EAGetName (eaName, ea);
                    248: 
                    249:                if (strcmp (eaName, "Triple DES") == 0)
                    250:                        sprintf (name, "%s", capitalLetters ? "Outer-CBC" : "outer-CBC");
                    251:                else
                    252:                        sprintf (name, "%s", "CBC");
                    253: 
                    254:                break;
                    255: 
                    256:        case OUTER_CBC:
                    257:                strcpy (name, capitalLetters ? "Outer-CBC" : "outer-CBC");
                    258:                break;
                    259: 
                    260:        case INNER_CBC:
                    261:                strcpy (name, capitalLetters ? "Inner-CBC" : "inner-CBC");
                    262:                break;
                    263: 
                    264:        default:
                    265:                strcpy (name, "[unknown]");
                    266:                break;
                    267:        }
                    268:        return name;
                    269: }
                    270: 
                    271: // Returns sum of key schedule sizes of all EA ciphers
                    272: int EAGetKeyScheduleSize (int ea)
                    273: {
                    274:        int i = EAGetFirstCipher(ea);
                    275:        int size = CipherGetKeyScheduleSize (i);
                    276: 
                    277:        while (i = EAGetNextCipher(ea, i))
                    278:        {
                    279:                size += CipherGetKeyScheduleSize (i);
                    280:        }
                    281: 
                    282:        return size;
                    283: }
                    284: 
                    285: // Returns largest key needed by all EAs
                    286: int EAGetLargestKey ()
                    287: {
                    288:        int ea, key = 0;
                    289: 
                    290:        for (ea = EAGetFirst (); ea != 0 ; ea = EAGetNext (ea))
                    291:        {
                    292:                if (EAGetKeySize (ea) >= key)
                    293:                        key = EAGetKeySize (ea);
                    294:        }
                    295: 
                    296:        return key;
                    297: }
                    298: 
                    299: // Returns number of ciphers in EA
                    300: int EAGetCipherCount (int ea)
                    301: {
                    302:        int i = 0;
                    303:        while (EncryptionAlgorithms[ea].Ciphers[i++]);
                    304: 
                    305:        return i - 1;
                    306: }
                    307: 
                    308: 
                    309: int EAGetFirstCipher (int ea)
                    310: {
                    311:        return EncryptionAlgorithms[ea].Ciphers[0];
                    312: }
                    313: 
                    314: int EAGetLastCipher (int ea)
                    315: {
                    316:        int c, i = 0;
                    317:        while (c = EncryptionAlgorithms[ea].Ciphers[i++]);
                    318: 
                    319:        return EncryptionAlgorithms[ea].Ciphers[i - 2];
                    320: }
                    321: 
                    322: int EAGetNextCipher (int ea, int previousCipherId)
                    323: {
                    324:        int c, i = 0;
                    325:        while (c = EncryptionAlgorithms[ea].Ciphers[i++])
                    326:        {
                    327:                if (c == previousCipherId) 
                    328:                        return EncryptionAlgorithms[ea].Ciphers[i];
                    329:        }
                    330: 
                    331:        return 0;
                    332: }
                    333: 
                    334: int EAGetPreviousCipher (int ea, int previousCipherId)
                    335: {
                    336:        int c, i = 0;
                    337: 
                    338:        if (EncryptionAlgorithms[ea].Ciphers[i++] == previousCipherId)
                    339:                return 0;
                    340: 
                    341:        while (c = EncryptionAlgorithms[ea].Ciphers[i++])
                    342:        {
                    343:                if (c == previousCipherId) 
                    344:                        return EncryptionAlgorithms[ea].Ciphers[i - 2];
                    345:        }
                    346: 
                    347:        return 0;
                    348: }
                    349: 
                    350: 
                    351: // Hash support functions
                    352: 
                    353: char * get_hash_name (int pkcs5)
                    354: {
                    355:        switch (pkcs5)
                    356:        {
                    357:        case SHA1:              return "HMAC-SHA-1";
                    358:        case RIPEMD160: return "HMAC-RIPEMD-160";
                    359:        default:                return "Unknown";
                    360:        }
                    361: }
                    362: 
                    363: 
1.1       root      364: 
                    365: PCRYPTO_INFO
                    366: crypto_open ()
                    367: {
                    368:        /* Do the crt allocation */
                    369:        PCRYPTO_INFO cryptoInfo = TCalloc (sizeof (CRYPTO_INFO));
1.1.1.2   root      370: #ifndef DEVICE_DRIVER
                    371:        VirtualLock (cryptoInfo, sizeof (CRYPTO_INFO));
                    372: #endif
                    373: 
1.1       root      374:        if (cryptoInfo == NULL)
                    375:                return NULL;
                    376: 
1.1.1.5   root      377:        cryptoInfo->ea = -1;
1.1       root      378:        return cryptoInfo;
                    379: }
                    380: 
                    381: void
                    382: crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen)
                    383: {
                    384:        keyInfo->keyLength = nUserKeyLen;
                    385:        burn (keyInfo->userKey, sizeof (keyInfo->userKey));
                    386:        memcpy (keyInfo->userKey, lpszUserKey, nUserKeyLen);
                    387: }
                    388: 
                    389: void
                    390: crypto_close (PCRYPTO_INFO cryptoInfo)
                    391: {
                    392:        burn (cryptoInfo, sizeof (CRYPTO_INFO));
1.1.1.2   root      393: #ifndef DEVICE_DRIVER
                    394:        VirtualUnlock (cryptoInfo, sizeof (CRYPTO_INFO));
                    395: #endif
1.1       root      396:        TCfree (cryptoInfo);
                    397: }
                    398: 
1.1.1.5   root      399: 
                    400: // Initializes IV and whitening values for sector encryption/decryption
                    401: static void 
                    402: InitSectorIVAndWhitening (unsigned __int64 secNo,
                    403:        int blockSize,
                    404:        unsigned long *iv,
                    405:        unsigned __int64 *ivSeed,
                    406:        unsigned long *whitening)
1.1       root      407: {
1.1.1.5   root      408:        unsigned __int64 iv64[4];
                    409:        unsigned long *iv32 = (unsigned long *) iv64;
                    410: 
                    411:        iv64[0] = ivSeed[0] ^ secNo;
                    412:        iv64[1] = ivSeed[1] ^ secNo;
                    413:        iv64[2] = ivSeed[2] ^ secNo;
                    414:        if (blockSize == 16)
1.1       root      415:        {
1.1.1.5   root      416:                iv64[3] = ivSeed[3] ^ secNo;
                    417:        }
                    418: 
                    419:        iv[0] = iv32[0];
                    420:        iv[1] = iv32[1];
                    421: 
                    422:        switch (blockSize)
                    423:        {
                    424:        case 16:
                    425: 
                    426:                // 128-bit block
                    427: 
                    428:                iv[2] = iv32[2];
                    429:                iv[3] = iv32[3];
                    430: 
                    431:                whitening[0] = crc32long ( &iv32[4] ) ^ crc32long ( &iv32[7] );
                    432:                whitening[1] = crc32long ( &iv32[5] ) ^ crc32long ( &iv32[6] );
                    433:                break;
                    434: 
                    435:        case 8:
                    436: 
                    437:                // 64-bit block
                    438: 
                    439:                whitening[0] = crc32long ( &iv32[2] ) ^ crc32long ( &iv32[5] );
                    440:                whitening[1] = crc32long ( &iv32[3] ) ^ crc32long ( &iv32[4] );
                    441:                break;
1.1       root      442:        }
                    443: }
                    444: 
1.1.1.5   root      445: 
                    446: // EncryptBufferCBC
                    447: //
                    448: // data:               data to be encrypted
                    449: // len:                        number of bytes to encrypt (must be divisible by the largest cipher block size)
                    450: // ks:                 scheduled key
                    451: // iv:                 IV
                    452: // whitening:  whitening constants
                    453: // ea:                 outer-CBC cascade ID (0 = CBC/inner-CBC)
                    454: // cipher:             CBC/inner-CBC cipher ID (0 = outer-CBC)
                    455: 
                    456: static void
                    457: EncryptBufferCBC (unsigned long *data, 
                    458:                 unsigned __int64 len,
                    459:                 unsigned char *ks,
                    460:                 unsigned long *iv,
                    461:                 unsigned long *whitening,
                    462:                 int ea,
                    463:                 int cipher)
1.1       root      464: {
1.1.1.5   root      465:        unsigned long bufIV[4];
                    466:        unsigned __int64 i;
                    467:        int blockSize = CipherGetBlockSize (ea != 0 ? EAGetFirstCipher (ea) : cipher);
                    468: 
                    469:        //  IV
                    470:        bufIV[0] = iv[0];
                    471:        bufIV[1] = iv[1];
                    472:        if (blockSize == 16)
                    473:        {
                    474:                bufIV[2] = iv[2];
                    475:                bufIV[3] = iv[3];
                    476:        }
                    477: 
                    478:        // Encrypt each block
                    479:        for (i = 0; i < len/blockSize; i++)
                    480:        {
                    481:                // CBC
                    482:                data[0] ^= bufIV[0];
                    483:                data[1] ^= bufIV[1];
                    484:                if (blockSize == 16)
                    485:                {
                    486:                        data[2] ^= bufIV[2];
                    487:                        data[3] ^= bufIV[3];
                    488:                }
                    489: 
                    490:                if (ea != 0)
                    491:                {
                    492:                        // Outer-CBC
                    493:                        for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
                    494:                        {
                    495:                                EncipherBlock (cipher, data, ks);
                    496:                                ks += CipherGetKeyScheduleSize (cipher);
                    497:                        }
                    498:                        ks -= EAGetKeyScheduleSize (ea);
                    499:                }
                    500:                else
                    501:                {
                    502:                        // CBC/inner-CBC
                    503:                        EncipherBlock (cipher, data, ks);
                    504:                }
                    505: 
                    506:                // CBC
                    507:                bufIV[0] = data[0];
                    508:                bufIV[1] = data[1];
                    509:                if (blockSize == 16)
                    510:                {
                    511:                        bufIV[2] = data[2];
                    512:                        bufIV[3] = data[3];
                    513:                }
                    514: 
                    515:                // Whitening
                    516:                data[0] ^= whitening[0];
                    517:                data[1] ^= whitening[1];
                    518:                if (blockSize == 16)
                    519:                {
                    520:                        data[2] ^= whitening[0];
                    521:                        data[3] ^= whitening[1];
                    522:                }
                    523: 
                    524:                data += blockSize / sizeof(data);
                    525:        }
1.1       root      526: }
                    527: 
1.1.1.5   root      528: 
                    529: // DecryptBufferCBC
                    530: //
                    531: // data:               data to be decrypted
                    532: // len:                        number of bytes to decrypt (must be divisible by the largest cipher block size)
                    533: // ks:                 scheduled key
                    534: // iv:                 IV
                    535: // whitening:  whitening constants
                    536: // ea:                 outer-CBC cascade ID (0 = CBC/inner-CBC)
                    537: // cipher:             CBC/inner-CBC cipher ID (0 = outer-CBC)
                    538: 
                    539: static void
                    540: DecryptBufferCBC (unsigned long *data,
                    541:                 unsigned __int64 len,
                    542:                 unsigned char *ks,
                    543:                 unsigned long *iv,
                    544:                 unsigned long *whitening,
                    545:                 int ea,
                    546:                 int cipher)
1.1       root      547: {
1.1.1.5   root      548:        unsigned long bufIV[4];
                    549:        unsigned __int64 i;
                    550:        unsigned long ct[4];
                    551:        int blockSize = CipherGetBlockSize (ea != 0 ? EAGetFirstCipher (ea) : cipher);
                    552: 
                    553:        //  IV
                    554:        bufIV[0] = iv[0];
                    555:        bufIV[1] = iv[1];
                    556:        if (blockSize == 16)
1.1       root      557:        {
1.1.1.5   root      558:                bufIV[2] = iv[2];
                    559:                bufIV[3] = iv[3];
                    560:        }
                    561: 
                    562:        // Decrypt each block
                    563:        for (i = 0; i < len/blockSize; i++)
                    564:        {
                    565:                // Dewhitening
                    566:                data[0] ^= whitening[0];
                    567:                data[1] ^= whitening[1];
                    568:                if (blockSize == 16)
                    569:                {
                    570:                        data[2] ^= whitening[0];
                    571:                        data[3] ^= whitening[1];
                    572:                }
                    573: 
                    574:                // CBC
                    575:                ct[0] = data[0];
                    576:                ct[1] = data[1];
                    577:                if (blockSize == 16)
                    578:                {
                    579:                        ct[2] = data[2];
                    580:                        ct[3] = data[3];
                    581:                }
                    582: 
                    583:                if (ea != 0)
                    584:                {
                    585:                        // Outer-CBC
                    586:                        ks += EAGetKeyScheduleSize (ea);
                    587:                        for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
                    588:                        {
                    589:                                ks -= CipherGetKeyScheduleSize (cipher);
                    590:                                DecipherBlock (cipher, data, ks);
                    591:                        }
                    592:                }
                    593:                else
                    594:                {
                    595:                        // CBC/inner-CBC
                    596:                        DecipherBlock (cipher, data, ks);
                    597:                }
                    598: 
                    599:                // CBC
                    600:                data[0] ^= bufIV[0];
                    601:                data[1] ^= bufIV[1];
                    602:                bufIV[0] = ct[0];
                    603:                bufIV[1] = ct[1];
                    604:                if (blockSize == 16)
                    605:                {
                    606:                        data[2] ^= bufIV[2];
                    607:                        data[3] ^= bufIV[3];
                    608:                        bufIV[2] = ct[2];
                    609:                        bufIV[3] = ct[3];
                    610:                }
                    611: 
                    612:                data += blockSize / sizeof(data);
1.1       root      613:        }
                    614: }
1.1.1.5   root      615: 
                    616: 
                    617: // EncryptBuffer
                    618: //
                    619: // buf:                        data to be encrypted
                    620: // len:                        number of bytes to encrypt; must be divisible by the block size (for cascaded
                    621: //              ciphers divisible by the largest block size used within the cascade)
                    622: // ks:                 scheduled key
                    623: // iv:                 IV
                    624: // whitening:  whitening constants
                    625: // ea:                 encryption algorithm
                    626: 
                    627: void 
                    628: EncryptBuffer (unsigned long *buf,
                    629:                           unsigned __int64 len,
                    630:                           unsigned char *ks,
                    631:                           void *iv,
                    632:                           void *whitening,
                    633:                           int ea)
                    634: {
                    635:        unsigned __int64 *iv64 = (unsigned __int64 *) iv;
                    636:        int cipher;
                    637: 
                    638:        switch (EAGetMode(ea))
                    639:        {
                    640:        case CBC:
                    641:        case INNER_CBC:
                    642: 
                    643:                for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
                    644:                {
                    645:                        EncryptBufferCBC (buf,
                    646:                                len,
                    647:                                ks,
                    648:                                (unsigned long *) iv,
                    649:                                (unsigned long *) whitening,
                    650:                                0,
                    651:                                cipher);
                    652: 
                    653:                        ks += CipherGetKeyScheduleSize (cipher);
                    654:                }
                    655: 
                    656:                break;
                    657: 
                    658:        case OUTER_CBC:
                    659: 
                    660:                EncryptBufferCBC (buf,
                    661:                        len,
                    662:                        ks,
                    663:                        (unsigned long *) iv,
                    664:                        (unsigned long *) whitening,
                    665:                        ea,
                    666:                        0);
                    667: 
                    668:                break;
                    669:        }
                    670: }
                    671: 
                    672: // EncryptSectors
                    673: //
                    674: // buf:                        data to be encrypted
                    675: // secNo:              sector number relative to volume start
                    676: // noSectors:  number of sectors in buffer
                    677: // ks:                 scheduled key
                    678: // iv:                 IV
                    679: // ea:                 encryption algorithm
                    680: 
                    681: void _cdecl 
                    682: EncryptSectors (unsigned long *buf,
                    683:                unsigned __int64 secNo,
                    684:                unsigned __int64 noSectors,
                    685:                unsigned char *ks,
                    686:                void *iv,
                    687:                int ea)
                    688: {
                    689:        unsigned __int64 *iv64 = (unsigned __int64 *) iv;
                    690:        unsigned long sectorIV[4];
                    691:        unsigned long secWhitening[2];
                    692:        int cipher;
                    693: 
                    694:        switch (EAGetMode(ea))
                    695:        {
                    696:        case CBC:
                    697:        case INNER_CBC:
                    698: 
                    699:                while (noSectors--)
                    700:                {
                    701:                        for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
                    702:                        {
                    703:                                InitSectorIVAndWhitening (secNo, CipherGetBlockSize (cipher), sectorIV, iv64, secWhitening);
                    704: 
                    705:                                EncryptBufferCBC (buf,
                    706:                                        SECTOR_SIZE,
                    707:                                        ks,
                    708:                                        sectorIV,
                    709:                                        secWhitening,
                    710:                                        0,
                    711:                                        cipher);
                    712: 
                    713:                                ks += CipherGetKeyScheduleSize (cipher);
                    714:                        }
                    715:                        ks -= EAGetKeyScheduleSize (ea);
                    716:                        buf += SECTOR_SIZE / sizeof(buf);
                    717:                        secNo++;
                    718:                }
                    719:                break;
                    720: 
                    721:        case OUTER_CBC:
                    722: 
                    723:                while (noSectors--)
                    724:                {
                    725:                        InitSectorIVAndWhitening (secNo, CipherGetBlockSize (EAGetFirstCipher (ea)), sectorIV, iv64, secWhitening);
                    726: 
                    727:                        EncryptBufferCBC (buf,
                    728:                                SECTOR_SIZE,
                    729:                                ks,
                    730:                                sectorIV,
                    731:                                secWhitening,
                    732:                                ea,
                    733:                                0);
                    734: 
                    735:                        buf += SECTOR_SIZE / sizeof(buf);
                    736:                        secNo++;
                    737:                }
                    738:                break;
                    739:        }
                    740: }
                    741: 
                    742: // DecryptBuffer
                    743: //
                    744: // buf:                        data to be decrypted
                    745: // len:                        number of bytes to decrypt; must be divisible by the block size (for cascaded
                    746: //              ciphers divisible by the largest block size used within the cascade)
                    747: // ks:                 scheduled key
                    748: // iv:                 IV
                    749: // whitening:  whitening constants
                    750: // ea:                 encryption algorithm
                    751: void 
                    752: DecryptBuffer (unsigned long *buf,
                    753:                unsigned __int64 len,
                    754:                unsigned char *ks,
                    755:                void *iv,
                    756:                void *whitening,
                    757:                int ea)
                    758: {
                    759:        unsigned __int64 *iv64 = (unsigned __int64 *) iv;
                    760:        int cipher;
                    761: 
                    762:        switch (EAGetMode(ea))
                    763:        {
                    764:        case CBC:
                    765:        case INNER_CBC:
                    766: 
                    767:                ks += EAGetKeyScheduleSize (ea);
                    768:                for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
                    769:                {
                    770:                        ks -= CipherGetKeyScheduleSize (cipher);
                    771: 
                    772:                        DecryptBufferCBC (buf,
                    773:                                len,
                    774:                                ks,
                    775:                                (unsigned long *) iv,
                    776:                                (unsigned long *) whitening,
                    777:                                0,
                    778:                                cipher);
                    779:                }
                    780:                break;
                    781: 
                    782:        case OUTER_CBC:
                    783: 
                    784:                DecryptBufferCBC (buf,
                    785:                        len,
                    786:                        ks,
                    787:                        (unsigned long *) iv,
                    788:                        (unsigned long *) whitening,
                    789:                        ea,
                    790:                        0);
                    791: 
                    792:                break;
                    793:        }
                    794: }
                    795: 
                    796: // DecryptSectors
                    797: //
                    798: // buf:                        data to be decrypted
                    799: // secNo:              sector number relative to volume start
                    800: // noSectors:  number of sectors in buffer
                    801: // ks:                 scheduled key
                    802: // iv:                 IV
                    803: // ea:                 encryption algorithm
                    804: 
                    805: void _cdecl 
                    806: DecryptSectors (unsigned long *buf,
                    807:                unsigned __int64 secNo,
                    808:                unsigned __int64 noSectors,
                    809:                unsigned char *ks,
                    810:                void *iv,
                    811:                int ea)
                    812: {
                    813:        unsigned __int64 *iv64 = (unsigned __int64 *) iv;
                    814:        unsigned long sectorIV[4];
                    815:        unsigned long secWhitening[2];
                    816:        int cipher;
                    817: 
                    818:        switch (EAGetMode(ea))
                    819:        {
                    820:        case CBC:
                    821:        case INNER_CBC:
                    822: 
                    823:                while (noSectors--)
                    824:                {
                    825:                        ks += EAGetKeyScheduleSize (ea);
                    826:                        for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
                    827:                        {
                    828:                                InitSectorIVAndWhitening (secNo, CipherGetBlockSize (cipher), sectorIV, iv64, secWhitening);
                    829: 
                    830:                                ks -= CipherGetKeyScheduleSize (cipher);
                    831: 
                    832:                                DecryptBufferCBC (buf,
                    833:                                        SECTOR_SIZE,
                    834:                                        ks,
                    835:                                        sectorIV,
                    836:                                        secWhitening,
                    837:                                        0,
                    838:                                        cipher);
                    839:                        }
                    840:                        buf += SECTOR_SIZE / sizeof(buf);
                    841:                        secNo++;
                    842:                }
                    843:                break;
                    844: 
                    845:        case OUTER_CBC:
                    846: 
                    847:                while (noSectors--)
                    848:                {
                    849:                        InitSectorIVAndWhitening (secNo, CipherGetBlockSize (EAGetFirstCipher (ea)), sectorIV, iv64, secWhitening);
                    850: 
                    851:                        DecryptBufferCBC (buf,
                    852:                                SECTOR_SIZE,
                    853:                                ks,
                    854:                                sectorIV,
                    855:                                secWhitening,
                    856:                                ea,
                    857:                                0);
                    858: 
                    859:                        buf += SECTOR_SIZE / sizeof(buf);
                    860:                        secNo++;
                    861:                }
                    862:                break;
                    863:        }
                    864: }
                    865: 

unix.superglobalmegacorp.com

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