|
|
1.1 root 1: /* 1.1.1.7 ! root 2: Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. 1.1 root 3: 1.1.1.7 ! root 4: Governed by the TrueCrypt License 2.8 the full text of which is contained in ! 5: the file License.txt included in TrueCrypt binary and source code distribution ! 6: packages. 1.1 root 7: */ 8: 1.1.1.3 root 9: /* If native 64-bit data types are not available, define TC_NO_COMPILER_INT64. 1.1 root 10: 1.1.1.3 root 11: For big-endian platforms define BYTE_ORDER as BIG_ENDIAN. */ 1.1 root 12: 13: 14: #ifdef TC_MINIMIZE_CODE_SIZE 1.1.1.3 root 15: // Preboot/boot version 16: # ifndef TC_NO_COMPILER_INT64 17: # define TC_NO_COMPILER_INT64 1.1 root 18: # endif 1.1.1.3 root 19: # pragma optimize ("tl", on) 1.1 root 20: #endif 21: 1.1.1.6 root 22: #ifdef TC_NO_COMPILER_INT64 23: # include <memory.h> 24: #endif 1.1 root 25: 26: #include "Xts.h" 27: 28: 1.1.1.3 root 29: #ifndef TC_NO_COMPILER_INT64 1.1 root 30: 31: // length: number of bytes to encrypt; may be larger than one data unit and must be divisible by the cipher block size 32: // ks: the primary key schedule 33: // ks2: the secondary key schedule 34: // startDataUnitNo: The sequential number of the data unit with which the buffer starts. 35: // startCipherBlockNo: The sequential number of the first plaintext block to encrypt inside the data unit startDataUnitNo. 36: // When encrypting the data unit from its first block, startCipherBlockNo is 0. 37: // The startCipherBlockNo value applies only to the first data unit in the buffer; each successive 38: // data unit is encrypted from its first block. The start of the buffer does not have to be 39: // aligned with the start of a data unit. If it is aligned, startCipherBlockNo must be 0; if it 40: // is not aligned, startCipherBlockNo must reflect the misalignment accordingly. 41: void EncryptBufferXTS (unsigned __int8 *buffer, 42: TC_LARGEST_COMPILER_UINT length, 43: const UINT64_STRUCT *startDataUnitNo, 44: unsigned int startCipherBlockNo, 45: unsigned __int8 *ks, 46: unsigned __int8 *ks2, 47: int cipher) 48: { 49: unsigned __int8 finalCarry; 50: unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK]; 51: unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK]; 52: unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue; 53: unsigned __int64 *bufPtr = (unsigned __int64 *) buffer; 54: unsigned int startBlock = startCipherBlockNo, endBlock, block; 55: TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo; 56: 57: /* The encrypted data unit number (i.e. the resultant ciphertext block) is to be multiplied in the 58: finite field GF(2^128) by j-th power of n, where j is the sequential plaintext/ciphertext block 59: number and n is 2, a primitive element of GF(2^128). This can be (and is) simplified and implemented 60: as a left shift of the preceding whitening value by one bit (with carry propagating). In addition, if 61: the shift of the highest byte results in a carry, 135 is XORed into the lowest byte. The value 135 is 62: derived from the modulus of the Galois Field (x^128+x^7+x^2+x+1). */ 63: 64: // Convert the 64-bit data unit number into a little-endian 16-byte array. 65: // Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes. 66: dataUnitNo = startDataUnitNo->Value; 67: *((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo); 68: *((unsigned __int64 *) byteBufUnitNo + 1) = 0; 69: 70: if (length % BYTES_PER_XTS_BLOCK) 71: TC_THROW_FATAL_EXCEPTION; 72: 73: blockCount = length / BYTES_PER_XTS_BLOCK; 74: 75: // Process all blocks in the buffer 76: while (blockCount > 0) 77: { 78: if (blockCount < BLOCKS_PER_XTS_DATA_UNIT) 79: endBlock = startBlock + (unsigned int) blockCount; 80: else 81: endBlock = BLOCKS_PER_XTS_DATA_UNIT; 82: 83: whiteningValuePtr64 = (unsigned __int64 *) whiteningValue; 84: 85: // Encrypt the data unit number using the secondary key (in order to generate the first 86: // whitening value for this data unit) 87: *whiteningValuePtr64 = *((unsigned __int64 *) byteBufUnitNo); 88: *(whiteningValuePtr64 + 1) = 0; 89: EncipherBlock (cipher, whiteningValue, ks2); 90: 1.1.1.3 root 91: // Generate (and apply) subsequent whitening values for blocks in this data unit and 92: // encrypt all relevant blocks in this data unit 1.1 root 93: for (block = 0; block < endBlock; block++) 94: { 95: if (block >= startBlock) 96: { 1.1.1.3 root 97: // Pre-whitening 98: *bufPtr++ ^= *whiteningValuePtr64++; 99: *bufPtr-- ^= *whiteningValuePtr64--; 100: 101: // Actual encryption 102: EncipherBlock (cipher, bufPtr, ks); 103: 104: // Post-whitening 105: *bufPtr++ ^= *whiteningValuePtr64++; 106: *bufPtr++ ^= *whiteningValuePtr64; 1.1 root 107: } 108: else 109: whiteningValuePtr64++; 110: 111: // Derive the next whitening value 112: 113: #if BYTE_ORDER == LITTLE_ENDIAN 114: 1.1.1.3 root 115: // Little-endian platforms 1.1 root 116: 117: finalCarry = 118: (*whiteningValuePtr64 & 0x8000000000000000) ? 119: 135 : 0; 120: 121: *whiteningValuePtr64-- <<= 1; 122: 123: if (*whiteningValuePtr64 & 0x8000000000000000) 124: *(whiteningValuePtr64 + 1) |= 1; 125: 126: *whiteningValuePtr64 <<= 1; 127: #else 1.1.1.3 root 128: 129: // Big-endian platforms 1.1 root 130: 131: finalCarry = 132: (*whiteningValuePtr64 & 0x80) ? 133: 135 : 0; 134: 135: *whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1); 136: 137: whiteningValuePtr64--; 138: 139: if (*whiteningValuePtr64 & 0x80) 140: *(whiteningValuePtr64 + 1) |= 0x0100000000000000; 141: 142: *whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1); 143: #endif 144: 145: whiteningValue[0] ^= finalCarry; 146: } 147: 1.1.1.3 root 148: blockCount -= endBlock - startBlock; 1.1 root 149: startBlock = 0; 150: dataUnitNo++; 151: *((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo); 152: } 153: 1.1.1.3 root 154: FAST_ERASE64 (whiteningValue, sizeof (whiteningValue)); 1.1 root 155: } 156: 157: 158: // For descriptions of the input parameters, see EncryptBufferXTS(). 159: void DecryptBufferXTS (unsigned __int8 *buffer, 160: TC_LARGEST_COMPILER_UINT length, 161: const UINT64_STRUCT *startDataUnitNo, 162: unsigned int startCipherBlockNo, 163: unsigned __int8 *ks, 164: unsigned __int8 *ks2, 165: int cipher) 166: { 167: unsigned __int8 finalCarry; 168: unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK]; 169: unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK]; 170: unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue; 171: unsigned __int64 *bufPtr = (unsigned __int64 *) buffer; 172: unsigned int startBlock = startCipherBlockNo, endBlock, block; 173: TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo; 1.1.1.3 root 174: 1.1 root 175: // Convert the 64-bit data unit number into a little-endian 16-byte array. 176: // Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes. 177: dataUnitNo = startDataUnitNo->Value; 178: *((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo); 179: *((unsigned __int64 *) byteBufUnitNo + 1) = 0; 180: 181: if (length % BYTES_PER_XTS_BLOCK) 182: TC_THROW_FATAL_EXCEPTION; 183: 184: blockCount = length / BYTES_PER_XTS_BLOCK; 185: 186: // Process all blocks in the buffer 187: while (blockCount > 0) 188: { 189: if (blockCount < BLOCKS_PER_XTS_DATA_UNIT) 190: endBlock = startBlock + (unsigned int) blockCount; 191: else 192: endBlock = BLOCKS_PER_XTS_DATA_UNIT; 193: 194: whiteningValuePtr64 = (unsigned __int64 *) whiteningValue; 195: 196: // Encrypt the data unit number using the secondary key (in order to generate the first 197: // whitening value for this data unit) 198: *whiteningValuePtr64 = *((unsigned __int64 *) byteBufUnitNo); 199: *(whiteningValuePtr64 + 1) = 0; 200: EncipherBlock (cipher, whiteningValue, ks2); 201: 1.1.1.3 root 202: // Generate (and apply) subsequent whitening values for blocks in this data unit and 203: // decrypt all relevant blocks in this data unit 1.1 root 204: for (block = 0; block < endBlock; block++) 205: { 206: if (block >= startBlock) 207: { 1.1.1.3 root 208: // Post-whitening 209: *bufPtr++ ^= *whiteningValuePtr64++; 210: *bufPtr-- ^= *whiteningValuePtr64--; 211: 212: // Actual decryption 213: DecipherBlock (cipher, bufPtr, ks); 214: 215: // Pre-whitening 216: *bufPtr++ ^= *whiteningValuePtr64++; 217: *bufPtr++ ^= *whiteningValuePtr64; 1.1 root 218: } 219: else 220: whiteningValuePtr64++; 221: 222: // Derive the next whitening value 223: 224: #if BYTE_ORDER == LITTLE_ENDIAN 225: 1.1.1.3 root 226: // Little-endian platforms 1.1 root 227: 228: finalCarry = 229: (*whiteningValuePtr64 & 0x8000000000000000) ? 230: 135 : 0; 231: 232: *whiteningValuePtr64-- <<= 1; 233: 234: if (*whiteningValuePtr64 & 0x8000000000000000) 235: *(whiteningValuePtr64 + 1) |= 1; 236: 237: *whiteningValuePtr64 <<= 1; 238: 239: #else 1.1.1.3 root 240: // Big-endian platforms 1.1 root 241: 242: finalCarry = 243: (*whiteningValuePtr64 & 0x80) ? 244: 135 : 0; 245: 246: *whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1); 247: 248: whiteningValuePtr64--; 249: 250: if (*whiteningValuePtr64 & 0x80) 251: *(whiteningValuePtr64 + 1) |= 0x0100000000000000; 252: 253: *whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1); 254: #endif 255: 256: whiteningValue[0] ^= finalCarry; 257: } 258: 1.1.1.3 root 259: blockCount -= endBlock - startBlock; 1.1 root 260: startBlock = 0; 261: dataUnitNo++; 262: *((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo); 263: } 264: 1.1.1.3 root 265: FAST_ERASE64 (whiteningValue, sizeof (whiteningValue)); 1.1 root 266: } 267: 268: 269: 1.1.1.3 root 270: #else // TC_NO_COMPILER_INT64 1.1 root 271: 1.1.1.3 root 272: /* ---- The following code is to be used only when native 64-bit data types are not available. ---- */ 1.1 root 273: 274: #if BYTE_ORDER == BIG_ENDIAN 1.1.1.3 root 275: #error The TC_NO_COMPILER_INT64 version of the XTS code is not compatible with big-endian platforms 1.1 root 276: #endif 277: 278: 279: // Converts a 64-bit unsigned integer (passed as two 32-bit integers for compatibility with non-64-bit 280: // environments/platforms) into a little-endian 16-byte array. 281: static void Uint64ToLE16ByteArray (unsigned __int8 *byteBuf, unsigned __int32 highInt32, unsigned __int32 lowInt32) 282: { 283: unsigned __int32 *bufPtr32 = (unsigned __int32 *) byteBuf; 284: 285: *bufPtr32++ = lowInt32; 286: *bufPtr32++ = highInt32; 287: 288: // We're converting a 64-bit number into a little-endian 16-byte array so we can zero the last 8 bytes 289: *bufPtr32++ = 0; 290: *bufPtr32 = 0; 291: } 292: 293: 1.1.1.3 root 294: // Encrypts or decrypts all blocks in the buffer in XTS mode. For descriptions of the input parameters, 295: // see the 64-bit version of EncryptBufferXTS(). 296: static void EncryptDecryptBufferXTS32 (const unsigned __int8 *buffer, 1.1 root 297: TC_LARGEST_COMPILER_UINT length, 298: const UINT64_STRUCT *startDataUnitNo, 299: unsigned int startBlock, 1.1.1.3 root 300: unsigned __int8 *ks, 1.1 root 301: unsigned __int8 *ks2, 1.1.1.3 root 302: int cipher, 303: BOOL decryption) 1.1 root 304: { 305: TC_LARGEST_COMPILER_UINT blockCount; 306: UINT64_STRUCT dataUnitNo; 307: unsigned int block; 308: unsigned int endBlock; 309: unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK]; 310: unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK]; 311: unsigned __int32 *bufPtr32 = (unsigned __int32 *) buffer; 312: unsigned __int32 *whiteningValuePtr32 = (unsigned __int32 *) whiteningValue; 313: unsigned __int8 finalCarry; 314: unsigned __int32 *const finalDwordWhiteningValuePtr = whiteningValuePtr32 + sizeof (whiteningValue) / sizeof (*whiteningValuePtr32) - 1; 315: 316: // Store the 64-bit data unit number in a way compatible with non-64-bit environments/platforms 317: dataUnitNo.HighPart = startDataUnitNo->HighPart; 318: dataUnitNo.LowPart = startDataUnitNo->LowPart; 319: 320: blockCount = length / BYTES_PER_XTS_BLOCK; 321: 322: // Convert the 64-bit data unit number into a little-endian 16-byte array. 323: // (Passed as two 32-bit integers for compatibility with non-64-bit environments/platforms.) 324: Uint64ToLE16ByteArray (byteBufUnitNo, dataUnitNo.HighPart, dataUnitNo.LowPart); 325: 326: // Generate whitening values for all blocks in the buffer 327: while (blockCount > 0) 328: { 329: if (blockCount < BLOCKS_PER_XTS_DATA_UNIT) 330: endBlock = startBlock + (unsigned int) blockCount; 331: else 332: endBlock = BLOCKS_PER_XTS_DATA_UNIT; 333: 334: // Encrypt the data unit number using the secondary key (in order to generate the first 335: // whitening value for this data unit) 336: memcpy (whiteningValue, byteBufUnitNo, BYTES_PER_XTS_BLOCK); 337: EncipherBlock (cipher, whiteningValue, ks2); 338: 1.1.1.3 root 339: // Generate (and apply) subsequent whitening values for blocks in this data unit and 340: // encrypt/decrypt all relevant blocks in this data unit 1.1 root 341: for (block = 0; block < endBlock; block++) 342: { 343: if (block >= startBlock) 344: { 345: whiteningValuePtr32 = (unsigned __int32 *) whiteningValue; 346: 1.1.1.3 root 347: // Whitening 1.1 root 348: *bufPtr32++ ^= *whiteningValuePtr32++; 349: *bufPtr32++ ^= *whiteningValuePtr32++; 350: *bufPtr32++ ^= *whiteningValuePtr32++; 1.1.1.3 root 351: *bufPtr32 ^= *whiteningValuePtr32; 352: 353: bufPtr32 -= BYTES_PER_XTS_BLOCK / sizeof (*bufPtr32) - 1; 354: 355: // Actual encryption/decryption 356: if (decryption) 357: DecipherBlock (cipher, bufPtr32, ks); 358: else 359: EncipherBlock (cipher, bufPtr32, ks); 360: 361: whiteningValuePtr32 = (unsigned __int32 *) whiteningValue; 1.1 root 362: 1.1.1.3 root 363: // Whitening 364: *bufPtr32++ ^= *whiteningValuePtr32++; 365: *bufPtr32++ ^= *whiteningValuePtr32++; 366: *bufPtr32++ ^= *whiteningValuePtr32++; 367: *bufPtr32++ ^= *whiteningValuePtr32; 1.1 root 368: } 369: 370: // Derive the next whitening value 371: 372: finalCarry = 0; 373: 374: for (whiteningValuePtr32 = finalDwordWhiteningValuePtr; 375: whiteningValuePtr32 >= (unsigned __int32 *) whiteningValue; 376: whiteningValuePtr32--) 377: { 378: if (*whiteningValuePtr32 & 0x80000000) // If the following shift results in a carry 379: { 380: if (whiteningValuePtr32 != finalDwordWhiteningValuePtr) // If not processing the highest double word 381: { 382: // A regular carry 383: *(whiteningValuePtr32 + 1) |= 1; 384: } 385: else 386: { 387: // The highest byte shift will result in a carry 388: finalCarry = 135; 389: } 390: } 391: 392: *whiteningValuePtr32 <<= 1; 393: } 394: 395: whiteningValue[0] ^= finalCarry; 396: } 397: 1.1.1.3 root 398: blockCount -= endBlock - startBlock; 1.1 root 399: startBlock = 0; 400: 401: // Increase the data unit number by one 1.1.1.3 root 402: if (!++dataUnitNo.LowPart) 403: { 404: dataUnitNo.HighPart++; 405: } 1.1 root 406: 407: // Convert the 64-bit data unit number into a little-endian 16-byte array. 408: Uint64ToLE16ByteArray (byteBufUnitNo, dataUnitNo.HighPart, dataUnitNo.LowPart); 409: } 410: 1.1.1.3 root 411: FAST_ERASE64 (whiteningValue, sizeof (whiteningValue)); 1.1 root 412: } 413: 414: 1.1.1.3 root 415: // For descriptions of the input parameters, see the 64-bit version of EncryptBufferXTS() above. 1.1 root 416: void EncryptBufferXTS (unsigned __int8 *buffer, 417: TC_LARGEST_COMPILER_UINT length, 1.1.1.3 root 418: const UINT64_STRUCT *startDataUnitNo, 1.1 root 419: unsigned int startCipherBlockNo, 420: unsigned __int8 *ks, 421: unsigned __int8 *ks2, 422: int cipher) 423: { 424: // Encrypt all plaintext blocks in the buffer 1.1.1.3 root 425: EncryptDecryptBufferXTS32 (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher, FALSE); 1.1 root 426: } 427: 428: 1.1.1.3 root 429: // For descriptions of the input parameters, see the 64-bit version of EncryptBufferXTS(). 1.1 root 430: void DecryptBufferXTS (unsigned __int8 *buffer, 431: TC_LARGEST_COMPILER_UINT length, 1.1.1.3 root 432: const UINT64_STRUCT *startDataUnitNo, 1.1 root 433: unsigned int startCipherBlockNo, 434: unsigned __int8 *ks, 435: unsigned __int8 *ks2, 436: int cipher) 437: { 1.1.1.3 root 438: // Decrypt all ciphertext blocks in the buffer 439: EncryptDecryptBufferXTS32 (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher, TRUE); 1.1 root 440: } 441: 1.1.1.3 root 442: #endif // TC_NO_COMPILER_INT64
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.