ddraw/tests: Fix compilation on systems that don't support nameless unions.
[wine] / dlls / advapi32 / crypt_des.c
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
27 static 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
39 static 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
50 static const unsigned char KeyRotation[16] =
51     { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
52
53 static 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
63 static 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
73 static 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
125 static 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
133 static 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
149 static 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
165 static 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
194 static 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
223 static 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
247 static void xor( unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count )
248 {
249     int i;
250
251     for (i = 0; i < count; i++)
252         dst[i] = a[i] ^ b[i];
253 }
254
255 unsigned 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
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 }