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

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
                      3:    additions to that source code contained in this file are Copyright (c) 2004
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.