2 * DES and 3DES-EDE ciphers
4 * Modifications to LibTomCrypt implementation:
5 * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Alternatively, this software may be distributed under the terms of BSD
14 * See README and COPYING for more details.
26 * This implementation is based on a DES implementation included in
27 * LibTomCrypt. The version here is modified to fit in wpa_supplicant/hostapd
31 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
33 * LibTomCrypt is a library that provides various cryptographic
34 * algorithms in a highly modular and flexible manner.
36 * The library is free for all purposes without any express
39 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
43 DES code submitted by Dobes Vandermeer
47 ((((unsigned long) (x) << (unsigned long) ((y) & 31)) | \
48 (((unsigned long) (x) & 0xFFFFFFFFUL) >> \
49 (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
51 (((((unsigned long) (x) & 0xFFFFFFFFUL) >> \
52 (unsigned long) ((y) & 31)) | \
53 ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & \
57 static const u32 bytebit
[8] =
59 0200, 0100, 040, 020, 010, 04, 02, 01
62 static const u32 bigbyte
[24] =
64 0x800000UL
, 0x400000UL
, 0x200000UL
, 0x100000UL
,
65 0x80000UL
, 0x40000UL
, 0x20000UL
, 0x10000UL
,
66 0x8000UL
, 0x4000UL
, 0x2000UL
, 0x1000UL
,
67 0x800UL
, 0x400UL
, 0x200UL
, 0x100UL
,
68 0x80UL
, 0x40UL
, 0x20UL
, 0x10UL
,
69 0x8UL
, 0x4UL
, 0x2UL
, 0x1L
72 /* Use the key schedule specific in the standard (ANSI X3.92-1981) */
74 static const u8 pc1
[56] = {
75 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
76 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
77 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
78 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
81 static const u8 totrot
[16] = {
88 static const u8 pc2
[48] = {
89 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
90 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
91 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
92 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
96 static const u32 SP1
[64] =
98 0x01010400UL
, 0x00000000UL
, 0x00010000UL
, 0x01010404UL
,
99 0x01010004UL
, 0x00010404UL
, 0x00000004UL
, 0x00010000UL
,
100 0x00000400UL
, 0x01010400UL
, 0x01010404UL
, 0x00000400UL
,
101 0x01000404UL
, 0x01010004UL
, 0x01000000UL
, 0x00000004UL
,
102 0x00000404UL
, 0x01000400UL
, 0x01000400UL
, 0x00010400UL
,
103 0x00010400UL
, 0x01010000UL
, 0x01010000UL
, 0x01000404UL
,
104 0x00010004UL
, 0x01000004UL
, 0x01000004UL
, 0x00010004UL
,
105 0x00000000UL
, 0x00000404UL
, 0x00010404UL
, 0x01000000UL
,
106 0x00010000UL
, 0x01010404UL
, 0x00000004UL
, 0x01010000UL
,
107 0x01010400UL
, 0x01000000UL
, 0x01000000UL
, 0x00000400UL
,
108 0x01010004UL
, 0x00010000UL
, 0x00010400UL
, 0x01000004UL
,
109 0x00000400UL
, 0x00000004UL
, 0x01000404UL
, 0x00010404UL
,
110 0x01010404UL
, 0x00010004UL
, 0x01010000UL
, 0x01000404UL
,
111 0x01000004UL
, 0x00000404UL
, 0x00010404UL
, 0x01010400UL
,
112 0x00000404UL
, 0x01000400UL
, 0x01000400UL
, 0x00000000UL
,
113 0x00010004UL
, 0x00010400UL
, 0x00000000UL
, 0x01010004UL
116 static const u32 SP2
[64] =
118 0x80108020UL
, 0x80008000UL
, 0x00008000UL
, 0x00108020UL
,
119 0x00100000UL
, 0x00000020UL
, 0x80100020UL
, 0x80008020UL
,
120 0x80000020UL
, 0x80108020UL
, 0x80108000UL
, 0x80000000UL
,
121 0x80008000UL
, 0x00100000UL
, 0x00000020UL
, 0x80100020UL
,
122 0x00108000UL
, 0x00100020UL
, 0x80008020UL
, 0x00000000UL
,
123 0x80000000UL
, 0x00008000UL
, 0x00108020UL
, 0x80100000UL
,
124 0x00100020UL
, 0x80000020UL
, 0x00000000UL
, 0x00108000UL
,
125 0x00008020UL
, 0x80108000UL
, 0x80100000UL
, 0x00008020UL
,
126 0x00000000UL
, 0x00108020UL
, 0x80100020UL
, 0x00100000UL
,
127 0x80008020UL
, 0x80100000UL
, 0x80108000UL
, 0x00008000UL
,
128 0x80100000UL
, 0x80008000UL
, 0x00000020UL
, 0x80108020UL
,
129 0x00108020UL
, 0x00000020UL
, 0x00008000UL
, 0x80000000UL
,
130 0x00008020UL
, 0x80108000UL
, 0x00100000UL
, 0x80000020UL
,
131 0x00100020UL
, 0x80008020UL
, 0x80000020UL
, 0x00100020UL
,
132 0x00108000UL
, 0x00000000UL
, 0x80008000UL
, 0x00008020UL
,
133 0x80000000UL
, 0x80100020UL
, 0x80108020UL
, 0x00108000UL
136 static const u32 SP3
[64] =
138 0x00000208UL
, 0x08020200UL
, 0x00000000UL
, 0x08020008UL
,
139 0x08000200UL
, 0x00000000UL
, 0x00020208UL
, 0x08000200UL
,
140 0x00020008UL
, 0x08000008UL
, 0x08000008UL
, 0x00020000UL
,
141 0x08020208UL
, 0x00020008UL
, 0x08020000UL
, 0x00000208UL
,
142 0x08000000UL
, 0x00000008UL
, 0x08020200UL
, 0x00000200UL
,
143 0x00020200UL
, 0x08020000UL
, 0x08020008UL
, 0x00020208UL
,
144 0x08000208UL
, 0x00020200UL
, 0x00020000UL
, 0x08000208UL
,
145 0x00000008UL
, 0x08020208UL
, 0x00000200UL
, 0x08000000UL
,
146 0x08020200UL
, 0x08000000UL
, 0x00020008UL
, 0x00000208UL
,
147 0x00020000UL
, 0x08020200UL
, 0x08000200UL
, 0x00000000UL
,
148 0x00000200UL
, 0x00020008UL
, 0x08020208UL
, 0x08000200UL
,
149 0x08000008UL
, 0x00000200UL
, 0x00000000UL
, 0x08020008UL
,
150 0x08000208UL
, 0x00020000UL
, 0x08000000UL
, 0x08020208UL
,
151 0x00000008UL
, 0x00020208UL
, 0x00020200UL
, 0x08000008UL
,
152 0x08020000UL
, 0x08000208UL
, 0x00000208UL
, 0x08020000UL
,
153 0x00020208UL
, 0x00000008UL
, 0x08020008UL
, 0x00020200UL
156 static const u32 SP4
[64] =
158 0x00802001UL
, 0x00002081UL
, 0x00002081UL
, 0x00000080UL
,
159 0x00802080UL
, 0x00800081UL
, 0x00800001UL
, 0x00002001UL
,
160 0x00000000UL
, 0x00802000UL
, 0x00802000UL
, 0x00802081UL
,
161 0x00000081UL
, 0x00000000UL
, 0x00800080UL
, 0x00800001UL
,
162 0x00000001UL
, 0x00002000UL
, 0x00800000UL
, 0x00802001UL
,
163 0x00000080UL
, 0x00800000UL
, 0x00002001UL
, 0x00002080UL
,
164 0x00800081UL
, 0x00000001UL
, 0x00002080UL
, 0x00800080UL
,
165 0x00002000UL
, 0x00802080UL
, 0x00802081UL
, 0x00000081UL
,
166 0x00800080UL
, 0x00800001UL
, 0x00802000UL
, 0x00802081UL
,
167 0x00000081UL
, 0x00000000UL
, 0x00000000UL
, 0x00802000UL
,
168 0x00002080UL
, 0x00800080UL
, 0x00800081UL
, 0x00000001UL
,
169 0x00802001UL
, 0x00002081UL
, 0x00002081UL
, 0x00000080UL
,
170 0x00802081UL
, 0x00000081UL
, 0x00000001UL
, 0x00002000UL
,
171 0x00800001UL
, 0x00002001UL
, 0x00802080UL
, 0x00800081UL
,
172 0x00002001UL
, 0x00002080UL
, 0x00800000UL
, 0x00802001UL
,
173 0x00000080UL
, 0x00800000UL
, 0x00002000UL
, 0x00802080UL
176 static const u32 SP5
[64] =
178 0x00000100UL
, 0x02080100UL
, 0x02080000UL
, 0x42000100UL
,
179 0x00080000UL
, 0x00000100UL
, 0x40000000UL
, 0x02080000UL
,
180 0x40080100UL
, 0x00080000UL
, 0x02000100UL
, 0x40080100UL
,
181 0x42000100UL
, 0x42080000UL
, 0x00080100UL
, 0x40000000UL
,
182 0x02000000UL
, 0x40080000UL
, 0x40080000UL
, 0x00000000UL
,
183 0x40000100UL
, 0x42080100UL
, 0x42080100UL
, 0x02000100UL
,
184 0x42080000UL
, 0x40000100UL
, 0x00000000UL
, 0x42000000UL
,
185 0x02080100UL
, 0x02000000UL
, 0x42000000UL
, 0x00080100UL
,
186 0x00080000UL
, 0x42000100UL
, 0x00000100UL
, 0x02000000UL
,
187 0x40000000UL
, 0x02080000UL
, 0x42000100UL
, 0x40080100UL
,
188 0x02000100UL
, 0x40000000UL
, 0x42080000UL
, 0x02080100UL
,
189 0x40080100UL
, 0x00000100UL
, 0x02000000UL
, 0x42080000UL
,
190 0x42080100UL
, 0x00080100UL
, 0x42000000UL
, 0x42080100UL
,
191 0x02080000UL
, 0x00000000UL
, 0x40080000UL
, 0x42000000UL
,
192 0x00080100UL
, 0x02000100UL
, 0x40000100UL
, 0x00080000UL
,
193 0x00000000UL
, 0x40080000UL
, 0x02080100UL
, 0x40000100UL
196 static const u32 SP6
[64] =
198 0x20000010UL
, 0x20400000UL
, 0x00004000UL
, 0x20404010UL
,
199 0x20400000UL
, 0x00000010UL
, 0x20404010UL
, 0x00400000UL
,
200 0x20004000UL
, 0x00404010UL
, 0x00400000UL
, 0x20000010UL
,
201 0x00400010UL
, 0x20004000UL
, 0x20000000UL
, 0x00004010UL
,
202 0x00000000UL
, 0x00400010UL
, 0x20004010UL
, 0x00004000UL
,
203 0x00404000UL
, 0x20004010UL
, 0x00000010UL
, 0x20400010UL
,
204 0x20400010UL
, 0x00000000UL
, 0x00404010UL
, 0x20404000UL
,
205 0x00004010UL
, 0x00404000UL
, 0x20404000UL
, 0x20000000UL
,
206 0x20004000UL
, 0x00000010UL
, 0x20400010UL
, 0x00404000UL
,
207 0x20404010UL
, 0x00400000UL
, 0x00004010UL
, 0x20000010UL
,
208 0x00400000UL
, 0x20004000UL
, 0x20000000UL
, 0x00004010UL
,
209 0x20000010UL
, 0x20404010UL
, 0x00404000UL
, 0x20400000UL
,
210 0x00404010UL
, 0x20404000UL
, 0x00000000UL
, 0x20400010UL
,
211 0x00000010UL
, 0x00004000UL
, 0x20400000UL
, 0x00404010UL
,
212 0x00004000UL
, 0x00400010UL
, 0x20004010UL
, 0x00000000UL
,
213 0x20404000UL
, 0x20000000UL
, 0x00400010UL
, 0x20004010UL
216 static const u32 SP7
[64] =
218 0x00200000UL
, 0x04200002UL
, 0x04000802UL
, 0x00000000UL
,
219 0x00000800UL
, 0x04000802UL
, 0x00200802UL
, 0x04200800UL
,
220 0x04200802UL
, 0x00200000UL
, 0x00000000UL
, 0x04000002UL
,
221 0x00000002UL
, 0x04000000UL
, 0x04200002UL
, 0x00000802UL
,
222 0x04000800UL
, 0x00200802UL
, 0x00200002UL
, 0x04000800UL
,
223 0x04000002UL
, 0x04200000UL
, 0x04200800UL
, 0x00200002UL
,
224 0x04200000UL
, 0x00000800UL
, 0x00000802UL
, 0x04200802UL
,
225 0x00200800UL
, 0x00000002UL
, 0x04000000UL
, 0x00200800UL
,
226 0x04000000UL
, 0x00200800UL
, 0x00200000UL
, 0x04000802UL
,
227 0x04000802UL
, 0x04200002UL
, 0x04200002UL
, 0x00000002UL
,
228 0x00200002UL
, 0x04000000UL
, 0x04000800UL
, 0x00200000UL
,
229 0x04200800UL
, 0x00000802UL
, 0x00200802UL
, 0x04200800UL
,
230 0x00000802UL
, 0x04000002UL
, 0x04200802UL
, 0x04200000UL
,
231 0x00200800UL
, 0x00000000UL
, 0x00000002UL
, 0x04200802UL
,
232 0x00000000UL
, 0x00200802UL
, 0x04200000UL
, 0x00000800UL
,
233 0x04000002UL
, 0x04000800UL
, 0x00000800UL
, 0x00200002UL
236 static const u32 SP8
[64] =
238 0x10001040UL
, 0x00001000UL
, 0x00040000UL
, 0x10041040UL
,
239 0x10000000UL
, 0x10001040UL
, 0x00000040UL
, 0x10000000UL
,
240 0x00040040UL
, 0x10040000UL
, 0x10041040UL
, 0x00041000UL
,
241 0x10041000UL
, 0x00041040UL
, 0x00001000UL
, 0x00000040UL
,
242 0x10040000UL
, 0x10000040UL
, 0x10001000UL
, 0x00001040UL
,
243 0x00041000UL
, 0x00040040UL
, 0x10040040UL
, 0x10041000UL
,
244 0x00001040UL
, 0x00000000UL
, 0x00000000UL
, 0x10040040UL
,
245 0x10000040UL
, 0x10001000UL
, 0x00041040UL
, 0x00040000UL
,
246 0x00041040UL
, 0x00040000UL
, 0x10041000UL
, 0x00001000UL
,
247 0x00000040UL
, 0x10040040UL
, 0x00001000UL
, 0x00041040UL
,
248 0x10001000UL
, 0x00000040UL
, 0x10000040UL
, 0x10040000UL
,
249 0x10040040UL
, 0x10000000UL
, 0x00040000UL
, 0x10001040UL
,
250 0x00000000UL
, 0x10041040UL
, 0x00040040UL
, 0x10000040UL
,
251 0x10040000UL
, 0x10001000UL
, 0x10001040UL
, 0x00000000UL
,
252 0x10041040UL
, 0x00041000UL
, 0x00041000UL
, 0x00001040UL
,
253 0x00001040UL
, 0x00040040UL
, 0x10000000UL
, 0x10041000UL
257 static void cookey(const u32
*raw1
, u32
*keyout
)
265 for (i
= 0; i
< 16; i
++, raw1
++) {
267 *cook
= (*raw0
& 0x00fc0000L
) << 6;
268 *cook
|= (*raw0
& 0x00000fc0L
) << 10;
269 *cook
|= (*raw1
& 0x00fc0000L
) >> 10;
270 *cook
++ |= (*raw1
& 0x00000fc0L
) >> 6;
271 *cook
= (*raw0
& 0x0003f000L
) << 12;
272 *cook
|= (*raw0
& 0x0000003fL
) << 16;
273 *cook
|= (*raw1
& 0x0003f000L
) >> 4;
274 *cook
++ |= (*raw1
& 0x0000003fL
);
277 os_memcpy(keyout
, dough
, sizeof(dough
));
281 static void deskey(const u8
*key
, int decrypt
, u32
*keyout
)
283 u32 i
, j
, l
, m
, n
, kn
[32];
284 u8 pc1m
[56], pcr
[56];
286 for (j
= 0; j
< 56; j
++) {
290 ((key
[l
>> 3U] & bytebit
[m
]) == bytebit
[m
] ? 1 : 0);
293 for (i
= 0; i
< 16; i
++) {
300 for (j
= 0; j
< 28; j
++) {
301 l
= j
+ (u32
) totrot
[i
];
305 pcr
[j
] = pc1m
[l
- 28];
307 for (/* j = 28 */; j
< 56; j
++) {
308 l
= j
+ (u32
) totrot
[i
];
312 pcr
[j
] = pc1m
[l
- 28];
314 for (j
= 0; j
< 24; j
++) {
315 if ((int) pcr
[(int) pc2
[j
]] != 0)
317 if ((int) pcr
[(int) pc2
[j
+ 24]] != 0)
326 static void desfunc(u32
*block
, const u32
*keys
)
328 u32 work
, right
, leftt
;
334 work
= ((leftt
>> 4) ^ right
) & 0x0f0f0f0fL
;
336 leftt
^= (work
<< 4);
338 work
= ((leftt
>> 16) ^ right
) & 0x0000ffffL
;
340 leftt
^= (work
<< 16);
342 work
= ((right
>> 2) ^ leftt
) & 0x33333333L
;
344 right
^= (work
<< 2);
346 work
= ((right
>> 8) ^ leftt
) & 0x00ff00ffL
;
348 right
^= (work
<< 8);
350 right
= ROLc(right
, 1);
351 work
= (leftt
^ right
) & 0xaaaaaaaaL
;
355 leftt
= ROLc(leftt
, 1);
357 for (cur_round
= 0; cur_round
< 8; cur_round
++) {
358 work
= RORc(right
, 4) ^ *keys
++;
359 leftt
^= SP7
[work
& 0x3fL
]
360 ^ SP5
[(work
>> 8) & 0x3fL
]
361 ^ SP3
[(work
>> 16) & 0x3fL
]
362 ^ SP1
[(work
>> 24) & 0x3fL
];
363 work
= right
^ *keys
++;
364 leftt
^= SP8
[ work
& 0x3fL
]
365 ^ SP6
[(work
>> 8) & 0x3fL
]
366 ^ SP4
[(work
>> 16) & 0x3fL
]
367 ^ SP2
[(work
>> 24) & 0x3fL
];
369 work
= RORc(leftt
, 4) ^ *keys
++;
370 right
^= SP7
[ work
& 0x3fL
]
371 ^ SP5
[(work
>> 8) & 0x3fL
]
372 ^ SP3
[(work
>> 16) & 0x3fL
]
373 ^ SP1
[(work
>> 24) & 0x3fL
];
374 work
= leftt
^ *keys
++;
375 right
^= SP8
[ work
& 0x3fL
]
376 ^ SP6
[(work
>> 8) & 0x3fL
]
377 ^ SP4
[(work
>> 16) & 0x3fL
]
378 ^ SP2
[(work
>> 24) & 0x3fL
];
381 right
= RORc(right
, 1);
382 work
= (leftt
^ right
) & 0xaaaaaaaaL
;
385 leftt
= RORc(leftt
, 1);
386 work
= ((leftt
>> 8) ^ right
) & 0x00ff00ffL
;
388 leftt
^= (work
<< 8);
390 work
= ((leftt
>> 2) ^ right
) & 0x33333333L
;
392 leftt
^= (work
<< 2);
393 work
= ((right
>> 16) ^ leftt
) & 0x0000ffffL
;
395 right
^= (work
<< 16);
396 work
= ((right
>> 4) ^ leftt
) & 0x0f0f0f0fL
;
398 right
^= (work
<< 4);
405 /* wpa_supplicant/hostapd specific wrapper */
407 void des_encrypt(const u8
*clear
, const u8
*key
, u8
*cypher
)
409 u8 pkey
[8], next
, tmp
;
413 /* Add parity bits to the key */
415 for (i
= 0; i
< 7; i
++) {
417 pkey
[i
] = (tmp
>> i
) | next
| 1;
418 next
= tmp
<< (7 - i
);
424 work
[0] = WPA_GET_BE32(clear
);
425 work
[1] = WPA_GET_BE32(clear
+ 4);
427 WPA_PUT_BE32(cypher
, work
[0]);
428 WPA_PUT_BE32(cypher
+ 4, work
[1]);
437 void des3_key_setup(const u8
*key
, struct des3_key_s
*dkey
)
439 deskey(key
, 0, dkey
->ek
[0]);
440 deskey(key
+ 8, 1, dkey
->ek
[1]);
441 deskey(key
+ 16, 0, dkey
->ek
[2]);
443 deskey(key
, 1, dkey
->dk
[2]);
444 deskey(key
+ 8, 0, dkey
->dk
[1]);
445 deskey(key
+ 16, 1, dkey
->dk
[0]);
449 void des3_encrypt(const u8
*plain
, const struct des3_key_s
*key
, u8
*crypt
)
453 work
[0] = WPA_GET_BE32(plain
);
454 work
[1] = WPA_GET_BE32(plain
+ 4);
455 desfunc(work
, key
->ek
[0]);
456 desfunc(work
, key
->ek
[1]);
457 desfunc(work
, key
->ek
[2]);
458 WPA_PUT_BE32(crypt
, work
[0]);
459 WPA_PUT_BE32(crypt
+ 4, work
[1]);
463 void des3_decrypt(const u8
*crypt
, const struct des3_key_s
*key
, u8
*plain
)
467 work
[0] = WPA_GET_BE32(crypt
);
468 work
[1] = WPA_GET_BE32(crypt
+ 4);
469 desfunc(work
, key
->dk
[0]);
470 desfunc(work
, key
->dk
[1]);
471 desfunc(work
, key
->dk
[2]);
472 WPA_PUT_BE32(plain
, work
[0]);
473 WPA_PUT_BE32(plain
+ 4, work
[1]);
476 #endif /* INTERNAL_DES */