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]);