|
|
1.1.1.3 root 1: /* Deprecated/legacy */
1.1.1.4 root 2: // des.cpp - modified by Wei Dai from Phil Karn's des.c
3: // The original code and all modifications are in the public domain.
1.1.1.3 root 4:
1.1.1.4 root 5: /*
6: * This is a major rewrite of my old public domain DES code written
7: * circa 1987, which in turn borrowed heavily from Jim Gillogly's 1977
8: * public domain code. I pretty much kept my key scheduling code, but
9: * the actual encrypt/decrypt routines are taken from from Richard
10: * Outerbridge's DES code as printed in Schneier's "Applied Cryptography."
11: *
12: * This code is in the public domain. I would appreciate bug reports and
13: * enhancements.
14: *
15: * Phil Karn KA9Q, [email protected], August 1994.
16: */
17:
1.1.1.5 ! root 18: /* Adapted for TrueCrypt */
1.1.1.4 root 19:
20: #include <memory.h>
21: #include "Common/Tcdefs.h"
22: #include "Common/Endian.h"
1.1.1.2 root 23: #include "Des.h"
1.1 root 24:
1.1.1.4 root 25: #define word32 unsigned __int32
26: #define byte unsigned __int8
27:
28: static word32 rotlFixed (word32 x, unsigned int y)
29: {
30: return (word32)((x<<y) | (x>>(sizeof(word32)*8-y)));
31: }
32:
33: static word32 rotrFixed (word32 x, unsigned int y)
34: {
35: return (word32)((x>>y) | (x<<(sizeof(word32)*8-y)));
36: }
37:
38:
39: /* Tables defined in the Data Encryption Standard documents
40: * Three of these tables, the initial permutation, the final
41: * permutation and the expansion operator, are regular enough that
42: * for speed, we hard-code them. They're here for reference only.
43: * Also, the S and P boxes are used by a separate program, gensp.c,
44: * to build the combined SP box, Spbox[]. They're also here just
45: * for reference.
46: */
47: #ifdef notdef
48: /* initial permutation IP */
49: static byte ip[] = {
50: 58, 50, 42, 34, 26, 18, 10, 2,
51: 60, 52, 44, 36, 28, 20, 12, 4,
52: 62, 54, 46, 38, 30, 22, 14, 6,
53: 64, 56, 48, 40, 32, 24, 16, 8,
54: 57, 49, 41, 33, 25, 17, 9, 1,
55: 59, 51, 43, 35, 27, 19, 11, 3,
56: 61, 53, 45, 37, 29, 21, 13, 5,
57: 63, 55, 47, 39, 31, 23, 15, 7
58: };
59:
60: /* final permutation IP^-1 */
61: static byte fp[] = {
62: 40, 8, 48, 16, 56, 24, 64, 32,
63: 39, 7, 47, 15, 55, 23, 63, 31,
64: 38, 6, 46, 14, 54, 22, 62, 30,
65: 37, 5, 45, 13, 53, 21, 61, 29,
66: 36, 4, 44, 12, 52, 20, 60, 28,
67: 35, 3, 43, 11, 51, 19, 59, 27,
68: 34, 2, 42, 10, 50, 18, 58, 26,
69: 33, 1, 41, 9, 49, 17, 57, 25
70: };
71: /* expansion operation matrix */
72: static byte ei[] = {
73: 32, 1, 2, 3, 4, 5,
74: 4, 5, 6, 7, 8, 9,
75: 8, 9, 10, 11, 12, 13,
76: 12, 13, 14, 15, 16, 17,
77: 16, 17, 18, 19, 20, 21,
78: 20, 21, 22, 23, 24, 25,
79: 24, 25, 26, 27, 28, 29,
80: 28, 29, 30, 31, 32, 1
81: };
82: /* The (in)famous S-boxes */
83: static byte sbox[8][64] = {
84: /* S1 */
85: 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
86: 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
87: 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
88: 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
89:
90: /* S2 */
91: 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
92: 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
93: 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
94: 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
95:
96: /* S3 */
97: 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
98: 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
99: 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
100: 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
101:
102: /* S4 */
103: 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
104: 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
105: 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
106: 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
107:
108: /* S5 */
109: 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
110: 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
111: 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
112: 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
113:
114: /* S6 */
115: 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
116: 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
117: 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
118: 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
119:
120: /* S7 */
121: 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
122: 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
123: 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
124: 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
125:
126: /* S8 */
127: 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
128: 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
129: 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
130: 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
131: };
132:
133: /* 32-bit permutation function P used on the output of the S-boxes */
134: static byte p32i[] = {
135: 16, 7, 20, 21,
136: 29, 12, 28, 17,
137: 1, 15, 23, 26,
138: 5, 18, 31, 10,
139: 2, 8, 24, 14,
140: 32, 27, 3, 9,
141: 19, 13, 30, 6,
142: 22, 11, 4, 25
143: };
144: #endif
145:
146: /* permuted choice table (key) */
147: static const byte pc1[] = {
148: 57, 49, 41, 33, 25, 17, 9,
149: 1, 58, 50, 42, 34, 26, 18,
150: 10, 2, 59, 51, 43, 35, 27,
151: 19, 11, 3, 60, 52, 44, 36,
152:
153: 63, 55, 47, 39, 31, 23, 15,
154: 7, 62, 54, 46, 38, 30, 22,
155: 14, 6, 61, 53, 45, 37, 29,
156: 21, 13, 5, 28, 20, 12, 4
157: };
158:
159: /* number left rotations of pc1 */
160: static const byte totrot[] = {
161: 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
162: };
163:
164: /* permuted choice key (table) */
165: static const byte pc2[] = {
166: 14, 17, 11, 24, 1, 5,
167: 3, 28, 15, 6, 21, 10,
168: 23, 19, 12, 4, 26, 8,
169: 16, 7, 27, 20, 13, 2,
170: 41, 52, 31, 37, 47, 55,
171: 30, 40, 51, 45, 33, 48,
172: 44, 49, 39, 56, 34, 53,
173: 46, 42, 50, 36, 29, 32
174: };
175:
176: /* End of DES-defined tables */
177:
178: /* bit 0 is left-most in byte */
179: static const int bytebit[] = {
180: 0200,0100,040,020,010,04,02,01
181: };
182:
183: static const word32 Spbox[8][64] = {
184: {
185: 0x01010400,0x00000000,0x00010000,0x01010404, 0x01010004,0x00010404,0x00000004,0x00010000,
186: 0x00000400,0x01010400,0x01010404,0x00000400, 0x01000404,0x01010004,0x01000000,0x00000004,
187: 0x00000404,0x01000400,0x01000400,0x00010400, 0x00010400,0x01010000,0x01010000,0x01000404,
188: 0x00010004,0x01000004,0x01000004,0x00010004, 0x00000000,0x00000404,0x00010404,0x01000000,
189: 0x00010000,0x01010404,0x00000004,0x01010000, 0x01010400,0x01000000,0x01000000,0x00000400,
190: 0x01010004,0x00010000,0x00010400,0x01000004, 0x00000400,0x00000004,0x01000404,0x00010404,
191: 0x01010404,0x00010004,0x01010000,0x01000404, 0x01000004,0x00000404,0x00010404,0x01010400,
192: 0x00000404,0x01000400,0x01000400,0x00000000, 0x00010004,0x00010400,0x00000000,0x01010004},
193: {
194: 0x80108020,0x80008000,0x00008000,0x00108020, 0x00100000,0x00000020,0x80100020,0x80008020,
195: 0x80000020,0x80108020,0x80108000,0x80000000, 0x80008000,0x00100000,0x00000020,0x80100020,
196: 0x00108000,0x00100020,0x80008020,0x00000000, 0x80000000,0x00008000,0x00108020,0x80100000,
197: 0x00100020,0x80000020,0x00000000,0x00108000, 0x00008020,0x80108000,0x80100000,0x00008020,
198: 0x00000000,0x00108020,0x80100020,0x00100000, 0x80008020,0x80100000,0x80108000,0x00008000,
199: 0x80100000,0x80008000,0x00000020,0x80108020, 0x00108020,0x00000020,0x00008000,0x80000000,
200: 0x00008020,0x80108000,0x00100000,0x80000020, 0x00100020,0x80008020,0x80000020,0x00100020,
201: 0x00108000,0x00000000,0x80008000,0x00008020, 0x80000000,0x80100020,0x80108020,0x00108000},
202: {
203: 0x00000208,0x08020200,0x00000000,0x08020008, 0x08000200,0x00000000,0x00020208,0x08000200,
204: 0x00020008,0x08000008,0x08000008,0x00020000, 0x08020208,0x00020008,0x08020000,0x00000208,
205: 0x08000000,0x00000008,0x08020200,0x00000200, 0x00020200,0x08020000,0x08020008,0x00020208,
206: 0x08000208,0x00020200,0x00020000,0x08000208, 0x00000008,0x08020208,0x00000200,0x08000000,
207: 0x08020200,0x08000000,0x00020008,0x00000208, 0x00020000,0x08020200,0x08000200,0x00000000,
208: 0x00000200,0x00020008,0x08020208,0x08000200, 0x08000008,0x00000200,0x00000000,0x08020008,
209: 0x08000208,0x00020000,0x08000000,0x08020208, 0x00000008,0x00020208,0x00020200,0x08000008,
210: 0x08020000,0x08000208,0x00000208,0x08020000, 0x00020208,0x00000008,0x08020008,0x00020200},
211: {
212: 0x00802001,0x00002081,0x00002081,0x00000080, 0x00802080,0x00800081,0x00800001,0x00002001,
213: 0x00000000,0x00802000,0x00802000,0x00802081, 0x00000081,0x00000000,0x00800080,0x00800001,
214: 0x00000001,0x00002000,0x00800000,0x00802001, 0x00000080,0x00800000,0x00002001,0x00002080,
215: 0x00800081,0x00000001,0x00002080,0x00800080, 0x00002000,0x00802080,0x00802081,0x00000081,
216: 0x00800080,0x00800001,0x00802000,0x00802081, 0x00000081,0x00000000,0x00000000,0x00802000,
217: 0x00002080,0x00800080,0x00800081,0x00000001, 0x00802001,0x00002081,0x00002081,0x00000080,
218: 0x00802081,0x00000081,0x00000001,0x00002000, 0x00800001,0x00002001,0x00802080,0x00800081,
219: 0x00002001,0x00002080,0x00800000,0x00802001, 0x00000080,0x00800000,0x00002000,0x00802080},
220: {
221: 0x00000100,0x02080100,0x02080000,0x42000100, 0x00080000,0x00000100,0x40000000,0x02080000,
222: 0x40080100,0x00080000,0x02000100,0x40080100, 0x42000100,0x42080000,0x00080100,0x40000000,
223: 0x02000000,0x40080000,0x40080000,0x00000000, 0x40000100,0x42080100,0x42080100,0x02000100,
224: 0x42080000,0x40000100,0x00000000,0x42000000, 0x02080100,0x02000000,0x42000000,0x00080100,
225: 0x00080000,0x42000100,0x00000100,0x02000000, 0x40000000,0x02080000,0x42000100,0x40080100,
226: 0x02000100,0x40000000,0x42080000,0x02080100, 0x40080100,0x00000100,0x02000000,0x42080000,
227: 0x42080100,0x00080100,0x42000000,0x42080100, 0x02080000,0x00000000,0x40080000,0x42000000,
228: 0x00080100,0x02000100,0x40000100,0x00080000, 0x00000000,0x40080000,0x02080100,0x40000100},
229: {
230: 0x20000010,0x20400000,0x00004000,0x20404010, 0x20400000,0x00000010,0x20404010,0x00400000,
231: 0x20004000,0x00404010,0x00400000,0x20000010, 0x00400010,0x20004000,0x20000000,0x00004010,
232: 0x00000000,0x00400010,0x20004010,0x00004000, 0x00404000,0x20004010,0x00000010,0x20400010,
233: 0x20400010,0x00000000,0x00404010,0x20404000, 0x00004010,0x00404000,0x20404000,0x20000000,
234: 0x20004000,0x00000010,0x20400010,0x00404000, 0x20404010,0x00400000,0x00004010,0x20000010,
235: 0x00400000,0x20004000,0x20000000,0x00004010, 0x20000010,0x20404010,0x00404000,0x20400000,
236: 0x00404010,0x20404000,0x00000000,0x20400010, 0x00000010,0x00004000,0x20400000,0x00404010,
237: 0x00004000,0x00400010,0x20004010,0x00000000, 0x20404000,0x20000000,0x00400010,0x20004010},
238: {
239: 0x00200000,0x04200002,0x04000802,0x00000000, 0x00000800,0x04000802,0x00200802,0x04200800,
240: 0x04200802,0x00200000,0x00000000,0x04000002, 0x00000002,0x04000000,0x04200002,0x00000802,
241: 0x04000800,0x00200802,0x00200002,0x04000800, 0x04000002,0x04200000,0x04200800,0x00200002,
242: 0x04200000,0x00000800,0x00000802,0x04200802, 0x00200800,0x00000002,0x04000000,0x00200800,
243: 0x04000000,0x00200800,0x00200000,0x04000802, 0x04000802,0x04200002,0x04200002,0x00000002,
244: 0x00200002,0x04000000,0x04000800,0x00200000, 0x04200800,0x00000802,0x00200802,0x04200800,
245: 0x00000802,0x04000002,0x04200802,0x04200000, 0x00200800,0x00000000,0x00000002,0x04200802,
246: 0x00000000,0x00200802,0x04200000,0x00000800, 0x04000002,0x04000800,0x00000800,0x00200002},
247: {
248: 0x10001040,0x00001000,0x00040000,0x10041040, 0x10000000,0x10001040,0x00000040,0x10000000,
249: 0x00040040,0x10040000,0x10041040,0x00041000, 0x10041000,0x00041040,0x00001000,0x00000040,
250: 0x10040000,0x10000040,0x10001000,0x00001040, 0x00041000,0x00040040,0x10040040,0x10041000,
251: 0x00001040,0x00000000,0x00000000,0x10040040, 0x10000040,0x10001000,0x00041040,0x00040000,
252: 0x00041040,0x00040000,0x10041000,0x00001000, 0x00000040,0x10040040,0x00001000,0x00041040,
253: 0x10001000,0x00000040,0x10000040,0x10040000, 0x10040040,0x10000000,0x00040000,0x10001040,
254: 0x00000000,0x10041040,0x00040040,0x10000040, 0x10040000,0x10001000,0x10001040,0x00000000,
255: 0x10041040,0x00041000,0x00041000,0x00001040, 0x00001040,0x00040040,0x10000000,0x10041000}
256: };
257:
258: /* Set key (initialize key schedule array) */
259: static void RawSetKey (int encryption, const byte *key, word32 *scheduledKey)
260: {
261: byte buffer[56+56+8];
262: byte *const pc1m=buffer; /* place to modify pc1 into */
263: byte *const pcr=pc1m+56; /* place to rotate pc1 into */
264: byte *const ks=pcr+56;
265: register int i,j,l;
266: int m;
267:
268: for (j=0; j<56; j++) { /* convert pc1 to bits of key */
269: l=pc1[j]-1; /* integer bit location */
270: m = l & 07; /* find bit */
271: pc1m[j]=(key[l>>3] & /* find which key byte l is in */
272: bytebit[m]) /* and which bit of that byte */
273: ? 1 : 0; /* and store 1-bit result */
274: }
275: for (i=0; i<16; i++) { /* key chunk for each iteration */
276: memset(ks,0,8); /* Clear key schedule */
277: for (j=0; j<56; j++) /* rotate pc1 the right amount */
278: pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
279: /* rotate left and right halves independently */
280: for (j=0; j<48; j++){ /* select bits individually */
281: /* check bit that goes to ks[j] */
282: if (pcr[pc2[j]-1]){
283: /* mask it in if it's there */
284: l= j % 6;
285: ks[j/6] |= bytebit[l] >> 2;
286: }
287: }
288: /* Now convert to odd/even interleaved form for use in F */
289: scheduledKey[2*i] = ((word32)ks[0] << 24)
290: | ((word32)ks[2] << 16)
291: | ((word32)ks[4] << 8)
292: | ((word32)ks[6]);
293: scheduledKey[2*i+1] = ((word32)ks[1] << 24)
294: | ((word32)ks[3] << 16)
295: | ((word32)ks[5] << 8)
296: | ((word32)ks[7]);
297: }
298:
299: if (!encryption) // reverse key schedule order
300: for (i=0; i<16; i+=2)
301: {
302: word32 b = scheduledKey[i];
303: scheduledKey[i] = scheduledKey[32-2-i];
304: scheduledKey[32-2-i] = b;
305:
306: b = scheduledKey[i+1];
307: scheduledKey[i+1] = scheduledKey[32-1-i];
308: scheduledKey[32-1-i] = b;
309: }
310:
311: burn (buffer, sizeof (buffer));
312: }
313:
314: static void RawProcessBlock(word32 *l_, word32 *r_, const word32 *k)
315: {
316: word32 l = *l_, r = *r_;
317: const word32 *kptr=k;
318: unsigned i;
319:
320: for (i=0; i<8; i++)
321: {
322: word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
323: l ^= Spbox[6][(work) & 0x3f]
324: ^ Spbox[4][(work >> 8) & 0x3f]
325: ^ Spbox[2][(work >> 16) & 0x3f]
326: ^ Spbox[0][(work >> 24) & 0x3f];
327: work = r ^ kptr[4*i+1];
328: l ^= Spbox[7][(work) & 0x3f]
329: ^ Spbox[5][(work >> 8) & 0x3f]
330: ^ Spbox[3][(work >> 16) & 0x3f]
331: ^ Spbox[1][(work >> 24) & 0x3f];
332:
333: work = rotrFixed(l, 4U) ^ kptr[4*i+2];
334: r ^= Spbox[6][(work) & 0x3f]
335: ^ Spbox[4][(work >> 8) & 0x3f]
336: ^ Spbox[2][(work >> 16) & 0x3f]
337: ^ Spbox[0][(work >> 24) & 0x3f];
338: work = l ^ kptr[4*i+3];
339: r ^= Spbox[7][(work) & 0x3f]
340: ^ Spbox[5][(work >> 8) & 0x3f]
341: ^ Spbox[3][(work >> 16) & 0x3f]
342: ^ Spbox[1][(work >> 24) & 0x3f];
343: }
344:
345: *l_ = l; *r_ = r;
346: }
347:
348: void TripleDesSetKey (const byte *userKey, unsigned int length, TDES_KEY *ks)
349: {
350: RawSetKey (1, userKey + 0, ks->k1);
351: RawSetKey (1, userKey + 8, ks->k2);
352: RawSetKey (1, userKey + 16, ks->k3);
353: RawSetKey (0, userKey + 16, ks->k1d);
354: RawSetKey (0, userKey + 8, ks->k2d);
355: RawSetKey (0, userKey + 0, ks->k3d);
356: }
357:
358: void TripleDesEncrypt (byte *inBlock, byte *outBlock, TDES_KEY *key, int encrypt)
359: {
360: word32 left = BE32 (((word32 *)inBlock)[0]);
361: word32 right = BE32 (((word32 *)inBlock)[1]);
362: word32 work;
363:
364: right = rotlFixed(right, 4U);
365: work = (left ^ right) & 0xf0f0f0f0;
366: left ^= work;
367: right = rotrFixed(right^work, 20U);
368: work = (left ^ right) & 0xffff0000;
369: left ^= work;
370: right = rotrFixed(right^work, 18U);
371: work = (left ^ right) & 0x33333333;
372: left ^= work;
373: right = rotrFixed(right^work, 6U);
374: work = (left ^ right) & 0x00ff00ff;
375: left ^= work;
376: right = rotlFixed(right^work, 9U);
377: work = (left ^ right) & 0xaaaaaaaa;
378: left = rotlFixed(left^work, 1U);
379: right ^= work;
380:
381: RawProcessBlock (&left, &right, encrypt ? key->k1 : key->k1d);
382: RawProcessBlock (&right, &left, !encrypt ? key->k2 : key->k2d);
383: RawProcessBlock (&left, &right, encrypt ? key->k3 : key->k3d);
384:
385: right = rotrFixed(right, 1U);
386: work = (left ^ right) & 0xaaaaaaaa;
387: right ^= work;
388: left = rotrFixed(left^work, 9U);
389: work = (left ^ right) & 0x00ff00ff;
390: right ^= work;
391: left = rotlFixed(left^work, 6U);
392: work = (left ^ right) & 0x33333333;
393: right ^= work;
394: left = rotlFixed(left^work, 18U);
395: work = (left ^ right) & 0xffff0000;
396: right ^= work;
397: left = rotlFixed(left^work, 20U);
398: work = (left ^ right) & 0xf0f0f0f0;
399: right ^= work;
400: left = rotrFixed(left^work, 4U);
401:
402: ((word32 *)outBlock)[0] = BE32 (right);
403: ((word32 *)outBlock)[1] = BE32 (left);
404: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.