1 /*
2 * Copyright 2004 Hans Leidekker
3 * Copyright 2006 Mike McCormack
4 *
5 * Based on DES.c from libcifs
6 *
7 * Copyright (C) 2003, 2004 by Christopher R. Hertel
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24 #ifdef __REACTOS__
25 #include <advapi32.h>
26 #else
27 #include "windef.h"
28 #include "crypt.h"
29 #endif
30
31 static const unsigned char InitialPermuteMap[64] =
32 {
33 57, 49, 41, 33, 25, 17, 9, 1,
34 59, 51, 43, 35, 27, 19, 11, 3,
35 61, 53, 45, 37, 29, 21, 13, 5,
36 63, 55, 47, 39, 31, 23, 15, 7,
37 56, 48, 40, 32, 24, 16, 8, 0,
38 58, 50, 42, 34, 26, 18, 10, 2,
39 60, 52, 44, 36, 28, 20, 12, 4,
40 62, 54, 46, 38, 30, 22, 14, 6
41 };
42
43 static const unsigned char KeyPermuteMap[56] =
44 {
45 49, 42, 35, 28, 21, 14, 7, 0,
46 50, 43, 36, 29, 22, 15, 8, 1,
47 51, 44, 37, 30, 23, 16, 9, 2,
48 52, 45, 38, 31, 55, 48, 41, 34,
49 27, 20, 13, 6, 54, 47, 40, 33,
50 26, 19, 12, 5, 53, 46, 39, 32,
51 25, 18, 11, 4, 24, 17, 10, 3,
52 };
53
54 static const unsigned char KeyRotation[16] =
55 { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
56
57 static const unsigned char KeyCompression[48] =
58 {
59 13, 16, 10, 23, 0, 4, 2, 27,
60 14, 5, 20, 9, 22, 18, 11, 3,
61 25, 7, 15, 6, 26, 19, 12, 1,
62 40, 51, 30, 36, 46, 54, 29, 39,
63 50, 44, 32, 47, 43, 48, 38, 55,
64 33, 52, 45, 41, 49, 35, 28, 31
65 };
66
67 static const unsigned char DataExpansion[48] =
68 {
69 31, 0, 1, 2, 3, 4, 3, 4,
70 5, 6, 7, 8, 7, 8, 9, 10,
71 11, 12, 11, 12, 13, 14, 15, 16,
72 15, 16, 17, 18, 19, 20, 19, 20,
73 21, 22, 23, 24, 23, 24, 25, 26,
74 27, 28, 27, 28, 29, 30, 31, 0
75 };
76
77 static const unsigned char SBox[8][64] =
78 {
79 { /* S0 */
80 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
81 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
82 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
83 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
84 },
85 { /* S1 */
86 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
87 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
88 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
89 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
90 },
91 { /* S2 */
92 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
93 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
94 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
95 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
96 },
97 { /* S3 */
98 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
99 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
100 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
101 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
102 },
103 { /* S4 */
104 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
105 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
106 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
107 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
108 },
109 { /* S5 */
110 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
111 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
112 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
113 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
114 },
115 { /* S6 */
116 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
117 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
118 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
119 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
120 },
121 { /* S7 */
122 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
123 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
124 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
125 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
126 }
127 };
128
129 static const unsigned char PBox[32] =
130 {
131 15, 6, 19, 20, 28, 11, 27, 16,
132 0, 14, 22, 25, 4, 17, 30, 9,
133 1, 7, 23, 13, 31, 26, 2, 8,
134 18, 12, 29, 5, 21, 10, 3, 24
135 };
136
137 static const unsigned char FinalPermuteMap[64] =
138 {
139 7, 39, 15, 47, 23, 55, 31, 63,
140 6, 38, 14, 46, 22, 54, 30, 62,
141 5, 37, 13, 45, 21, 53, 29, 61,
142 4, 36, 12, 44, 20, 52, 28, 60,
143 3, 35, 11, 43, 19, 51, 27, 59,
144 2, 34, 10, 42, 18, 50, 26, 58,
145 1, 33, 9, 41, 17, 49, 25, 57,
146 0, 32, 8, 40, 16, 48, 24, 56
147 };
148
149 #define CLRBIT( STR, IDX ) ( (STR)[(IDX)/8] &= ~(0x01 << (7 - ((IDX)%8))) )
150 #define SETBIT( STR, IDX ) ( (STR)[(IDX)/8] |= (0x01 << (7 - ((IDX)%8))) )
151 #define GETBIT( STR, IDX ) (( ((STR)[(IDX)/8]) >> (7 - ((IDX)%8)) ) & 0x01)
152
Permute(unsigned char * dst,const unsigned char * src,const unsigned char * map,const int mapsize)153 static void Permute( unsigned char *dst, const unsigned char *src, const unsigned char *map, const int mapsize )
154 {
155 int bitcount, i;
156
157 for (i = 0; i < mapsize; i++)
158 dst[i] = 0;
159
160 bitcount = mapsize * 8;
161
162 for (i = 0; i < bitcount; i++)
163 {
164 if (GETBIT( src, map[i] ))
165 SETBIT( dst, i );
166 }
167 }
168
KeyShiftLeft(unsigned char * key,const int numbits)169 static void KeyShiftLeft( unsigned char *key, const int numbits )
170 {
171 int i;
172 unsigned char keep = key[0];
173
174 for (i = 0; i < numbits; i++)
175 {
176 int j;
177
178 for (j = 0; j < 7; j++)
179 {
180 if (j && (key[j] & 0x80))
181 key[j-1] |= 0x01;
182 key[j] <<= 1;
183 }
184
185 if (GETBIT( key, 27 ))
186 {
187 CLRBIT( key, 27 );
188 SETBIT( key, 55 );
189 }
190
191 if (keep & 0x80)
192 SETBIT( key, 27 );
193
194 keep <<= 1;
195 }
196 }
197
KeyShiftRight(unsigned char * key,const int numbits)198 static void KeyShiftRight( unsigned char *key, const int numbits )
199 {
200 int i;
201 unsigned char keep = key[6];
202
203 for (i = 0; i < numbits; i++)
204 {
205 int j;
206
207 for (j = 6; j >= 0; j--)
208 {
209 if (j!=6 && (key[j] & 0x01))
210 key[j+1] |= 0x80;
211 key[j] >>= 1;
212 }
213
214 if (GETBIT( key, 28 ))
215 {
216 CLRBIT( key, 28 );
217 SETBIT( key, 0 );
218 }
219
220 if (keep & 0x01)
221 SETBIT( key, 28 );
222
223 keep >>= 1;
224 }
225 }
226
sbox(unsigned char * dst,const unsigned char * src)227 static void sbox( unsigned char *dst, const unsigned char *src )
228 {
229 int i;
230
231 for (i = 0; i < 4; i++)
232 dst[i] = 0;
233
234 for (i = 0; i < 8; i++)
235 {
236 int j, Snum, bitnum;
237
238 for (Snum = j = 0, bitnum = (i * 6); j < 6; j++, bitnum++)
239 {
240 Snum <<= 1;
241 Snum |= GETBIT( src, bitnum );
242 }
243
244 if (0 == (i%2))
245 dst[i/2] |= ((SBox[i][Snum]) << 4);
246 else
247 dst[i/2] |= SBox[i][Snum];
248 }
249 }
250
xor(unsigned char * dst,const unsigned char * a,const unsigned char * b,const int count)251 static void xor( unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count )
252 {
253 int i;
254
255 for (i = 0; i < count; i++)
256 dst[i] = a[i] ^ b[i];
257 }
258
CRYPT_DEShash(unsigned char * dst,const unsigned char * key,const unsigned char * src)259 unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key, const unsigned char *src )
260 {
261 int i;
262 unsigned char K[7];
263 unsigned char D[8];
264
265 Permute( K, key, KeyPermuteMap, 7 );
266 Permute( D, src, InitialPermuteMap, 8 );
267
268 for (i = 0; i < 16; i++)
269 {
270 int j;
271 unsigned char *L = D;
272 unsigned char *R = &(D[4]);
273 unsigned char Rexp[6];
274 unsigned char Rn[4];
275 unsigned char SubK[6];
276
277 KeyShiftLeft( K, KeyRotation[i] );
278 Permute( SubK, K, KeyCompression, 6 );
279
280 Permute( Rexp, R, DataExpansion, 6 );
281 xor( Rexp, Rexp, SubK, 6 );
282
283 sbox( Rn, Rexp );
284 Permute( Rexp, Rn, PBox, 4 );
285 xor( Rn, L, Rexp, 4 );
286
287 for (j = 0; j < 4; j++)
288 {
289 L[j] = R[j];
290 R[j] = Rn[j];
291 }
292 }
293
294 Permute( dst, D, FinalPermuteMap, 8 );
295
296 return dst;
297 }
298
CRYPT_DESunhash(unsigned char * dst,const unsigned char * key,const unsigned char * src)299 unsigned char *CRYPT_DESunhash( unsigned char *dst, const unsigned char *key, const unsigned char *src )
300 {
301 int i;
302 unsigned char K[7];
303 unsigned char D[8];
304
305 Permute( K, key, KeyPermuteMap, 7 );
306 Permute( D, src, InitialPermuteMap, 8 );
307
308 for (i = 0; i < 16; i++)
309 {
310 int j;
311 unsigned char *L = D;
312 unsigned char *R = &(D[4]);
313 unsigned char Rexp[6];
314 unsigned char Rn[4];
315 unsigned char SubK[6];
316
317 Permute( SubK, K, KeyCompression, 6 );
318
319 Permute( Rexp, R, DataExpansion, 6 );
320 xor( Rexp, Rexp, SubK, 6 );
321
322 sbox( Rn, Rexp );
323 Permute( Rexp, Rn, PBox, 4 );
324 xor( Rn, L, Rexp, 4 );
325
326 for (j = 0; j < 4; j++)
327 {
328 L[j] = R[j];
329 R[j] = Rn[j];
330 }
331
332 KeyShiftRight( K, KeyRotation[15 - i] );
333 }
334
335 Permute( dst, D, FinalPermuteMap, 8 );
336
337 return dst;
338 }
339