xref: /reactos/dll/win32/advapi32/wine/crypt_des.c (revision a3ff25c1)
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