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