3c9b1d58eab5e9b9082afbdf290d65770fada593
[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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 KeyShift(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 sbox(unsigned char *dst, const unsigned char *src)
194 {
195 int i;
196
197 for (i = 0; i < 4; i++)
198 dst[i] = 0;
199
200 for (i = 0; i < 8; i++)
201 {
202 int j, Snum, bitnum;
203
204 for (Snum = j = 0, bitnum = (i * 6); j < 6; j++, bitnum++)
205 {
206 Snum <<= 1;
207 Snum |= GETBIT(src, bitnum);
208 }
209
210 if (0 == (i%2))
211 dst[i/2] |= ((SBox[i][Snum]) << 4);
212 else
213 dst[i/2] |= SBox[i][Snum];
214 }
215 }
216
217 static void xor(unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count)
218 {
219 int i;
220
221 for (i = 0; i < count; i++)
222 dst[i] = a[i] ^ b[i];
223 }
224
225 unsigned char *CRYPT_DESkey8to7(unsigned char *dst, const unsigned char *key)
226 {
227 int i;
228 unsigned char tmp[7];
229 static const unsigned char map8to7[56] =
230 {
231 0, 1, 2, 3, 4, 5, 6,
232 8, 9, 10, 11, 12, 13, 14,
233 16, 17, 18, 19, 20, 21, 22,
234 24, 25, 26, 27, 28, 29, 30,
235 32, 33, 34, 35, 36, 37, 38,
236 40, 41, 42, 43, 44, 45, 46,
237 48, 49, 50, 51, 52, 53, 54,
238 56, 57, 58, 59, 60, 61, 62
239 };
240
241 if ((dst == NULL) || (key == NULL))
242 return NULL;
243
244 Permute(tmp, key, map8to7, 7);
245
246 for (i = 0; i < 7; i++)
247 dst[i] = tmp[i];
248
249 return dst;
250 }
251
252
253 unsigned char *CRYPT_DEShash(unsigned char *dst, const unsigned char *key, const unsigned char *src)
254 {
255 int i;
256 unsigned char K[7];
257 unsigned char D[8];
258
259 Permute(K, key, KeyPermuteMap, 7);
260 Permute(D, src, InitialPermuteMap, 8);
261
262 for (i = 0; i < 16; i++)
263 {
264 int j;
265 unsigned char *L = D;
266 unsigned char *R = &(D[4]);
267 unsigned char Rexp[6];
268 unsigned char Rn[4];
269 unsigned char SubK[6];
270
271 KeyShift(K, KeyRotation[i]);
272 Permute(SubK, K, KeyCompression, 6);
273
274 Permute(Rexp, R, DataExpansion, 6);
275 xor(Rexp, Rexp, SubK, 6);
276
277 sbox(Rn, Rexp);
278 Permute(Rexp, Rn, PBox, 4);
279 xor(Rn, L, Rexp, 4);
280
281 for (j = 0; j < 4; j++)
282 {
283 L[j] = R[j];
284 R[j] = Rn[j];
285 }
286 }
287
288 Permute(dst, D, FinalPermuteMap, 8);
289
290 return dst;
291 }