source: trunk/src/advapi32/crypt_lmhash.cpp

Last change on this file was 21326, checked in by ydario, 16 years ago

advapi32 and crypt32 updates.

  • Property svn:eol-style set to native
File size: 11.0 KB
Line 
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 "winternl.h"
29
30#include <string.h>
31
32#include "crypt.h"
33
34static const unsigned char CRYPT_LMhash_Magic[8] =
35 { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
36
37static 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
51NTSTATUS WINAPI SystemFunction006( LPCSTR password, LPSTR hash )
52{
53 CRYPT_LMhash( (unsigned char*)hash, (const 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 */
76NTSTATUS WINAPI SystemFunction008(const BYTE *challenge, const BYTE *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 */
98NTSTATUS WINAPI SystemFunction009(const BYTE *challenge, const BYTE *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 */
118NTSTATUS WINAPI SystemFunction001(const BYTE *data, const BYTE *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 */
141NTSTATUS WINAPI SystemFunction002(const BYTE *data, const BYTE *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 */
163NTSTATUS WINAPI SystemFunction003(const BYTE *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 */
190NTSTATUS 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 unsigned 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 */
249NTSTATUS 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 unsigned 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 */
313NTSTATUS WINAPI SystemFunction012(const BYTE *in, const BYTE *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 */
342NTSTATUS WINAPI SystemFunction013(const BYTE *in, const BYTE *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 */
365NTSTATUS WINAPI SystemFunction024(const BYTE *in, const BYTE *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 */
393NTSTATUS WINAPI SystemFunction025(const BYTE *in, const BYTE *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}
Note: See TracBrowser for help on using the repository browser.