source: trunk/src/advapi32/crypt_des.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

  • Property svn:eol-style set to native
File size: 9.8 KB
RevLine 
[21326]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#include "windef.h"
25#include "crypt.h"
26
27static const unsigned char InitialPermuteMap[64] =
28{
29 57, 49, 41, 33, 25, 17, 9, 1,
30 59, 51, 43, 35, 27, 19, 11, 3,
31 61, 53, 45, 37, 29, 21, 13, 5,
32 63, 55, 47, 39, 31, 23, 15, 7,
33 56, 48, 40, 32, 24, 16, 8, 0,
34 58, 50, 42, 34, 26, 18, 10, 2,
35 60, 52, 44, 36, 28, 20, 12, 4,
36 62, 54, 46, 38, 30, 22, 14, 6
37 };
38
39static const unsigned char KeyPermuteMap[56] =
40{
41 49, 42, 35, 28, 21, 14, 7, 0,
42 50, 43, 36, 29, 22, 15, 8, 1,
43 51, 44, 37, 30, 23, 16, 9, 2,
44 52, 45, 38, 31, 55, 48, 41, 34,
45 27, 20, 13, 6, 54, 47, 40, 33,
46 26, 19, 12, 5, 53, 46, 39, 32,
47 25, 18, 11, 4, 24, 17, 10, 3,
48};
49
50static const unsigned char KeyRotation[16] =
51 { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
52
53static const unsigned char KeyCompression[48] =
54{
55 13, 16, 10, 23, 0, 4, 2, 27,
56 14, 5, 20, 9, 22, 18, 11, 3,
57 25, 7, 15, 6, 26, 19, 12, 1,
58 40, 51, 30, 36, 46, 54, 29, 39,
59 50, 44, 32, 47, 43, 48, 38, 55,
60 33, 52, 45, 41, 49, 35, 28, 31
61};
62
63static const unsigned char DataExpansion[48] =
64{
65 31, 0, 1, 2, 3, 4, 3, 4,
66 5, 6, 7, 8, 7, 8, 9, 10,
67 11, 12, 11, 12, 13, 14, 15, 16,
68 15, 16, 17, 18, 19, 20, 19, 20,
69 21, 22, 23, 24, 23, 24, 25, 26,
70 27, 28, 27, 28, 29, 30, 31, 0
71};
72
73static const unsigned char SBox[8][64] =
74{
75 { /* S0 */
76 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
77 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
78 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
79 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
80 },
81 { /* S1 */
82 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
83 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
84 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
85 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
86 },
87 { /* S2 */
88 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
89 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
90 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
91 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
92 },
93 { /* S3 */
94 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
95 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
96 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
97 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
98 },
99 { /* S4 */
100 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
101 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
102 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
103 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
104 },
105 { /* S5 */
106 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
107 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
108 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
109 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
110 },
111 { /* S6 */
112 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
113 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
114 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
115 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
116 },
117 { /* S7 */
118 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
119 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
120 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
121 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
122 }
123};
124
125static const unsigned char PBox[32] =
126{
127 15, 6, 19, 20, 28, 11, 27, 16,
128 0, 14, 22, 25, 4, 17, 30, 9,
129 1, 7, 23, 13, 31, 26, 2, 8,
130 18, 12, 29, 5, 21, 10, 3, 24
131};
132
133static const unsigned char FinalPermuteMap[64] =
134{
135 7, 39, 15, 47, 23, 55, 31, 63,
136 6, 38, 14, 46, 22, 54, 30, 62,
137 5, 37, 13, 45, 21, 53, 29, 61,
138 4, 36, 12, 44, 20, 52, 28, 60,
139 3, 35, 11, 43, 19, 51, 27, 59,
140 2, 34, 10, 42, 18, 50, 26, 58,
141 1, 33, 9, 41, 17, 49, 25, 57,
142 0, 32, 8, 40, 16, 48, 24, 56
143};
144
145#define CLRBIT( STR, IDX ) ( (STR)[(IDX)/8] &= ~(0x01 << (7 - ((IDX)%8))) )
146#define SETBIT( STR, IDX ) ( (STR)[(IDX)/8] |= (0x01 << (7 - ((IDX)%8))) )
147#define GETBIT( STR, IDX ) (( ((STR)[(IDX)/8]) >> (7 - ((IDX)%8)) ) & 0x01)
148
149static void Permute( unsigned char *dst, const unsigned char *src, const unsigned char *map, const int mapsize )
150{
151 int bitcount, i;
152
153 for (i = 0; i < mapsize; i++)
154 dst[i] = 0;
155
156 bitcount = mapsize * 8;
157
158 for (i = 0; i < bitcount; i++)
159 {
160 if (GETBIT( src, map[i] ))
161 SETBIT( dst, i );
162 }
163}
164
165static void KeyShiftLeft( unsigned char *key, const int numbits )
166{
167 int i;
168 unsigned char keep = key[0];
169
170 for (i = 0; i < numbits; i++)
171 {
172 int j;
173
174 for (j = 0; j < 7; j++)
175 {
176 if (j && (key[j] & 0x80))
177 key[j-1] |= 0x01;
178 key[j] <<= 1;
179 }
180
181 if (GETBIT( key, 27 ))
182 {
183 CLRBIT( key, 27 );
184 SETBIT( key, 55 );
185 }
186
187 if (keep & 0x80)
188 SETBIT( key, 27 );
189
190 keep <<= 1;
191 }
192}
193
194static void KeyShiftRight( unsigned char *key, const int numbits )
195{
196 int i;
197 unsigned char keep = key[6];
198
199 for (i = 0; i < numbits; i++)
200 {
201 int j;
202
203 for (j = 6; j >= 0; j--)
204 {
205 if (j!=6 && (key[j] & 0x01))
206 key[j+1] |= 0x80;
207 key[j] >>= 1;
208 }
209
210 if (GETBIT( key, 28 ))
211 {
212 CLRBIT( key, 28 );
213 SETBIT( key, 0 );
214 }
215
216 if (keep & 0x01)
217 SETBIT( key, 28 );
218
219 keep >>= 1;
220 }
221}
222
223static void sbox( unsigned char *dst, const unsigned char *src )
224{
225 int i;
226
227 for (i = 0; i < 4; i++)
228 dst[i] = 0;
229
230 for (i = 0; i < 8; i++)
231 {
232 int j, Snum, bitnum;
233
234 for (Snum = j = 0, bitnum = (i * 6); j < 6; j++, bitnum++)
235 {
236 Snum <<= 1;
237 Snum |= GETBIT( src, bitnum );
238 }
239
240 if (0 == (i%2))
241 dst[i/2] |= ((SBox[i][Snum]) << 4);
242 else
243 dst[i/2] |= SBox[i][Snum];
244 }
245}
246
[21916]247static void Xor( unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count )
[21326]248{
249 int i;
250
251 for (i = 0; i < count; i++)
252 dst[i] = a[i] ^ b[i];
253}
254
255unsigned char *CRYPT_DESkey8to7( unsigned char *dst, const unsigned char *key )
256{
257 int i;
258 unsigned char tmp[7];
259 static const unsigned char map8to7[56] =
260 {
261 0, 1, 2, 3, 4, 5, 6,
262 8, 9, 10, 11, 12, 13, 14,
263 16, 17, 18, 19, 20, 21, 22,
264 24, 25, 26, 27, 28, 29, 30,
265 32, 33, 34, 35, 36, 37, 38,
266 40, 41, 42, 43, 44, 45, 46,
267 48, 49, 50, 51, 52, 53, 54,
268 56, 57, 58, 59, 60, 61, 62
269 };
270
271 if ((dst == NULL) || (key == NULL))
272 return NULL;
273
274 Permute( tmp, key, map8to7, 7 );
275
276 for (i = 0; i < 7; i++)
277 dst[i] = tmp[i];
278
279 return dst;
280}
281
282unsigned 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 );
[21916]304 Xor( Rexp, Rexp, SubK, 6 );
[21326]305
306 sbox( Rn, Rexp );
307 Permute( Rexp, Rn, PBox, 4 );
[21916]308 Xor( Rn, L, Rexp, 4 );
[21326]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
322unsigned 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 );
[21916]343 Xor( Rexp, Rexp, SubK, 6 );
[21326]344
345 sbox( Rn, Rexp );
346 Permute( Rexp, Rn, PBox, 4 );
[21916]347 Xor( Rn, L, Rexp, 4 );
[21326]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}
Note: See TracBrowser for help on using the repository browser.