|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.