xref: /freebsd/contrib/wpa/src/crypto/des-internal.c (revision 67350cb56a69468c118bd4ccf6e361b7ebfa9eb4)
1e28a4053SRui Paulo /*
2e28a4053SRui Paulo  * DES and 3DES-EDE ciphers
3e28a4053SRui Paulo  *
4e28a4053SRui Paulo  * Modifications to LibTomCrypt implementation:
5e28a4053SRui Paulo  * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
6e28a4053SRui Paulo  *
7f05cddf9SRui Paulo  * This software may be distributed under the terms of the BSD license.
8f05cddf9SRui Paulo  * See README for more details.
9e28a4053SRui Paulo  */
10e28a4053SRui Paulo 
11e28a4053SRui Paulo #include "includes.h"
12e28a4053SRui Paulo 
13e28a4053SRui Paulo #include "common.h"
14e28a4053SRui Paulo #include "crypto.h"
15e28a4053SRui Paulo #include "des_i.h"
16e28a4053SRui Paulo 
17e28a4053SRui Paulo /*
18e28a4053SRui Paulo  * This implementation is based on a DES implementation included in
19e28a4053SRui Paulo  * LibTomCrypt. The version here is modified to fit in wpa_supplicant/hostapd
20e28a4053SRui Paulo  * coding style.
21e28a4053SRui Paulo  */
22e28a4053SRui Paulo 
23e28a4053SRui Paulo /* LibTomCrypt, modular cryptographic library -- Tom St Denis
24e28a4053SRui Paulo  *
25e28a4053SRui Paulo  * LibTomCrypt is a library that provides various cryptographic
26e28a4053SRui Paulo  * algorithms in a highly modular and flexible manner.
27e28a4053SRui Paulo  *
28e28a4053SRui Paulo  * The library is free for all purposes without any express
29e28a4053SRui Paulo  * guarantee it works.
30e28a4053SRui Paulo  *
31e28a4053SRui Paulo  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
32e28a4053SRui Paulo  */
33e28a4053SRui Paulo 
34e28a4053SRui Paulo /**
35e28a4053SRui Paulo   DES code submitted by Dobes Vandermeer
36e28a4053SRui Paulo */
37e28a4053SRui Paulo 
38e28a4053SRui Paulo #define ROLc(x, y) \
39e28a4053SRui Paulo 	((((unsigned long) (x) << (unsigned long) ((y) & 31)) | \
40e28a4053SRui Paulo 	  (((unsigned long) (x) & 0xFFFFFFFFUL) >> \
41e28a4053SRui Paulo 	   (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
42e28a4053SRui Paulo #define RORc(x, y) \
43e28a4053SRui Paulo 	(((((unsigned long) (x) & 0xFFFFFFFFUL) >> \
44e28a4053SRui Paulo 	   (unsigned long) ((y) & 31)) | \
45e28a4053SRui Paulo 	  ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & \
46e28a4053SRui Paulo 	 0xFFFFFFFFUL)
47e28a4053SRui Paulo 
48e28a4053SRui Paulo 
49e28a4053SRui Paulo static const u32 bytebit[8] =
50e28a4053SRui Paulo {
51e28a4053SRui Paulo 	0200, 0100, 040, 020, 010, 04, 02, 01
52e28a4053SRui Paulo };
53e28a4053SRui Paulo 
54e28a4053SRui Paulo static const u32 bigbyte[24] =
55e28a4053SRui Paulo {
56e28a4053SRui Paulo 	0x800000UL,  0x400000UL,  0x200000UL,  0x100000UL,
57e28a4053SRui Paulo 	0x80000UL,   0x40000UL,   0x20000UL,   0x10000UL,
58e28a4053SRui Paulo 	0x8000UL,    0x4000UL,    0x2000UL,    0x1000UL,
59e28a4053SRui Paulo 	0x800UL,     0x400UL,     0x200UL,     0x100UL,
60e28a4053SRui Paulo 	0x80UL,      0x40UL,      0x20UL,      0x10UL,
61e28a4053SRui Paulo 	0x8UL,       0x4UL,       0x2UL,       0x1L
62e28a4053SRui Paulo };
63e28a4053SRui Paulo 
64e28a4053SRui Paulo /* Use the key schedule specific in the standard (ANSI X3.92-1981) */
65e28a4053SRui Paulo 
66e28a4053SRui Paulo static const u8 pc1[56] = {
67e28a4053SRui Paulo 	56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,
68e28a4053SRui Paulo 	 9,  1, 58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35,
69e28a4053SRui Paulo 	62, 54, 46, 38, 30, 22, 14,  6, 61, 53, 45, 37, 29, 21,
70e28a4053SRui Paulo 	13,  5, 60, 52, 44, 36, 28, 20, 12,  4, 27, 19, 11,  3
71e28a4053SRui Paulo };
72e28a4053SRui Paulo 
73e28a4053SRui Paulo static const u8 totrot[16] = {
74e28a4053SRui Paulo 	1,   2,  4,  6,
75e28a4053SRui Paulo 	8,  10, 12, 14,
76e28a4053SRui Paulo 	15, 17, 19, 21,
77e28a4053SRui Paulo 	23, 25, 27, 28
78e28a4053SRui Paulo };
79e28a4053SRui Paulo 
80e28a4053SRui Paulo static const u8 pc2[48] = {
81e28a4053SRui Paulo 	13, 16, 10, 23,  0,  4,      2, 27, 14,  5, 20,  9,
82e28a4053SRui Paulo 	22, 18, 11,  3, 25,  7,     15,  6, 26, 19, 12,  1,
83e28a4053SRui Paulo 	40, 51, 30, 36, 46, 54,     29, 39, 50, 44, 32, 47,
84e28a4053SRui Paulo 	43, 48, 38, 55, 33, 52,     45, 41, 49, 35, 28, 31
85e28a4053SRui Paulo };
86e28a4053SRui Paulo 
87e28a4053SRui Paulo 
88e28a4053SRui Paulo static const u32 SP1[64] =
89e28a4053SRui Paulo {
90e28a4053SRui Paulo 	0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL,
91e28a4053SRui Paulo 	0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL,
92e28a4053SRui Paulo 	0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL,
93e28a4053SRui Paulo 	0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL,
94e28a4053SRui Paulo 	0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL,
95e28a4053SRui Paulo 	0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL,
96e28a4053SRui Paulo 	0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL,
97e28a4053SRui Paulo 	0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL,
98e28a4053SRui Paulo 	0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL,
99e28a4053SRui Paulo 	0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL,
100e28a4053SRui Paulo 	0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL,
101e28a4053SRui Paulo 	0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL,
102e28a4053SRui Paulo 	0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL,
103e28a4053SRui Paulo 	0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL,
104e28a4053SRui Paulo 	0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL,
105e28a4053SRui Paulo 	0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL
106e28a4053SRui Paulo };
107e28a4053SRui Paulo 
108e28a4053SRui Paulo static const u32 SP2[64] =
109e28a4053SRui Paulo {
110e28a4053SRui Paulo 	0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL,
111e28a4053SRui Paulo 	0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL,
112e28a4053SRui Paulo 	0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL,
113e28a4053SRui Paulo 	0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL,
114e28a4053SRui Paulo 	0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL,
115e28a4053SRui Paulo 	0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL,
116e28a4053SRui Paulo 	0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL,
117e28a4053SRui Paulo 	0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL,
118e28a4053SRui Paulo 	0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL,
119e28a4053SRui Paulo 	0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL,
120e28a4053SRui Paulo 	0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL,
121e28a4053SRui Paulo 	0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL,
122e28a4053SRui Paulo 	0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL,
123e28a4053SRui Paulo 	0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL,
124e28a4053SRui Paulo 	0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL,
125e28a4053SRui Paulo 	0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL
126e28a4053SRui Paulo };
127e28a4053SRui Paulo 
128e28a4053SRui Paulo static const u32 SP3[64] =
129e28a4053SRui Paulo {
130e28a4053SRui Paulo 	0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL,
131e28a4053SRui Paulo 	0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL,
132e28a4053SRui Paulo 	0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL,
133e28a4053SRui Paulo 	0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL,
134e28a4053SRui Paulo 	0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL,
135e28a4053SRui Paulo 	0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL,
136e28a4053SRui Paulo 	0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL,
137e28a4053SRui Paulo 	0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL,
138e28a4053SRui Paulo 	0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL,
139e28a4053SRui Paulo 	0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL,
140e28a4053SRui Paulo 	0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL,
141e28a4053SRui Paulo 	0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL,
142e28a4053SRui Paulo 	0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL,
143e28a4053SRui Paulo 	0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL,
144e28a4053SRui Paulo 	0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL,
145e28a4053SRui Paulo 	0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL
146e28a4053SRui Paulo };
147e28a4053SRui Paulo 
148e28a4053SRui Paulo static const u32 SP4[64] =
149e28a4053SRui Paulo {
150e28a4053SRui Paulo 	0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
151e28a4053SRui Paulo 	0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL,
152e28a4053SRui Paulo 	0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL,
153e28a4053SRui Paulo 	0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL,
154e28a4053SRui Paulo 	0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL,
155e28a4053SRui Paulo 	0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL,
156e28a4053SRui Paulo 	0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL,
157e28a4053SRui Paulo 	0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL,
158e28a4053SRui Paulo 	0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL,
159e28a4053SRui Paulo 	0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL,
160e28a4053SRui Paulo 	0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL,
161e28a4053SRui Paulo 	0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
162e28a4053SRui Paulo 	0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL,
163e28a4053SRui Paulo 	0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL,
164e28a4053SRui Paulo 	0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL,
165e28a4053SRui Paulo 	0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL
166e28a4053SRui Paulo };
167e28a4053SRui Paulo 
168e28a4053SRui Paulo static const u32 SP5[64] =
169e28a4053SRui Paulo {
170e28a4053SRui Paulo 	0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL,
171e28a4053SRui Paulo 	0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL,
172e28a4053SRui Paulo 	0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL,
173e28a4053SRui Paulo 	0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL,
174e28a4053SRui Paulo 	0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL,
175e28a4053SRui Paulo 	0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL,
176e28a4053SRui Paulo 	0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL,
177e28a4053SRui Paulo 	0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL,
178e28a4053SRui Paulo 	0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL,
179e28a4053SRui Paulo 	0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL,
180e28a4053SRui Paulo 	0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL,
181e28a4053SRui Paulo 	0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL,
182e28a4053SRui Paulo 	0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL,
183e28a4053SRui Paulo 	0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL,
184e28a4053SRui Paulo 	0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL,
185e28a4053SRui Paulo 	0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL
186e28a4053SRui Paulo };
187e28a4053SRui Paulo 
188e28a4053SRui Paulo static const u32 SP6[64] =
189e28a4053SRui Paulo {
190e28a4053SRui Paulo 	0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL,
191e28a4053SRui Paulo 	0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL,
192e28a4053SRui Paulo 	0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL,
193e28a4053SRui Paulo 	0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
194e28a4053SRui Paulo 	0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL,
195e28a4053SRui Paulo 	0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL,
196e28a4053SRui Paulo 	0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL,
197e28a4053SRui Paulo 	0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL,
198e28a4053SRui Paulo 	0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL,
199e28a4053SRui Paulo 	0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL,
200e28a4053SRui Paulo 	0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
201e28a4053SRui Paulo 	0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL,
202e28a4053SRui Paulo 	0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL,
203e28a4053SRui Paulo 	0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL,
204e28a4053SRui Paulo 	0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL,
205e28a4053SRui Paulo 	0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL
206e28a4053SRui Paulo };
207e28a4053SRui Paulo 
208e28a4053SRui Paulo static const u32 SP7[64] =
209e28a4053SRui Paulo {
210e28a4053SRui Paulo 	0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL,
211e28a4053SRui Paulo 	0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL,
212e28a4053SRui Paulo 	0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL,
213e28a4053SRui Paulo 	0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL,
214e28a4053SRui Paulo 	0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL,
215e28a4053SRui Paulo 	0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL,
216e28a4053SRui Paulo 	0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL,
217e28a4053SRui Paulo 	0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL,
218e28a4053SRui Paulo 	0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL,
219e28a4053SRui Paulo 	0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL,
220e28a4053SRui Paulo 	0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL,
221e28a4053SRui Paulo 	0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL,
222e28a4053SRui Paulo 	0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL,
223e28a4053SRui Paulo 	0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL,
224e28a4053SRui Paulo 	0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL,
225e28a4053SRui Paulo 	0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL
226e28a4053SRui Paulo };
227e28a4053SRui Paulo 
228e28a4053SRui Paulo static const u32 SP8[64] =
229e28a4053SRui Paulo {
230e28a4053SRui Paulo 	0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL,
231e28a4053SRui Paulo 	0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL,
232e28a4053SRui Paulo 	0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL,
233e28a4053SRui Paulo 	0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL,
234e28a4053SRui Paulo 	0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL,
235e28a4053SRui Paulo 	0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL,
236e28a4053SRui Paulo 	0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL,
237e28a4053SRui Paulo 	0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL,
238e28a4053SRui Paulo 	0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL,
239e28a4053SRui Paulo 	0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL,
240e28a4053SRui Paulo 	0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL,
241e28a4053SRui Paulo 	0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL,
242e28a4053SRui Paulo 	0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL,
243e28a4053SRui Paulo 	0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL,
244e28a4053SRui Paulo 	0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL,
245e28a4053SRui Paulo 	0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL
246e28a4053SRui Paulo };
247e28a4053SRui Paulo 
248e28a4053SRui Paulo 
cookey(const u32 * raw1,u32 * keyout)249e28a4053SRui Paulo static void cookey(const u32 *raw1, u32 *keyout)
250e28a4053SRui Paulo {
251e28a4053SRui Paulo 	u32 *cook;
252e28a4053SRui Paulo 	const u32 *raw0;
253e28a4053SRui Paulo 	u32 dough[32];
254e28a4053SRui Paulo 	int i;
255e28a4053SRui Paulo 
256e28a4053SRui Paulo 	cook = dough;
257e28a4053SRui Paulo 	for (i = 0; i < 16; i++, raw1++) {
258e28a4053SRui Paulo 		raw0 = raw1++;
259e28a4053SRui Paulo 		*cook    = (*raw0 & 0x00fc0000L) << 6;
260e28a4053SRui Paulo 		*cook   |= (*raw0 & 0x00000fc0L) << 10;
261e28a4053SRui Paulo 		*cook   |= (*raw1 & 0x00fc0000L) >> 10;
262e28a4053SRui Paulo 		*cook++ |= (*raw1 & 0x00000fc0L) >> 6;
263e28a4053SRui Paulo 		*cook    = (*raw0 & 0x0003f000L) << 12;
264e28a4053SRui Paulo 		*cook   |= (*raw0 & 0x0000003fL) << 16;
265e28a4053SRui Paulo 		*cook   |= (*raw1 & 0x0003f000L) >> 4;
266e28a4053SRui Paulo 		*cook++ |= (*raw1 & 0x0000003fL);
267e28a4053SRui Paulo 	}
268e28a4053SRui Paulo 
269e28a4053SRui Paulo 	os_memcpy(keyout, dough, sizeof(dough));
270e28a4053SRui Paulo }
271e28a4053SRui Paulo 
272e28a4053SRui Paulo 
deskey(const u8 * key,int decrypt,u32 * keyout)273e28a4053SRui Paulo static void deskey(const u8 *key, int decrypt, u32 *keyout)
274e28a4053SRui Paulo {
275e28a4053SRui Paulo 	u32 i, j, l, m, n, kn[32];
276e28a4053SRui Paulo 	u8 pc1m[56], pcr[56];
277e28a4053SRui Paulo 
278e28a4053SRui Paulo 	for (j = 0; j < 56; j++) {
279e28a4053SRui Paulo 		l = (u32) pc1[j];
280e28a4053SRui Paulo 		m = l & 7;
281e28a4053SRui Paulo 		pc1m[j] = (u8)
282e28a4053SRui Paulo 			((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0);
283e28a4053SRui Paulo 	}
284e28a4053SRui Paulo 
285e28a4053SRui Paulo 	for (i = 0; i < 16; i++) {
286e28a4053SRui Paulo 		if (decrypt)
287e28a4053SRui Paulo 			m = (15 - i) << 1;
288e28a4053SRui Paulo 		else
289e28a4053SRui Paulo 			m = i << 1;
290e28a4053SRui Paulo 		n = m + 1;
291e28a4053SRui Paulo 		kn[m] = kn[n] = 0L;
292e28a4053SRui Paulo 		for (j = 0; j < 28; j++) {
293e28a4053SRui Paulo 			l = j + (u32) totrot[i];
294e28a4053SRui Paulo 			if (l < 28)
295e28a4053SRui Paulo 				pcr[j] = pc1m[l];
296e28a4053SRui Paulo 			else
297e28a4053SRui Paulo 				pcr[j] = pc1m[l - 28];
298e28a4053SRui Paulo 		}
299e28a4053SRui Paulo 		for (/* j = 28 */; j < 56; j++) {
300e28a4053SRui Paulo 			l = j + (u32) totrot[i];
301e28a4053SRui Paulo 			if (l < 56)
302e28a4053SRui Paulo 				pcr[j] = pc1m[l];
303e28a4053SRui Paulo 			else
304e28a4053SRui Paulo 				pcr[j] = pc1m[l - 28];
305e28a4053SRui Paulo 		}
306e28a4053SRui Paulo 		for (j = 0; j < 24; j++) {
307e28a4053SRui Paulo 			if ((int) pcr[(int) pc2[j]] != 0)
308e28a4053SRui Paulo 				kn[m] |= bigbyte[j];
309e28a4053SRui Paulo 			if ((int) pcr[(int) pc2[j + 24]] != 0)
310e28a4053SRui Paulo 				kn[n] |= bigbyte[j];
311e28a4053SRui Paulo 		}
312e28a4053SRui Paulo 	}
313e28a4053SRui Paulo 
314e28a4053SRui Paulo 	cookey(kn, keyout);
315e28a4053SRui Paulo }
316e28a4053SRui Paulo 
317e28a4053SRui Paulo 
desfunc(u32 * block,const u32 * keys)318e28a4053SRui Paulo static void desfunc(u32 *block, const u32 *keys)
319e28a4053SRui Paulo {
320e28a4053SRui Paulo 	u32 work, right, leftt;
321e28a4053SRui Paulo 	int cur_round;
322e28a4053SRui Paulo 
323e28a4053SRui Paulo 	leftt = block[0];
324e28a4053SRui Paulo 	right = block[1];
325e28a4053SRui Paulo 
326e28a4053SRui Paulo 	work = ((leftt >> 4)  ^ right) & 0x0f0f0f0fL;
327e28a4053SRui Paulo 	right ^= work;
328e28a4053SRui Paulo 	leftt ^= (work << 4);
329e28a4053SRui Paulo 
330e28a4053SRui Paulo 	work = ((leftt >> 16) ^ right) & 0x0000ffffL;
331e28a4053SRui Paulo 	right ^= work;
332e28a4053SRui Paulo 	leftt ^= (work << 16);
333e28a4053SRui Paulo 
334e28a4053SRui Paulo 	work = ((right >> 2)  ^ leftt) & 0x33333333L;
335e28a4053SRui Paulo 	leftt ^= work;
336e28a4053SRui Paulo 	right ^= (work << 2);
337e28a4053SRui Paulo 
338e28a4053SRui Paulo 	work = ((right >> 8)  ^ leftt) & 0x00ff00ffL;
339e28a4053SRui Paulo 	leftt ^= work;
340e28a4053SRui Paulo 	right ^= (work << 8);
341e28a4053SRui Paulo 
342e28a4053SRui Paulo 	right = ROLc(right, 1);
343e28a4053SRui Paulo 	work = (leftt ^ right) & 0xaaaaaaaaL;
344e28a4053SRui Paulo 
345e28a4053SRui Paulo 	leftt ^= work;
346e28a4053SRui Paulo 	right ^= work;
347e28a4053SRui Paulo 	leftt = ROLc(leftt, 1);
348e28a4053SRui Paulo 
349e28a4053SRui Paulo 	for (cur_round = 0; cur_round < 8; cur_round++) {
350e28a4053SRui Paulo 		work  = RORc(right, 4) ^ *keys++;
351e28a4053SRui Paulo 		leftt ^= SP7[work        & 0x3fL]
352e28a4053SRui Paulo 			^ SP5[(work >>  8) & 0x3fL]
353e28a4053SRui Paulo 			^ SP3[(work >> 16) & 0x3fL]
354e28a4053SRui Paulo 			^ SP1[(work >> 24) & 0x3fL];
355e28a4053SRui Paulo 		work  = right ^ *keys++;
356e28a4053SRui Paulo 		leftt ^= SP8[ work        & 0x3fL]
357e28a4053SRui Paulo 			^  SP6[(work >>  8) & 0x3fL]
358e28a4053SRui Paulo 			^  SP4[(work >> 16) & 0x3fL]
359e28a4053SRui Paulo 			^  SP2[(work >> 24) & 0x3fL];
360e28a4053SRui Paulo 
361e28a4053SRui Paulo 		work = RORc(leftt, 4) ^ *keys++;
362e28a4053SRui Paulo 		right ^= SP7[ work        & 0x3fL]
363e28a4053SRui Paulo 			^  SP5[(work >>  8) & 0x3fL]
364e28a4053SRui Paulo 			^  SP3[(work >> 16) & 0x3fL]
365e28a4053SRui Paulo 			^  SP1[(work >> 24) & 0x3fL];
366e28a4053SRui Paulo 		work  = leftt ^ *keys++;
367e28a4053SRui Paulo 		right ^= SP8[ work        & 0x3fL]
368e28a4053SRui Paulo 			^  SP6[(work >>  8) & 0x3fL]
369e28a4053SRui Paulo 			^  SP4[(work >> 16) & 0x3fL]
370e28a4053SRui Paulo 			^  SP2[(work >> 24) & 0x3fL];
371e28a4053SRui Paulo 	}
372e28a4053SRui Paulo 
373e28a4053SRui Paulo 	right = RORc(right, 1);
374e28a4053SRui Paulo 	work = (leftt ^ right) & 0xaaaaaaaaL;
375e28a4053SRui Paulo 	leftt ^= work;
376e28a4053SRui Paulo 	right ^= work;
377e28a4053SRui Paulo 	leftt = RORc(leftt, 1);
378e28a4053SRui Paulo 	work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
379e28a4053SRui Paulo 	right ^= work;
380e28a4053SRui Paulo 	leftt ^= (work << 8);
381e28a4053SRui Paulo 	/* -- */
382e28a4053SRui Paulo 	work = ((leftt >> 2) ^ right) & 0x33333333L;
383e28a4053SRui Paulo 	right ^= work;
384e28a4053SRui Paulo 	leftt ^= (work << 2);
385e28a4053SRui Paulo 	work = ((right >> 16) ^ leftt) & 0x0000ffffL;
386e28a4053SRui Paulo 	leftt ^= work;
387e28a4053SRui Paulo 	right ^= (work << 16);
388e28a4053SRui Paulo 	work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
389e28a4053SRui Paulo 	leftt ^= work;
390e28a4053SRui Paulo 	right ^= (work << 4);
391e28a4053SRui Paulo 
392e28a4053SRui Paulo 	block[0] = right;
393e28a4053SRui Paulo 	block[1] = leftt;
394e28a4053SRui Paulo }
395e28a4053SRui Paulo 
396e28a4053SRui Paulo 
397e28a4053SRui Paulo /* wpa_supplicant/hostapd specific wrapper */
398e28a4053SRui Paulo 
des_encrypt(const u8 * clear,const u8 * key,u8 * cypher)399*85732ac8SCy Schubert int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
400e28a4053SRui Paulo {
401e28a4053SRui Paulo 	u8 pkey[8], next, tmp;
402e28a4053SRui Paulo 	int i;
403e28a4053SRui Paulo 	u32 ek[32], work[2];
404e28a4053SRui Paulo 
405e28a4053SRui Paulo 	/* Add parity bits to the key */
406e28a4053SRui Paulo 	next = 0;
407e28a4053SRui Paulo 	for (i = 0; i < 7; i++) {
408e28a4053SRui Paulo 		tmp = key[i];
409e28a4053SRui Paulo 		pkey[i] = (tmp >> i) | next | 1;
410e28a4053SRui Paulo 		next = tmp << (7 - i);
411e28a4053SRui Paulo 	}
412e28a4053SRui Paulo 	pkey[i] = next | 1;
413e28a4053SRui Paulo 
414e28a4053SRui Paulo 	deskey(pkey, 0, ek);
415e28a4053SRui Paulo 
416e28a4053SRui Paulo 	work[0] = WPA_GET_BE32(clear);
417e28a4053SRui Paulo 	work[1] = WPA_GET_BE32(clear + 4);
418e28a4053SRui Paulo 	desfunc(work, ek);
419e28a4053SRui Paulo 	WPA_PUT_BE32(cypher, work[0]);
420e28a4053SRui Paulo 	WPA_PUT_BE32(cypher + 4, work[1]);
421e28a4053SRui Paulo 
422e28a4053SRui Paulo 	os_memset(pkey, 0, sizeof(pkey));
423e28a4053SRui Paulo 	os_memset(ek, 0, sizeof(ek));
424*85732ac8SCy Schubert 	return 0;
425e28a4053SRui Paulo }
426e28a4053SRui Paulo 
427e28a4053SRui Paulo 
des_key_setup(const u8 * key,u32 * ek,u32 * dk)428e28a4053SRui Paulo void des_key_setup(const u8 *key, u32 *ek, u32 *dk)
429e28a4053SRui Paulo {
430e28a4053SRui Paulo 	deskey(key, 0, ek);
431e28a4053SRui Paulo 	deskey(key, 1, dk);
432e28a4053SRui Paulo }
433e28a4053SRui Paulo 
434e28a4053SRui Paulo 
des_block_encrypt(const u8 * plain,const u32 * ek,u8 * crypt)435e28a4053SRui Paulo void des_block_encrypt(const u8 *plain, const u32 *ek, u8 *crypt)
436e28a4053SRui Paulo {
437e28a4053SRui Paulo 	u32 work[2];
438e28a4053SRui Paulo 	work[0] = WPA_GET_BE32(plain);
439e28a4053SRui Paulo 	work[1] = WPA_GET_BE32(plain + 4);
440e28a4053SRui Paulo 	desfunc(work, ek);
441e28a4053SRui Paulo 	WPA_PUT_BE32(crypt, work[0]);
442e28a4053SRui Paulo 	WPA_PUT_BE32(crypt + 4, work[1]);
443e28a4053SRui Paulo }
444e28a4053SRui Paulo 
445e28a4053SRui Paulo 
des_block_decrypt(const u8 * crypt,const u32 * dk,u8 * plain)446e28a4053SRui Paulo void des_block_decrypt(const u8 *crypt, const u32 *dk, u8 *plain)
447e28a4053SRui Paulo {
448e28a4053SRui Paulo 	u32 work[2];
449e28a4053SRui Paulo 	work[0] = WPA_GET_BE32(crypt);
450e28a4053SRui Paulo 	work[1] = WPA_GET_BE32(crypt + 4);
451e28a4053SRui Paulo 	desfunc(work, dk);
452e28a4053SRui Paulo 	WPA_PUT_BE32(plain, work[0]);
453e28a4053SRui Paulo 	WPA_PUT_BE32(plain + 4, work[1]);
454e28a4053SRui Paulo }
455e28a4053SRui Paulo 
456e28a4053SRui Paulo 
des3_key_setup(const u8 * key,struct des3_key_s * dkey)457e28a4053SRui Paulo void des3_key_setup(const u8 *key, struct des3_key_s *dkey)
458e28a4053SRui Paulo {
459e28a4053SRui Paulo 	deskey(key, 0, dkey->ek[0]);
460e28a4053SRui Paulo 	deskey(key + 8, 1, dkey->ek[1]);
461e28a4053SRui Paulo 	deskey(key + 16, 0, dkey->ek[2]);
462e28a4053SRui Paulo 
463e28a4053SRui Paulo 	deskey(key, 1, dkey->dk[2]);
464e28a4053SRui Paulo 	deskey(key + 8, 0, dkey->dk[1]);
465e28a4053SRui Paulo 	deskey(key + 16, 1, dkey->dk[0]);
466e28a4053SRui Paulo }
467e28a4053SRui Paulo 
468e28a4053SRui Paulo 
des3_encrypt(const u8 * plain,const struct des3_key_s * key,u8 * crypt)469e28a4053SRui Paulo void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt)
470e28a4053SRui Paulo {
471e28a4053SRui Paulo 	u32 work[2];
472e28a4053SRui Paulo 
473e28a4053SRui Paulo 	work[0] = WPA_GET_BE32(plain);
474e28a4053SRui Paulo 	work[1] = WPA_GET_BE32(plain + 4);
475e28a4053SRui Paulo 	desfunc(work, key->ek[0]);
476e28a4053SRui Paulo 	desfunc(work, key->ek[1]);
477e28a4053SRui Paulo 	desfunc(work, key->ek[2]);
478e28a4053SRui Paulo 	WPA_PUT_BE32(crypt, work[0]);
479e28a4053SRui Paulo 	WPA_PUT_BE32(crypt + 4, work[1]);
480e28a4053SRui Paulo }
481e28a4053SRui Paulo 
482e28a4053SRui Paulo 
des3_decrypt(const u8 * crypt,const struct des3_key_s * key,u8 * plain)483e28a4053SRui Paulo void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain)
484e28a4053SRui Paulo {
485e28a4053SRui Paulo 	u32 work[2];
486e28a4053SRui Paulo 
487e28a4053SRui Paulo 	work[0] = WPA_GET_BE32(crypt);
488e28a4053SRui Paulo 	work[1] = WPA_GET_BE32(crypt + 4);
489e28a4053SRui Paulo 	desfunc(work, key->dk[0]);
490e28a4053SRui Paulo 	desfunc(work, key->dk[1]);
491e28a4053SRui Paulo 	desfunc(work, key->dk[2]);
492e28a4053SRui Paulo 	WPA_PUT_BE32(plain, work[0]);
493e28a4053SRui Paulo 	WPA_PUT_BE32(plain + 4, work[1]);
494e28a4053SRui Paulo }
495