|
|
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.