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 |
|
---|
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, (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 | */
|
---|
76 | NTSTATUS 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 | */
|
---|
98 | NTSTATUS 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 | */
|
---|
118 | NTSTATUS 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 | */
|
---|
141 | NTSTATUS 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 | */
|
---|
163 | NTSTATUS 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 | */
|
---|
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 | 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 | */
|
---|
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 | 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 | */
|
---|
313 | NTSTATUS 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 | */
|
---|
342 | NTSTATUS 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 | */
|
---|
365 | NTSTATUS 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 | */
|
---|
393 | NTSTATUS 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 | }
|
---|