[ADVAPI32]
[reactos.git] / reactos / dll / win32 / advapi32 / wine / crypt_lmhash.c
1 /*
2 * Copyright 2004 Hans Leidekker
3 *
4 * Based on LMHash.c from libcifs
5 *
6 * Copyright (C) 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23 #include <advapi32.h>
24
25 static const unsigned char CRYPT_LMhash_Magic[8] =
26 { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
27
28 static void CRYPT_LMhash( unsigned char *dst, const unsigned char *pwd, const int len )
29 {
30 int i, max = 14;
31 unsigned char tmp_pwd[14] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
32
33 max = len > max ? max : len;
34
35 for (i = 0; i < max; i++)
36 tmp_pwd[i] = pwd[i];
37
38 CRYPT_DEShash( dst, tmp_pwd, CRYPT_LMhash_Magic );
39 CRYPT_DEShash( &dst[8], &tmp_pwd[7], CRYPT_LMhash_Magic );
40 }
41
42 NTSTATUS WINAPI SystemFunction006( LPCSTR password, LPSTR hash )
43 {
44 CRYPT_LMhash( (unsigned char*)hash, (const unsigned char*)password, strlen(password) );
45
46 return STATUS_SUCCESS;
47 }
48
49 #ifndef __REACTOS__
50 /******************************************************************************
51 * SystemFunction008 [ADVAPI32.@]
52 *
53 * Creates a LM response from a challenge and a password hash
54 *
55 * PARAMS
56 * challenge [I] Challenge from authentication server
57 * hash [I] NTLM hash (from SystemFunction006)
58 * response [O] response to send back to the server
59 *
60 * RETURNS
61 * Success: STATUS_SUCCESS
62 * Failure: STATUS_UNSUCCESSFUL
63 *
64 * NOTES
65 * see http://davenport.sourceforge.net/ntlm.html#theLmResponse
66 *
67 */
68 NTSTATUS WINAPI SystemFunction008(const BYTE *challenge, const BYTE *hash, LPBYTE response)
69 {
70 BYTE key[7*3];
71
72 if (!challenge || !response)
73 return STATUS_UNSUCCESSFUL;
74
75 memset(key, 0, sizeof key);
76 memcpy(key, hash, 0x10);
77
78 CRYPT_DEShash(response, key, challenge);
79 CRYPT_DEShash(response+8, key+7, challenge);
80 CRYPT_DEShash(response+16, key+14, challenge);
81
82 return STATUS_SUCCESS;
83 }
84
85 /******************************************************************************
86 * SystemFunction009 [ADVAPI32.@]
87 *
88 * Seems to do the same as SystemFunction008 ...
89 */
90 NTSTATUS WINAPI SystemFunction009(const BYTE *challenge, const BYTE *hash, LPBYTE response)
91 {
92 return SystemFunction008(challenge, hash, response);
93 }
94
95 /******************************************************************************
96 * SystemFunction001 [ADVAPI32.@]
97 *
98 * Encrypts a single block of data using DES
99 *
100 * PARAMS
101 * data [I] data to encrypt (8 bytes)
102 * key [I] key data (7 bytes)
103 * output [O] the encrypted data (8 bytes)
104 *
105 * RETURNS
106 * Success: STATUS_SUCCESS
107 * Failure: STATUS_UNSUCCESSFUL
108 *
109 */
110 NTSTATUS WINAPI SystemFunction001(const BYTE *data, const BYTE *key, LPBYTE output)
111 {
112 if (!data || !output)
113 return STATUS_UNSUCCESSFUL;
114 CRYPT_DEShash(output, key, data);
115 return STATUS_SUCCESS;
116 }
117
118 /******************************************************************************
119 * SystemFunction002 [ADVAPI32.@]
120 *
121 * Decrypts a single block of data using DES
122 *
123 * PARAMS
124 * data [I] data to decrypt (8 bytes)
125 * key [I] key data (7 bytes)
126 * output [O] the decrypted data (8 bytes)
127 *
128 * RETURNS
129 * Success: STATUS_SUCCESS
130 * Failure: STATUS_UNSUCCESSFUL
131 *
132 */
133 NTSTATUS WINAPI SystemFunction002(const BYTE *data, const BYTE *key, LPBYTE output)
134 {
135 if (!data || !output)
136 return STATUS_UNSUCCESSFUL;
137 CRYPT_DESunhash(output, key, data);
138 return STATUS_SUCCESS;
139 }
140
141 /******************************************************************************
142 * SystemFunction003 [ADVAPI32.@]
143 *
144 * Hashes a key using DES and a fixed datablock
145 *
146 * PARAMS
147 * key [I] key data (7 bytes)
148 * output [O] hashed key (8 bytes)
149 *
150 * RETURNS
151 * Success: STATUS_SUCCESS
152 * Failure: STATUS_UNSUCCESSFUL
153 *
154 */
155 NTSTATUS WINAPI SystemFunction003(const BYTE *key, LPBYTE output)
156 {
157 if (!output)
158 return STATUS_UNSUCCESSFUL;
159 CRYPT_DEShash(output, key, CRYPT_LMhash_Magic);
160 return STATUS_SUCCESS;
161 }
162
163 /******************************************************************************
164 * SystemFunction004 [ADVAPI32.@]
165 *
166 * Encrypts a block of data with DES in ECB mode, preserving the length
167 *
168 * PARAMS
169 * data [I] data to encrypt
170 * key [I] key data (up to 7 bytes)
171 * output [O] buffer to receive encrypted data
172 *
173 * RETURNS
174 * Success: STATUS_SUCCESS
175 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
176 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
177 *
178 * NOTES
179 * Encrypt buffer size should be input size rounded up to 8 bytes
180 * plus an extra 8 bytes.
181 */
182 NTSTATUS WINAPI SystemFunction004(const struct ustring *in,
183 const struct ustring *key,
184 struct ustring *out)
185 {
186 union {
187 unsigned char uc[8];
188 unsigned int ui[2];
189 } data;
190 unsigned char deskey[7];
191 unsigned int crypt_len, ofs;
192
193 if (key->Length<=0)
194 return STATUS_INVALID_PARAMETER_2;
195
196 crypt_len = ((in->Length+7)&~7);
197 if (out->MaximumLength < (crypt_len+8))
198 return STATUS_BUFFER_TOO_SMALL;
199
200 data.ui[0] = in->Length;
201 data.ui[1] = 1;
202
203 if (key->Length<sizeof deskey)
204 {
205 memset(deskey, 0, sizeof deskey);
206 memcpy(deskey, key->Buffer, key->Length);
207 }
208 else
209 memcpy(deskey, key->Buffer, sizeof deskey);
210
211 CRYPT_DEShash(out->Buffer, deskey, data.uc);
212
213 for(ofs=0; ofs<(crypt_len-8); ofs+=8)
214 CRYPT_DEShash(out->Buffer+8+ofs, deskey, in->Buffer+ofs);
215
216 memset(data.uc, 0, sizeof data.uc);
217 memcpy(data.uc, in->Buffer+ofs, in->Length +8-crypt_len);
218 CRYPT_DEShash(out->Buffer+8+ofs, deskey, data.uc);
219
220 out->Length = crypt_len+8;
221
222 return STATUS_SUCCESS;
223 }
224
225 /******************************************************************************
226 * SystemFunction005 [ADVAPI32.@]
227 *
228 * Decrypts a block of data with DES in ECB mode
229 *
230 * PARAMS
231 * data [I] data to decrypt
232 * key [I] key data (up to 7 bytes)
233 * output [O] buffer to receive decrypted data
234 *
235 * RETURNS
236 * Success: STATUS_SUCCESS
237 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
238 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
239 *
240 */
241 NTSTATUS WINAPI SystemFunction005(const struct ustring *in,
242 const struct ustring *key,
243 struct ustring *out)
244 {
245 union {
246 unsigned char uc[8];
247 unsigned int ui[2];
248 } data;
249 unsigned char deskey[7];
250 unsigned int ofs, crypt_len;
251
252 if (key->Length<=0)
253 return STATUS_INVALID_PARAMETER_2;
254
255 if (key->Length<sizeof deskey)
256 {
257 memset(deskey, 0, sizeof deskey);
258 memcpy(deskey, key->Buffer, key->Length);
259 }
260 else
261 memcpy(deskey, key->Buffer, sizeof deskey);
262
263 CRYPT_DESunhash(data.uc, deskey, in->Buffer);
264
265 if (data.ui[1] != 1)
266 return STATUS_UNKNOWN_REVISION;
267
268 crypt_len = data.ui[0];
269 if (crypt_len > out->MaximumLength)
270 return STATUS_BUFFER_TOO_SMALL;
271
272 for (ofs=0; (ofs+8)<crypt_len; ofs+=8)
273 CRYPT_DESunhash(out->Buffer+ofs, deskey, in->Buffer+ofs+8);
274
275 if (ofs<crypt_len)
276 {
277 CRYPT_DESunhash(data.uc, deskey, in->Buffer+ofs+8);
278 memcpy(out->Buffer+ofs, data.uc, crypt_len-ofs);
279 }
280
281 out->Length = crypt_len;
282
283 return STATUS_SUCCESS;
284 }
285
286 /******************************************************************************
287 * SystemFunction012 [ADVAPI32.@]
288 * SystemFunction014 [ADVAPI32.@]
289 * SystemFunction016 [ADVAPI32.@]
290 * SystemFunction018 [ADVAPI32.@]
291 * SystemFunction020 [ADVAPI32.@]
292 * SystemFunction022 [ADVAPI32.@]
293 *
294 * Encrypts two DES blocks with two keys
295 *
296 * PARAMS
297 * data [I] data to encrypt (16 bytes)
298 * key [I] key data (two lots of 7 bytes)
299 * output [O] buffer to receive encrypted data (16 bytes)
300 *
301 * RETURNS
302 * Success: STATUS_SUCCESS
303 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
304 */
305 NTSTATUS WINAPI SystemFunction012(const BYTE *in, const BYTE *key, LPBYTE out)
306 {
307 if (!in || !out)
308 return STATUS_UNSUCCESSFUL;
309
310 CRYPT_DEShash(out, key, in);
311 CRYPT_DEShash(out+8, key+7, in+8);
312 return STATUS_SUCCESS;
313 }
314
315 /******************************************************************************
316 * SystemFunction013 [ADVAPI32.@]
317 * SystemFunction015 [ADVAPI32.@]
318 * SystemFunction017 [ADVAPI32.@]
319 * SystemFunction019 [ADVAPI32.@]
320 * SystemFunction021 [ADVAPI32.@]
321 * SystemFunction023 [ADVAPI32.@]
322 *
323 * Decrypts two DES blocks with two keys
324 *
325 * PARAMS
326 * data [I] data to decrypt (16 bytes)
327 * key [I] key data (two lots of 7 bytes)
328 * output [O] buffer to receive decrypted data (16 bytes)
329 *
330 * RETURNS
331 * Success: STATUS_SUCCESS
332 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
333 */
334 NTSTATUS WINAPI SystemFunction013(const BYTE *in, const BYTE *key, LPBYTE out)
335 {
336 if (!in || !out)
337 return STATUS_UNSUCCESSFUL;
338
339 CRYPT_DESunhash(out, key, in);
340 CRYPT_DESunhash(out+8, key+7, in+8);
341 return STATUS_SUCCESS;
342 }
343
344 /******************************************************************************
345 * SystemFunction024 [ADVAPI32.@]
346 *
347 * Encrypts two DES blocks with a 32 bit key...
348 *
349 * PARAMS
350 * data [I] data to encrypt (16 bytes)
351 * key [I] key data (4 bytes)
352 * output [O] buffer to receive encrypted data (16 bytes)
353 *
354 * RETURNS
355 * Success: STATUS_SUCCESS
356 */
357 NTSTATUS WINAPI SystemFunction024(const BYTE *in, const BYTE *key, LPBYTE out)
358 {
359 BYTE deskey[0x10];
360
361 memcpy(deskey, key, 4);
362 memcpy(deskey+4, key, 4);
363 memcpy(deskey+8, key, 4);
364 memcpy(deskey+12, key, 4);
365
366 CRYPT_DEShash(out, deskey, in);
367 CRYPT_DEShash(out+8, deskey+7, in+8);
368
369 return STATUS_SUCCESS;
370 }
371
372 /******************************************************************************
373 * SystemFunction025 [ADVAPI32.@]
374 *
375 * Decrypts two DES blocks with a 32 bit key...
376 *
377 * PARAMS
378 * data [I] data to encrypt (16 bytes)
379 * key [I] key data (4 bytes)
380 * output [O] buffer to receive encrypted data (16 bytes)
381 *
382 * RETURNS
383 * Success: STATUS_SUCCESS
384 */
385 NTSTATUS WINAPI SystemFunction025(const BYTE *in, const BYTE *key, LPBYTE out)
386 {
387 BYTE deskey[0x10];
388
389 memcpy(deskey, key, 4);
390 memcpy(deskey+4, key, 4);
391 memcpy(deskey+8, key, 4);
392 memcpy(deskey+12, key, 4);
393
394 CRYPT_DESunhash(out, deskey, in);
395 CRYPT_DESunhash(out+8, deskey+7, in+8);
396
397 return STATUS_SUCCESS;
398 }
399 #endif /* !__REACTOS__ */