msvcrt: Added _strtime_s and _wstrtime_s implementation.
[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_DEShash( unsigned char *dst, const unsigned char *key, const unsigned char *src )
256 {
257     int i;
258     unsigned char K[7];
259     unsigned char D[8];
260
261     Permute( K, key, KeyPermuteMap, 7 );
262     Permute( D, src, InitialPermuteMap, 8 );
263
264     for (i = 0; i < 16; i++)
265     {
266         int j;
267         unsigned char *L = D;
268         unsigned char *R = &(D[4]);
269         unsigned char  Rexp[6];
270         unsigned char  Rn[4];
271         unsigned char  SubK[6];
272
273         KeyShiftLeft( K, KeyRotation[i] );
274         Permute( SubK, K, KeyCompression, 6 );
275
276         Permute( Rexp, R, DataExpansion, 6 );
277         xor( Rexp, Rexp, SubK, 6 );
278
279         sbox( Rn, Rexp );
280         Permute( Rexp, Rn, PBox, 4 );
281         xor( Rn, L, Rexp, 4 );
282
283         for (j = 0; j < 4; j++)
284         {
285             L[j] = R[j];
286             R[j] = Rn[j];
287         }
288     }
289
290     Permute( dst, D, FinalPermuteMap, 8 );
291
292     return dst;
293 }
294
295 unsigned char *CRYPT_DESunhash( unsigned char *dst, const unsigned char *key, const unsigned char *src )
296 {
297     int i;
298     unsigned char K[7];
299     unsigned char D[8];
300
301     Permute( K, key, KeyPermuteMap, 7 );
302     Permute( D, src, InitialPermuteMap, 8 );
303
304     for (i = 0; i < 16; i++)
305     {
306         int j;
307         unsigned char *L = D;
308         unsigned char *R = &(D[4]);
309         unsigned char  Rexp[6];
310         unsigned char  Rn[4];
311         unsigned char  SubK[6];
312
313         Permute( SubK, K, KeyCompression, 6 );
314
315         Permute( Rexp, R, DataExpansion, 6 );
316         xor( Rexp, Rexp, SubK, 6 );
317
318         sbox( Rn, Rexp );
319         Permute( Rexp, Rn, PBox, 4 );
320         xor( Rn, L, Rexp, 4 );
321
322         for (j = 0; j < 4; j++)
323         {
324             L[j] = R[j];
325             R[j] = Rn[j];
326         }
327
328         KeyShiftRight( K, KeyRotation[15 - i] );
329     }
330
331     Permute( dst, D, FinalPermuteMap, 8 );
332
333     return dst;
334 }