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