2 * DES and 3DES-EDE ciphers
4 * Modifications to LibTomCrypt implementation:
5 * Copyright (c) 2006-2009, 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.
24 * This implementation is based on a DES implementation included in
25 * LibTomCrypt. The version here is modified to fit in wpa_supplicant/hostapd
29 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
31 * LibTomCrypt is a library that provides various cryptographic
32 * algorithms in a highly modular and flexible manner.
34 * The library is free for all purposes without any express
37 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
41 DES code submitted by Dobes Vandermeer
45 ((((unsigned long) (x) << (unsigned long) ((y) & 31)) | \
46 (((unsigned long) (x) & 0xFFFFFFFFUL) >> \
47 (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
49 (((((unsigned long) (x) & 0xFFFFFFFFUL) >> \
50 (unsigned long) ((y) & 31)) | \
51 ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & \
55 static const u32 bytebit
[8] =
57 0200, 0100, 040, 020, 010, 04, 02, 01
60 static const u32 bigbyte
[24] =
62 0x800000UL
, 0x400000UL
, 0x200000UL
, 0x100000UL
,
63 0x80000UL
, 0x40000UL
, 0x20000UL
, 0x10000UL
,
64 0x8000UL
, 0x4000UL
, 0x2000UL
, 0x1000UL
,
65 0x800UL
, 0x400UL
, 0x200UL
, 0x100UL
,
66 0x80UL
, 0x40UL
, 0x20UL
, 0x10UL
,
67 0x8UL
, 0x4UL
, 0x2UL
, 0x1L
70 /* Use the key schedule specific in the standard (ANSI X3.92-1981) */
72 static const u8 pc1
[56] = {
73 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
74 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
75 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
76 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
79 static const u8 totrot
[16] = {
86 static const u8 pc2
[48] = {
87 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
88 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
89 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
90 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
94 static const u32 SP1
[64] =
96 0x01010400UL
, 0x00000000UL
, 0x00010000UL
, 0x01010404UL
,
97 0x01010004UL
, 0x00010404UL
, 0x00000004UL
, 0x00010000UL
,
98 0x00000400UL
, 0x01010400UL
, 0x01010404UL
, 0x00000400UL
,
99 0x01000404UL
, 0x01010004UL
, 0x01000000UL
, 0x00000004UL
,
100 0x00000404UL
, 0x01000400UL
, 0x01000400UL
, 0x00010400UL
,
101 0x00010400UL
, 0x01010000UL
, 0x01010000UL
, 0x01000404UL
,
102 0x00010004UL
, 0x01000004UL
, 0x01000004UL
, 0x00010004UL
,
103 0x00000000UL
, 0x00000404UL
, 0x00010404UL
, 0x01000000UL
,
104 0x00010000UL
, 0x01010404UL
, 0x00000004UL
, 0x01010000UL
,
105 0x01010400UL
, 0x01000000UL
, 0x01000000UL
, 0x00000400UL
,
106 0x01010004UL
, 0x00010000UL
, 0x00010400UL
, 0x01000004UL
,
107 0x00000400UL
, 0x00000004UL
, 0x01000404UL
, 0x00010404UL
,
108 0x01010404UL
, 0x00010004UL
, 0x01010000UL
, 0x01000404UL
,
109 0x01000004UL
, 0x00000404UL
, 0x00010404UL
, 0x01010400UL
,
110 0x00000404UL
, 0x01000400UL
, 0x01000400UL
, 0x00000000UL
,
111 0x00010004UL
, 0x00010400UL
, 0x00000000UL
, 0x01010004UL
114 static const u32 SP2
[64] =
116 0x80108020UL
, 0x80008000UL
, 0x00008000UL
, 0x00108020UL
,
117 0x00100000UL
, 0x00000020UL
, 0x80100020UL
, 0x80008020UL
,
118 0x80000020UL
, 0x80108020UL
, 0x80108000UL
, 0x80000000UL
,
119 0x80008000UL
, 0x00100000UL
, 0x00000020UL
, 0x80100020UL
,
120 0x00108000UL
, 0x00100020UL
, 0x80008020UL
, 0x00000000UL
,
121 0x80000000UL
, 0x00008000UL
, 0x00108020UL
, 0x80100000UL
,
122 0x00100020UL
, 0x80000020UL
, 0x00000000UL
, 0x00108000UL
,
123 0x00008020UL
, 0x80108000UL
, 0x80100000UL
, 0x00008020UL
,
124 0x00000000UL
, 0x00108020UL
, 0x80100020UL
, 0x00100000UL
,
125 0x80008020UL
, 0x80100000UL
, 0x80108000UL
, 0x00008000UL
,
126 0x80100000UL
, 0x80008000UL
, 0x00000020UL
, 0x80108020UL
,
127 0x00108020UL
, 0x00000020UL
, 0x00008000UL
, 0x80000000UL
,
128 0x00008020UL
, 0x80108000UL
, 0x00100000UL
, 0x80000020UL
,
129 0x00100020UL
, 0x80008020UL
, 0x80000020UL
, 0x00100020UL
,
130 0x00108000UL
, 0x00000000UL
, 0x80008000UL
, 0x00008020UL
,
131 0x80000000UL
, 0x80100020UL
, 0x80108020UL
, 0x00108000UL
134 static const u32 SP3
[64] =
136 0x00000208UL
, 0x08020200UL
, 0x00000000UL
, 0x08020008UL
,
137 0x08000200UL
, 0x00000000UL
, 0x00020208UL
, 0x08000200UL
,
138 0x00020008UL
, 0x08000008UL
, 0x08000008UL
, 0x00020000UL
,
139 0x08020208UL
, 0x00020008UL
, 0x08020000UL
, 0x00000208UL
,
140 0x08000000UL
, 0x00000008UL
, 0x08020200UL
, 0x00000200UL
,
141 0x00020200UL
, 0x08020000UL
, 0x08020008UL
, 0x00020208UL
,
142 0x08000208UL
, 0x00020200UL
, 0x00020000UL
, 0x08000208UL
,
143 0x00000008UL
, 0x08020208UL
, 0x00000200UL
, 0x08000000UL
,
144 0x08020200UL
, 0x08000000UL
, 0x00020008UL
, 0x00000208UL
,
145 0x00020000UL
, 0x08020200UL
, 0x08000200UL
, 0x00000000UL
,
146 0x00000200UL
, 0x00020008UL
, 0x08020208UL
, 0x08000200UL
,
147 0x08000008UL
, 0x00000200UL
, 0x00000000UL
, 0x08020008UL
,
148 0x08000208UL
, 0x00020000UL
, 0x08000000UL
, 0x08020208UL
,
149 0x00000008UL
, 0x00020208UL
, 0x00020200UL
, 0x08000008UL
,
150 0x08020000UL
, 0x08000208UL
, 0x00000208UL
, 0x08020000UL
,
151 0x00020208UL
, 0x00000008UL
, 0x08020008UL
, 0x00020200UL
154 static const u32 SP4
[64] =
156 0x00802001UL
, 0x00002081UL
, 0x00002081UL
, 0x00000080UL
,
157 0x00802080UL
, 0x00800081UL
, 0x00800001UL
, 0x00002001UL
,
158 0x00000000UL
, 0x00802000UL
, 0x00802000UL
, 0x00802081UL
,
159 0x00000081UL
, 0x00000000UL
, 0x00800080UL
, 0x00800001UL
,
160 0x00000001UL
, 0x00002000UL
, 0x00800000UL
, 0x00802001UL
,
161 0x00000080UL
, 0x00800000UL
, 0x00002001UL
, 0x00002080UL
,
162 0x00800081UL
, 0x00000001UL
, 0x00002080UL
, 0x00800080UL
,
163 0x00002000UL
, 0x00802080UL
, 0x00802081UL
, 0x00000081UL
,
164 0x00800080UL
, 0x00800001UL
, 0x00802000UL
, 0x00802081UL
,
165 0x00000081UL
, 0x00000000UL
, 0x00000000UL
, 0x00802000UL
,
166 0x00002080UL
, 0x00800080UL
, 0x00800081UL
, 0x00000001UL
,
167 0x00802001UL
, 0x00002081UL
, 0x00002081UL
, 0x00000080UL
,
168 0x00802081UL
, 0x00000081UL
, 0x00000001UL
, 0x00002000UL
,
169 0x00800001UL
, 0x00002001UL
, 0x00802080UL
, 0x00800081UL
,
170 0x00002001UL
, 0x00002080UL
, 0x00800000UL
, 0x00802001UL
,
171 0x00000080UL
, 0x00800000UL
, 0x00002000UL
, 0x00802080UL
174 static const u32 SP5
[64] =
176 0x00000100UL
, 0x02080100UL
, 0x02080000UL
, 0x42000100UL
,
177 0x00080000UL
, 0x00000100UL
, 0x40000000UL
, 0x02080000UL
,
178 0x40080100UL
, 0x00080000UL
, 0x02000100UL
, 0x40080100UL
,
179 0x42000100UL
, 0x42080000UL
, 0x00080100UL
, 0x40000000UL
,
180 0x02000000UL
, 0x40080000UL
, 0x40080000UL
, 0x00000000UL
,
181 0x40000100UL
, 0x42080100UL
, 0x42080100UL
, 0x02000100UL
,
182 0x42080000UL
, 0x40000100UL
, 0x00000000UL
, 0x42000000UL
,
183 0x02080100UL
, 0x02000000UL
, 0x42000000UL
, 0x00080100UL
,
184 0x00080000UL
, 0x42000100UL
, 0x00000100UL
, 0x02000000UL
,
185 0x40000000UL
, 0x02080000UL
, 0x42000100UL
, 0x40080100UL
,
186 0x02000100UL
, 0x40000000UL
, 0x42080000UL
, 0x02080100UL
,
187 0x40080100UL
, 0x00000100UL
, 0x02000000UL
, 0x42080000UL
,
188 0x42080100UL
, 0x00080100UL
, 0x42000000UL
, 0x42080100UL
,
189 0x02080000UL
, 0x00000000UL
, 0x40080000UL
, 0x42000000UL
,
190 0x00080100UL
, 0x02000100UL
, 0x40000100UL
, 0x00080000UL
,
191 0x00000000UL
, 0x40080000UL
, 0x02080100UL
, 0x40000100UL
194 static const u32 SP6
[64] =
196 0x20000010UL
, 0x20400000UL
, 0x00004000UL
, 0x20404010UL
,
197 0x20400000UL
, 0x00000010UL
, 0x20404010UL
, 0x00400000UL
,
198 0x20004000UL
, 0x00404010UL
, 0x00400000UL
, 0x20000010UL
,
199 0x00400010UL
, 0x20004000UL
, 0x20000000UL
, 0x00004010UL
,
200 0x00000000UL
, 0x00400010UL
, 0x20004010UL
, 0x00004000UL
,
201 0x00404000UL
, 0x20004010UL
, 0x00000010UL
, 0x20400010UL
,
202 0x20400010UL
, 0x00000000UL
, 0x00404010UL
, 0x20404000UL
,
203 0x00004010UL
, 0x00404000UL
, 0x20404000UL
, 0x20000000UL
,
204 0x20004000UL
, 0x00000010UL
, 0x20400010UL
, 0x00404000UL
,
205 0x20404010UL
, 0x00400000UL
, 0x00004010UL
, 0x20000010UL
,
206 0x00400000UL
, 0x20004000UL
, 0x20000000UL
, 0x00004010UL
,
207 0x20000010UL
, 0x20404010UL
, 0x00404000UL
, 0x20400000UL
,
208 0x00404010UL
, 0x20404000UL
, 0x00000000UL
, 0x20400010UL
,
209 0x00000010UL
, 0x00004000UL
, 0x20400000UL
, 0x00404010UL
,
210 0x00004000UL
, 0x00400010UL
, 0x20004010UL
, 0x00000000UL
,
211 0x20404000UL
, 0x20000000UL
, 0x00400010UL
, 0x20004010UL
214 static const u32 SP7
[64] =
216 0x00200000UL
, 0x04200002UL
, 0x04000802UL
, 0x00000000UL
,
217 0x00000800UL
, 0x04000802UL
, 0x00200802UL
, 0x04200800UL
,
218 0x04200802UL
, 0x00200000UL
, 0x00000000UL
, 0x04000002UL
,
219 0x00000002UL
, 0x04000000UL
, 0x04200002UL
, 0x00000802UL
,
220 0x04000800UL
, 0x00200802UL
, 0x00200002UL
, 0x04000800UL
,
221 0x04000002UL
, 0x04200000UL
, 0x04200800UL
, 0x00200002UL
,
222 0x04200000UL
, 0x00000800UL
, 0x00000802UL
, 0x04200802UL
,
223 0x00200800UL
, 0x00000002UL
, 0x04000000UL
, 0x00200800UL
,
224 0x04000000UL
, 0x00200800UL
, 0x00200000UL
, 0x04000802UL
,
225 0x04000802UL
, 0x04200002UL
, 0x04200002UL
, 0x00000002UL
,
226 0x00200002UL
, 0x04000000UL
, 0x04000800UL
, 0x00200000UL
,
227 0x04200800UL
, 0x00000802UL
, 0x00200802UL
, 0x04200800UL
,
228 0x00000802UL
, 0x04000002UL
, 0x04200802UL
, 0x04200000UL
,
229 0x00200800UL
, 0x00000000UL
, 0x00000002UL
, 0x04200802UL
,
230 0x00000000UL
, 0x00200802UL
, 0x04200000UL
, 0x00000800UL
,
231 0x04000002UL
, 0x04000800UL
, 0x00000800UL
, 0x00200002UL
234 static const u32 SP8
[64] =
236 0x10001040UL
, 0x00001000UL
, 0x00040000UL
, 0x10041040UL
,
237 0x10000000UL
, 0x10001040UL
, 0x00000040UL
, 0x10000000UL
,
238 0x00040040UL
, 0x10040000UL
, 0x10041040UL
, 0x00041000UL
,
239 0x10041000UL
, 0x00041040UL
, 0x00001000UL
, 0x00000040UL
,
240 0x10040000UL
, 0x10000040UL
, 0x10001000UL
, 0x00001040UL
,
241 0x00041000UL
, 0x00040040UL
, 0x10040040UL
, 0x10041000UL
,
242 0x00001040UL
, 0x00000000UL
, 0x00000000UL
, 0x10040040UL
,
243 0x10000040UL
, 0x10001000UL
, 0x00041040UL
, 0x00040000UL
,
244 0x00041040UL
, 0x00040000UL
, 0x10041000UL
, 0x00001000UL
,
245 0x00000040UL
, 0x10040040UL
, 0x00001000UL
, 0x00041040UL
,
246 0x10001000UL
, 0x00000040UL
, 0x10000040UL
, 0x10040000UL
,
247 0x10040040UL
, 0x10000000UL
, 0x00040000UL
, 0x10001040UL
,
248 0x00000000UL
, 0x10041040UL
, 0x00040040UL
, 0x10000040UL
,
249 0x10040000UL
, 0x10001000UL
, 0x10001040UL
, 0x00000000UL
,
250 0x10041040UL
, 0x00041000UL
, 0x00041000UL
, 0x00001040UL
,
251 0x00001040UL
, 0x00040040UL
, 0x10000000UL
, 0x10041000UL
255 static void cookey(const u32
*raw1
, u32
*keyout
)
263 for (i
= 0; i
< 16; i
++, raw1
++) {
265 *cook
= (*raw0
& 0x00fc0000L
) << 6;
266 *cook
|= (*raw0
& 0x00000fc0L
) << 10;
267 *cook
|= (*raw1
& 0x00fc0000L
) >> 10;
268 *cook
++ |= (*raw1
& 0x00000fc0L
) >> 6;
269 *cook
= (*raw0
& 0x0003f000L
) << 12;
270 *cook
|= (*raw0
& 0x0000003fL
) << 16;
271 *cook
|= (*raw1
& 0x0003f000L
) >> 4;
272 *cook
++ |= (*raw1
& 0x0000003fL
);
275 os_memcpy(keyout
, dough
, sizeof(dough
));
279 static void deskey(const u8
*key
, int decrypt
, u32
*keyout
)
281 u32 i
, j
, l
, m
, n
, kn
[32];
282 u8 pc1m
[56], pcr
[56];
284 for (j
= 0; j
< 56; j
++) {
288 ((key
[l
>> 3U] & bytebit
[m
]) == bytebit
[m
] ? 1 : 0);
291 for (i
= 0; i
< 16; i
++) {
298 for (j
= 0; j
< 28; j
++) {
299 l
= j
+ (u32
) totrot
[i
];
303 pcr
[j
] = pc1m
[l
- 28];
305 for (/* j = 28 */; j
< 56; j
++) {
306 l
= j
+ (u32
) totrot
[i
];
310 pcr
[j
] = pc1m
[l
- 28];
312 for (j
= 0; j
< 24; j
++) {
313 if ((int) pcr
[(int) pc2
[j
]] != 0)
315 if ((int) pcr
[(int) pc2
[j
+ 24]] != 0)
324 static void desfunc(u32
*block
, const u32
*keys
)
326 u32 work
, right
, leftt
;
332 work
= ((leftt
>> 4) ^ right
) & 0x0f0f0f0fL
;
334 leftt
^= (work
<< 4);
336 work
= ((leftt
>> 16) ^ right
) & 0x0000ffffL
;
338 leftt
^= (work
<< 16);
340 work
= ((right
>> 2) ^ leftt
) & 0x33333333L
;
342 right
^= (work
<< 2);
344 work
= ((right
>> 8) ^ leftt
) & 0x00ff00ffL
;
346 right
^= (work
<< 8);
348 right
= ROLc(right
, 1);
349 work
= (leftt
^ right
) & 0xaaaaaaaaL
;
353 leftt
= ROLc(leftt
, 1);
355 for (cur_round
= 0; cur_round
< 8; cur_round
++) {
356 work
= RORc(right
, 4) ^ *keys
++;
357 leftt
^= SP7
[work
& 0x3fL
]
358 ^ SP5
[(work
>> 8) & 0x3fL
]
359 ^ SP3
[(work
>> 16) & 0x3fL
]
360 ^ SP1
[(work
>> 24) & 0x3fL
];
361 work
= right
^ *keys
++;
362 leftt
^= SP8
[ work
& 0x3fL
]
363 ^ SP6
[(work
>> 8) & 0x3fL
]
364 ^ SP4
[(work
>> 16) & 0x3fL
]
365 ^ SP2
[(work
>> 24) & 0x3fL
];
367 work
= RORc(leftt
, 4) ^ *keys
++;
368 right
^= SP7
[ work
& 0x3fL
]
369 ^ SP5
[(work
>> 8) & 0x3fL
]
370 ^ SP3
[(work
>> 16) & 0x3fL
]
371 ^ SP1
[(work
>> 24) & 0x3fL
];
372 work
= leftt
^ *keys
++;
373 right
^= SP8
[ work
& 0x3fL
]
374 ^ SP6
[(work
>> 8) & 0x3fL
]
375 ^ SP4
[(work
>> 16) & 0x3fL
]
376 ^ SP2
[(work
>> 24) & 0x3fL
];
379 right
= RORc(right
, 1);
380 work
= (leftt
^ right
) & 0xaaaaaaaaL
;
383 leftt
= RORc(leftt
, 1);
384 work
= ((leftt
>> 8) ^ right
) & 0x00ff00ffL
;
386 leftt
^= (work
<< 8);
388 work
= ((leftt
>> 2) ^ right
) & 0x33333333L
;
390 leftt
^= (work
<< 2);
391 work
= ((right
>> 16) ^ leftt
) & 0x0000ffffL
;
393 right
^= (work
<< 16);
394 work
= ((right
>> 4) ^ leftt
) & 0x0f0f0f0fL
;
396 right
^= (work
<< 4);
403 /* wpa_supplicant/hostapd specific wrapper */
405 void des_encrypt(const u8
*clear
, const u8
*key
, u8
*cypher
)
407 u8 pkey
[8], next
, tmp
;
411 /* Add parity bits to the key */
413 for (i
= 0; i
< 7; i
++) {
415 pkey
[i
] = (tmp
>> i
) | next
| 1;
416 next
= tmp
<< (7 - i
);
422 work
[0] = WPA_GET_BE32(clear
);
423 work
[1] = WPA_GET_BE32(clear
+ 4);
425 WPA_PUT_BE32(cypher
, work
[0]);
426 WPA_PUT_BE32(cypher
+ 4, work
[1]);
428 os_memset(pkey
, 0, sizeof(pkey
));
429 os_memset(ek
, 0, sizeof(ek
));
433 void des_key_setup(const u8
*key
, u32
*ek
, u32
*dk
)
440 void des_block_encrypt(const u8
*plain
, const u32
*ek
, u8
*crypt
)
443 work
[0] = WPA_GET_BE32(plain
);
444 work
[1] = WPA_GET_BE32(plain
+ 4);
446 WPA_PUT_BE32(crypt
, work
[0]);
447 WPA_PUT_BE32(crypt
+ 4, work
[1]);
451 void des_block_decrypt(const u8
*crypt
, const u32
*dk
, u8
*plain
)
454 work
[0] = WPA_GET_BE32(crypt
);
455 work
[1] = WPA_GET_BE32(crypt
+ 4);
457 WPA_PUT_BE32(plain
, work
[0]);
458 WPA_PUT_BE32(plain
+ 4, work
[1]);
462 void des3_key_setup(const u8
*key
, struct des3_key_s
*dkey
)
464 deskey(key
, 0, dkey
->ek
[0]);
465 deskey(key
+ 8, 1, dkey
->ek
[1]);
466 deskey(key
+ 16, 0, dkey
->ek
[2]);
468 deskey(key
, 1, dkey
->dk
[2]);
469 deskey(key
+ 8, 0, dkey
->dk
[1]);
470 deskey(key
+ 16, 1, dkey
->dk
[0]);
474 void des3_encrypt(const u8
*plain
, const struct des3_key_s
*key
, u8
*crypt
)
478 work
[0] = WPA_GET_BE32(plain
);
479 work
[1] = WPA_GET_BE32(plain
+ 4);
480 desfunc(work
, key
->ek
[0]);
481 desfunc(work
, key
->ek
[1]);
482 desfunc(work
, key
->ek
[2]);
483 WPA_PUT_BE32(crypt
, work
[0]);
484 WPA_PUT_BE32(crypt
+ 4, work
[1]);
488 void des3_decrypt(const u8
*crypt
, const struct des3_key_s
*key
, u8
*plain
)
492 work
[0] = WPA_GET_BE32(crypt
);
493 work
[1] = WPA_GET_BE32(crypt
+ 4);
494 desfunc(work
, key
->dk
[0]);
495 desfunc(work
, key
->dk
[1]);
496 desfunc(work
, key
->dk
[2]);
497 WPA_PUT_BE32(plain
, work
[0]);
498 WPA_PUT_BE32(plain
+ 4, work
[1]);