Removed the DOS version option, specifying the Windows version should
[wine] / dlls / advapi32 / 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 "windef.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 unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key, const unsigned char *src )
253 {
254     int i;
255     unsigned char K[7];
256     unsigned char D[8];
257
258     Permute( K, key, KeyPermuteMap, 7 );
259     Permute( D, src, InitialPermuteMap, 8 );
260
261     for (i = 0; i < 16; i++)
262     {
263         int j;
264         unsigned char *L = D;
265         unsigned char *R = &(D[4]);
266         unsigned char  Rexp[6];
267         unsigned char  Rn[4];
268         unsigned char  SubK[6];
269
270         KeyShift( K, KeyRotation[i] );
271         Permute( SubK, K, KeyCompression, 6 );
272
273         Permute( Rexp, R, DataExpansion, 6 );
274         xor( Rexp, Rexp, SubK, 6 );
275
276         sbox( Rn, Rexp );
277         Permute( Rexp, Rn, PBox, 4 );
278         xor( Rn, L, Rexp, 4 );
279
280         for (j = 0; j < 4; j++)
281         {
282             L[j] = R[j];
283             R[j] = Rn[j];
284         }
285     }
286
287     Permute( dst, D, FinalPermuteMap, 8 );
288
289     return dst;
290 }