vcomp/tests: Add tests for atomic double functions.
[wine.git] / dlls / advapi32 / crypt_des.c
blob2da2d77e2d8549ca1d84ea3ce573af7142de6139
1 /*
2 * Copyright 2004 Hans Leidekker
3 * Copyright 2006 Mike McCormack
5 * Based on DES.c from libcifs
7 * Copyright (C) 2003, 2004 by Christopher R. Hertel
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.
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.
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
24 #include "windef.h"
25 #include "crypt.h"
27 static const unsigned char InitialPermuteMap[64] =
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
39 static const unsigned char KeyPermuteMap[56] =
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,
50 static const unsigned char KeyRotation[16] =
51 { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
53 static const unsigned char KeyCompression[48] =
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
63 static const unsigned char DataExpansion[48] =
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
73 static const unsigned char SBox[8][64] =
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
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
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
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
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
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
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
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
125 static const unsigned char PBox[32] =
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
133 static const unsigned char FinalPermuteMap[64] =
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
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)
149 static void Permute( unsigned char *dst, const unsigned char *src, const unsigned char *map, const int mapsize )
151 int bitcount, i;
153 for (i = 0; i < mapsize; i++)
154 dst[i] = 0;
156 bitcount = mapsize * 8;
158 for (i = 0; i < bitcount; i++)
160 if (GETBIT( src, map[i] ))
161 SETBIT( dst, i );
165 static void KeyShiftLeft( unsigned char *key, const int numbits )
167 int i;
168 unsigned char keep = key[0];
170 for (i = 0; i < numbits; i++)
172 int j;
174 for (j = 0; j < 7; j++)
176 if (j && (key[j] & 0x80))
177 key[j-1] |= 0x01;
178 key[j] <<= 1;
181 if (GETBIT( key, 27 ))
183 CLRBIT( key, 27 );
184 SETBIT( key, 55 );
187 if (keep & 0x80)
188 SETBIT( key, 27 );
190 keep <<= 1;
194 static void KeyShiftRight( unsigned char *key, const int numbits )
196 int i;
197 unsigned char keep = key[6];
199 for (i = 0; i < numbits; i++)
201 int j;
203 for (j = 6; j >= 0; j--)
205 if (j!=6 && (key[j] & 0x01))
206 key[j+1] |= 0x80;
207 key[j] >>= 1;
210 if (GETBIT( key, 28 ))
212 CLRBIT( key, 28 );
213 SETBIT( key, 0 );
216 if (keep & 0x01)
217 SETBIT( key, 28 );
219 keep >>= 1;
223 static void sbox( unsigned char *dst, const unsigned char *src )
225 int i;
227 for (i = 0; i < 4; i++)
228 dst[i] = 0;
230 for (i = 0; i < 8; i++)
232 int j, Snum, bitnum;
234 for (Snum = j = 0, bitnum = (i * 6); j < 6; j++, bitnum++)
236 Snum <<= 1;
237 Snum |= GETBIT( src, bitnum );
240 if (0 == (i%2))
241 dst[i/2] |= ((SBox[i][Snum]) << 4);
242 else
243 dst[i/2] |= SBox[i][Snum];
247 static void xor( unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count )
249 int i;
251 for (i = 0; i < count; i++)
252 dst[i] = a[i] ^ b[i];
255 unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key, const unsigned char *src )
257 int i;
258 unsigned char K[7];
259 unsigned char D[8];
261 Permute( K, key, KeyPermuteMap, 7 );
262 Permute( D, src, InitialPermuteMap, 8 );
264 for (i = 0; i < 16; i++)
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];
273 KeyShiftLeft( K, KeyRotation[i] );
274 Permute( SubK, K, KeyCompression, 6 );
276 Permute( Rexp, R, DataExpansion, 6 );
277 xor( Rexp, Rexp, SubK, 6 );
279 sbox( Rn, Rexp );
280 Permute( Rexp, Rn, PBox, 4 );
281 xor( Rn, L, Rexp, 4 );
283 for (j = 0; j < 4; j++)
285 L[j] = R[j];
286 R[j] = Rn[j];
290 Permute( dst, D, FinalPermuteMap, 8 );
292 return dst;
295 unsigned char *CRYPT_DESunhash( unsigned char *dst, const unsigned char *key, const unsigned char *src )
297 int i;
298 unsigned char K[7];
299 unsigned char D[8];
301 Permute( K, key, KeyPermuteMap, 7 );
302 Permute( D, src, InitialPermuteMap, 8 );
304 for (i = 0; i < 16; i++)
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];
313 Permute( SubK, K, KeyCompression, 6 );
315 Permute( Rexp, R, DataExpansion, 6 );
316 xor( Rexp, Rexp, SubK, 6 );
318 sbox( Rn, Rexp );
319 Permute( Rexp, Rn, PBox, 4 );
320 xor( Rn, L, Rexp, 4 );
322 for (j = 0; j < 4; j++)
324 L[j] = R[j];
325 R[j] = Rn[j];
328 KeyShiftRight( K, KeyRotation[15 - i] );
331 Permute( dst, D, FinalPermuteMap, 8 );
333 return dst;