|
|
1.1 ! root 1: /* ! 2: Copyright (c) 2008 TrueCrypt Foundation. All rights reserved. ! 3: ! 4: Governed by the TrueCrypt License 2.4 the full text of which is contained ! 5: in the file License.txt included in TrueCrypt binary and source code ! 6: distribution packages. ! 7: */ ! 8: ! 9: #include "EncryptionModeLRW.h" ! 10: #include "Common/GfMul.h" ! 11: ! 12: namespace TrueCrypt ! 13: { ! 14: void EncryptionModeLRW::Decrypt (byte *data, uint64 length) const ! 15: { ! 16: if_debug (ValidateState ()); ! 17: DecryptBuffer (data, length, 1); ! 18: } ! 19: ! 20: void EncryptionModeLRW::DecryptBuffer (byte *data, uint64 length, uint64 blockIndex) const ! 21: { ! 22: size_t blockSize = Ciphers.front()->GetBlockSize(); ! 23: if (blockSize != 8 && blockSize != 16) ! 24: throw ParameterIncorrect (SRC_POS); ! 25: ! 26: byte i[8]; ! 27: *(uint64 *)i = Endian::Big (blockIndex); ! 28: ! 29: byte t[Cipher::MaxBlockSize]; ! 30: ! 31: for (unsigned int b = 0; b < length / blockSize; b++) ! 32: { ! 33: if (blockSize == 8) ! 34: { ! 35: Gf64MulTab (i, t, (GfCtx *) (GfContext.Ptr())); ! 36: Xor64 ((uint64 *)data, (uint64 *)t); ! 37: } ! 38: else ! 39: { ! 40: Gf128MulBy64Tab (i, t, (GfCtx *) (GfContext.Ptr())); ! 41: Xor128 ((uint64 *)data, (uint64 *)t); ! 42: } ! 43: ! 44: for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin(); ! 45: iCipherList != Ciphers.rend(); ! 46: ++iCipherList) ! 47: { ! 48: const Cipher &c = **iCipherList; ! 49: ! 50: if (c.GetBlockSize () != blockSize) ! 51: throw ParameterIncorrect (SRC_POS); ! 52: ! 53: c.DecryptBlock (data); ! 54: } ! 55: ! 56: if (blockSize == 8) ! 57: Xor64 ((uint64 *)data, (uint64 *)t); ! 58: else ! 59: Xor128 ((uint64 *)data, (uint64 *)t); ! 60: ! 61: data += blockSize; ! 62: IncrementBlockIndex (i); ! 63: } ! 64: ! 65: Memory::Erase (t, sizeof (t)); ! 66: } ! 67: ! 68: void EncryptionModeLRW::DecryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const ! 69: { ! 70: if_debug (ValidateState ()); ! 71: if_debug (ValidateParameters (data, sectorCount, sectorSize)); ! 72: ! 73: DecryptBuffer (data, ! 74: sectorCount * sectorSize, ! 75: SectorToBlockIndex (sectorIndex)); ! 76: } ! 77: ! 78: void EncryptionModeLRW::Encrypt (byte *data, uint64 length) const ! 79: { ! 80: ValidateState (); ! 81: EncryptBuffer (data, length, 1); ! 82: } ! 83: ! 84: void EncryptionModeLRW::EncryptBuffer (byte *data, uint64 length, uint64 blockIndex) const ! 85: { ! 86: size_t blockSize = Ciphers.front()->GetBlockSize(); ! 87: if (blockSize != 8 && blockSize != 16) ! 88: throw ParameterIncorrect (SRC_POS); ! 89: ! 90: byte i[8]; ! 91: *(uint64 *)i = Endian::Big (blockIndex); ! 92: ! 93: byte t[Cipher::MaxBlockSize]; ! 94: ! 95: for (unsigned int b = 0; b < length / blockSize; b++) ! 96: { ! 97: if (blockSize == 8) ! 98: { ! 99: Gf64MulTab (i, t, (GfCtx *) (GfContext.Ptr())); ! 100: Xor64 ((uint64 *)data, (uint64 *)t); ! 101: } ! 102: else ! 103: { ! 104: Gf128MulBy64Tab (i, t, (GfCtx *) (GfContext.Ptr())); ! 105: Xor128 ((uint64 *)data, (uint64 *)t); ! 106: } ! 107: ! 108: for (CipherList::const_iterator iCipherList = Ciphers.begin(); ! 109: iCipherList != Ciphers.end(); ! 110: ++iCipherList) ! 111: { ! 112: const Cipher &c = **iCipherList; ! 113: ! 114: if (c.GetBlockSize () != blockSize) ! 115: throw ParameterIncorrect (SRC_POS); ! 116: ! 117: c.EncryptBlock (data); ! 118: } ! 119: ! 120: if (blockSize == 8) ! 121: Xor64 ((uint64 *)data, (uint64 *)t); ! 122: else ! 123: Xor128 ((uint64 *)data, (uint64 *)t); ! 124: ! 125: data += blockSize; ! 126: IncrementBlockIndex (i); ! 127: } ! 128: ! 129: Memory::Erase (t, sizeof (t)); ! 130: } ! 131: ! 132: void EncryptionModeLRW::EncryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const ! 133: { ! 134: if_debug (ValidateState ()); ! 135: if_debug (ValidateParameters (data, sectorCount, sectorSize)); ! 136: ! 137: EncryptBuffer (data, ! 138: sectorCount * sectorSize, ! 139: SectorToBlockIndex (sectorIndex)); ! 140: } ! 141: ! 142: void EncryptionModeLRW::IncrementBlockIndex (byte *index) const ! 143: { ! 144: if (index[7] != 0xff) ! 145: index[7]++; ! 146: else ! 147: *(uint64 *)index = Endian::Big ( Endian::Big (*(uint64 *)index) + 1 ); ! 148: } ! 149: ! 150: uint64 EncryptionModeLRW::SectorToBlockIndex (uint64 sectorIndex) const ! 151: { ! 152: sectorIndex -= SectorOffset; ! 153: ! 154: switch (Ciphers.front()->GetBlockSize()) ! 155: { ! 156: case 8: ! 157: return (sectorIndex << 6) | 1; ! 158: ! 159: case 16: ! 160: return (sectorIndex << 5) | 1; ! 161: ! 162: default: ! 163: throw ParameterIncorrect (SRC_POS); ! 164: } ! 165: } ! 166: ! 167: void EncryptionModeLRW::SetKey (const ConstBufferPtr &key) ! 168: { ! 169: if (key.Size() != 16) ! 170: throw ParameterIncorrect (SRC_POS); ! 171: ! 172: if (!KeySet) ! 173: GfContext.Allocate (sizeof (GfCtx)); ! 174: ! 175: if (!Gf64TabInit ((unsigned char *) key.Get(), (GfCtx *) (GfContext.Ptr()))) ! 176: throw bad_alloc(); ! 177: ! 178: if (!Gf128Tab64Init ((unsigned char *) key.Get(), (GfCtx *) (GfContext.Ptr()))) ! 179: throw bad_alloc(); ! 180: ! 181: KeySet = true; ! 182: } ! 183: ! 184: void EncryptionModeLRW::Xor64 (uint64 *a, const uint64 *b) const ! 185: { ! 186: *a ^= *b; ! 187: } ! 188: ! 189: void EncryptionModeLRW::Xor128 (uint64 *a, const uint64 *b) const ! 190: { ! 191: *a++ ^= *b++; ! 192: *a ^= *b; ! 193: } ! 194: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.