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]);
430
os_memset(pkey, 0, sizeof(pkey));
431
os_memset(ek, 0, sizeof(ek));
440
void des3_key_setup(const u8 *key, struct des3_key_s *dkey)
442
deskey(key, 0, dkey->ek[0]);
443
deskey(key + 8, 1, dkey->ek[1]);
444
deskey(key + 16, 0, dkey->ek[2]);
446
deskey(key, 1, dkey->dk[2]);
447
deskey(key + 8, 0, dkey->dk[1]);
448
deskey(key + 16, 1, dkey->dk[0]);
452
void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt)
456
work[0] = WPA_GET_BE32(plain);
457
work[1] = WPA_GET_BE32(plain + 4);
458
desfunc(work, key->ek[0]);
459
desfunc(work, key->ek[1]);
460
desfunc(work, key->ek[2]);
461
WPA_PUT_BE32(crypt, work[0]);
462
WPA_PUT_BE32(crypt + 4, work[1]);
466
void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain)
470
work[0] = WPA_GET_BE32(crypt);
471
work[1] = WPA_GET_BE32(crypt + 4);
472
desfunc(work, key->dk[0]);
473
desfunc(work, key->dk[1]);
474
desfunc(work, key->dk[2]);
475
WPA_PUT_BE32(plain, work[0]);
476
WPA_PUT_BE32(plain + 4, work[1]);
479
#endif /* INTERNAL_DES */