1 /* Deprecated/legacy */
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.
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."
12 * This code is in the public domain. I would appreciate bug reports and
15 * Phil Karn KA9Q, karn@unix.ka9q.ampr.org, August 1994.
18 /* Adapted for TrueCrypt by the TrueCrypt Foundation */
21 #include "Common/Tcdefs.h"
22 #include "Common/Endian.h"
25 #define word32 unsigned __int32
26 #define byte unsigned __int8
28 static word32
rotlFixed (word32 x
, unsigned int y
)
30 return (word32
)((x
<<y
) | (x
>>(sizeof(word32
)*8-y
)));
33 static word32
rotrFixed (word32 x
, unsigned int y
)
35 return (word32
)((x
>>y
) | (x
<<(sizeof(word32
)*8-y
)));
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
48 /* initial permutation 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
60 /* final permutation IP^-1 */
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
71 /* expansion operation matrix */
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,
82 /* The (in)famous S-boxes */
83 static byte sbox
[8][64] = {
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,
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,
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,
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,
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,
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,
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,
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
133 /* 32-bit permutation function P used on the output of the S-boxes */
134 static byte p32i
[] = {
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,
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
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
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
176 /* End of DES-defined tables */
178 /* bit 0 is left-most in byte */
179 static const int bytebit
[] = {
180 0200,0100,040,020,010,04,02,01
183 static const word32 Spbox
[8][64] = {
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},
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},
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},
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},
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},
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},
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},
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}
258 /* Set key (initialize key schedule array) */
259 static void RawSetKey (int encryption
, const byte
*key
, word32
*scheduledKey
)
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;
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 */
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] */
283 /* mask it in if it's there */
285 ks
[j
/6] |= bytebit
[l
] >> 2;
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)
293 scheduledKey
[2*i
+1] = ((word32
)ks
[1] << 24)
294 | ((word32
)ks
[3] << 16)
295 | ((word32
)ks
[5] << 8)
299 if (!encryption
) // reverse key schedule order
300 for (i
=0; i
<16; i
+=2)
302 word32 b
= scheduledKey
[i
];
303 scheduledKey
[i
] = scheduledKey
[32-2-i
];
304 scheduledKey
[32-2-i
] = b
;
306 b
= scheduledKey
[i
+1];
307 scheduledKey
[i
+1] = scheduledKey
[32-1-i
];
308 scheduledKey
[32-1-i
] = b
;
311 burn (buffer
, sizeof (buffer
));
314 static void RawProcessBlock(word32
*l_
, word32
*r_
, const word32
*k
)
316 word32 l
= *l_
, r
= *r_
;
317 const word32
*kptr
=k
;
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];
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];
348 void TripleDesSetKey (const byte
*userKey
, unsigned int length
, TDES_KEY
*ks
)
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
);
358 void TripleDesEncrypt (byte
*inBlock
, byte
*outBlock
, TDES_KEY
*key
, int encrypt
)
360 word32 left
= BE32 (((word32
*)inBlock
)[0]);
361 word32 right
= BE32 (((word32
*)inBlock
)[1]);
364 right
= rotlFixed(right
, 4U);
365 work
= (left
^ right
) & 0xf0f0f0f0;
367 right
= rotrFixed(right
^work
, 20U);
368 work
= (left
^ right
) & 0xffff0000;
370 right
= rotrFixed(right
^work
, 18U);
371 work
= (left
^ right
) & 0x33333333;
373 right
= rotrFixed(right
^work
, 6U);
374 work
= (left
^ right
) & 0x00ff00ff;
376 right
= rotlFixed(right
^work
, 9U);
377 work
= (left
^ right
) & 0xaaaaaaaa;
378 left
= rotlFixed(left
^work
, 1U);
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
);
385 right
= rotrFixed(right
, 1U);
386 work
= (left
^ right
) & 0xaaaaaaaa;
388 left
= rotrFixed(left
^work
, 9U);
389 work
= (left
^ right
) & 0x00ff00ff;
391 left
= rotlFixed(left
^work
, 6U);
392 work
= (left
^ right
) & 0x33333333;
394 left
= rotlFixed(left
^work
, 18U);
395 work
= (left
^ right
) & 0xffff0000;
397 left
= rotlFixed(left
^work
, 20U);
398 work
= (left
^ right
) & 0xf0f0f0f0;
400 left
= rotrFixed(left
^work
, 4U);
402 ((word32
*)outBlock
)[0] = BE32 (right
);
403 ((word32
*)outBlock
)[1] = BE32 (left
);