2 * Copyright 2004 Hans Leidekker
4 * Based on LMHash.c from libcifs
6 * Copyright (C) 2004 by Christopher R. Hertel
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.
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.
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
25 static const unsigned char CRYPT_LMhash_Magic
[8] =
26 { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
28 static void CRYPT_LMhash( unsigned char *dst
, const unsigned char *pwd
, const int len
)
31 unsigned char tmp_pwd
[14] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
33 max
= len
> max
? max
: len
;
35 for (i
= 0; i
< max
; i
++)
38 CRYPT_DEShash( dst
, tmp_pwd
, CRYPT_LMhash_Magic
);
39 CRYPT_DEShash( &dst
[8], &tmp_pwd
[7], CRYPT_LMhash_Magic
);
42 NTSTATUS WINAPI
SystemFunction006( LPCSTR password
, LPSTR hash
)
44 CRYPT_LMhash( (unsigned char*)hash
, (const unsigned char*)password
, strlen(password
) );
46 return STATUS_SUCCESS
;
50 /******************************************************************************
51 * SystemFunction008 [ADVAPI32.@]
53 * Creates a LM response from a challenge and a password hash
56 * challenge [I] Challenge from authentication server
57 * hash [I] NTLM hash (from SystemFunction006)
58 * response [O] response to send back to the server
61 * Success: STATUS_SUCCESS
62 * Failure: STATUS_UNSUCCESSFUL
65 * see http://davenport.sourceforge.net/ntlm.html#theLmResponse
68 NTSTATUS WINAPI
SystemFunction008(const BYTE
*challenge
, const BYTE
*hash
, LPBYTE response
)
72 if (!challenge
|| !response
)
73 return STATUS_UNSUCCESSFUL
;
75 memset(key
, 0, sizeof key
);
76 memcpy(key
, hash
, 0x10);
78 CRYPT_DEShash(response
, key
, challenge
);
79 CRYPT_DEShash(response
+8, key
+7, challenge
);
80 CRYPT_DEShash(response
+16, key
+14, challenge
);
82 return STATUS_SUCCESS
;
85 /******************************************************************************
86 * SystemFunction009 [ADVAPI32.@]
88 * Seems to do the same as SystemFunction008 ...
90 NTSTATUS WINAPI
SystemFunction009(const BYTE
*challenge
, const BYTE
*hash
, LPBYTE response
)
92 return SystemFunction008(challenge
, hash
, response
);
95 /******************************************************************************
96 * SystemFunction001 [ADVAPI32.@]
98 * Encrypts a single block of data using DES
101 * data [I] data to encrypt (8 bytes)
102 * key [I] key data (7 bytes)
103 * output [O] the encrypted data (8 bytes)
106 * Success: STATUS_SUCCESS
107 * Failure: STATUS_UNSUCCESSFUL
110 NTSTATUS WINAPI
SystemFunction001(const BYTE
*data
, const BYTE
*key
, LPBYTE output
)
112 if (!data
|| !output
)
113 return STATUS_UNSUCCESSFUL
;
114 CRYPT_DEShash(output
, key
, data
);
115 return STATUS_SUCCESS
;
118 /******************************************************************************
119 * SystemFunction002 [ADVAPI32.@]
121 * Decrypts a single block of data using DES
124 * data [I] data to decrypt (8 bytes)
125 * key [I] key data (7 bytes)
126 * output [O] the decrypted data (8 bytes)
129 * Success: STATUS_SUCCESS
130 * Failure: STATUS_UNSUCCESSFUL
133 NTSTATUS WINAPI
SystemFunction002(const BYTE
*data
, const BYTE
*key
, LPBYTE output
)
135 if (!data
|| !output
)
136 return STATUS_UNSUCCESSFUL
;
137 CRYPT_DESunhash(output
, key
, data
);
138 return STATUS_SUCCESS
;
141 /******************************************************************************
142 * SystemFunction003 [ADVAPI32.@]
144 * Hashes a key using DES and a fixed datablock
147 * key [I] key data (7 bytes)
148 * output [O] hashed key (8 bytes)
151 * Success: STATUS_SUCCESS
152 * Failure: STATUS_UNSUCCESSFUL
155 NTSTATUS WINAPI
SystemFunction003(const BYTE
*key
, LPBYTE output
)
158 return STATUS_UNSUCCESSFUL
;
159 CRYPT_DEShash(output
, key
, CRYPT_LMhash_Magic
);
160 return STATUS_SUCCESS
;
163 /******************************************************************************
164 * SystemFunction004 [ADVAPI32.@]
166 * Encrypts a block of data with DES in ECB mode, preserving the length
169 * data [I] data to encrypt
170 * key [I] key data (up to 7 bytes)
171 * output [O] buffer to receive encrypted data
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
179 * Encrypt buffer size should be input size rounded up to 8 bytes
180 * plus an extra 8 bytes.
182 NTSTATUS WINAPI
SystemFunction004(const struct ustring
*in
,
183 const struct ustring
*key
,
190 unsigned char deskey
[7];
191 unsigned int crypt_len
, ofs
;
194 return STATUS_INVALID_PARAMETER_2
;
196 crypt_len
= ((in
->Length
+7)&~7);
197 if (out
->MaximumLength
< (crypt_len
+8))
198 return STATUS_BUFFER_TOO_SMALL
;
200 data
.ui
[0] = in
->Length
;
203 if (key
->Length
<sizeof deskey
)
205 memset(deskey
, 0, sizeof deskey
);
206 memcpy(deskey
, key
->Buffer
, key
->Length
);
209 memcpy(deskey
, key
->Buffer
, sizeof deskey
);
211 CRYPT_DEShash(out
->Buffer
, deskey
, data
.uc
);
213 for(ofs
=0; ofs
<(crypt_len
-8); ofs
+=8)
214 CRYPT_DEShash(out
->Buffer
+8+ofs
, deskey
, in
->Buffer
+ofs
);
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
);
220 out
->Length
= crypt_len
+8;
222 return STATUS_SUCCESS
;
225 /******************************************************************************
226 * SystemFunction005 [ADVAPI32.@]
228 * Decrypts a block of data with DES in ECB mode
231 * data [I] data to decrypt
232 * key [I] key data (up to 7 bytes)
233 * output [O] buffer to receive decrypted data
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
241 NTSTATUS WINAPI
SystemFunction005(const struct ustring
*in
,
242 const struct ustring
*key
,
249 unsigned char deskey
[7];
250 unsigned int ofs
, crypt_len
;
253 return STATUS_INVALID_PARAMETER_2
;
255 if (key
->Length
<sizeof deskey
)
257 memset(deskey
, 0, sizeof deskey
);
258 memcpy(deskey
, key
->Buffer
, key
->Length
);
261 memcpy(deskey
, key
->Buffer
, sizeof deskey
);
263 CRYPT_DESunhash(data
.uc
, deskey
, in
->Buffer
);
266 return STATUS_UNKNOWN_REVISION
;
268 crypt_len
= data
.ui
[0];
269 if (crypt_len
> out
->MaximumLength
)
270 return STATUS_BUFFER_TOO_SMALL
;
272 for (ofs
=0; (ofs
+8)<crypt_len
; ofs
+=8)
273 CRYPT_DESunhash(out
->Buffer
+ofs
, deskey
, in
->Buffer
+ofs
+8);
277 CRYPT_DESunhash(data
.uc
, deskey
, in
->Buffer
+ofs
+8);
278 memcpy(out
->Buffer
+ofs
, data
.uc
, crypt_len
-ofs
);
281 out
->Length
= crypt_len
;
283 return STATUS_SUCCESS
;
286 /******************************************************************************
287 * SystemFunction012 [ADVAPI32.@]
288 * SystemFunction014 [ADVAPI32.@]
289 * SystemFunction016 [ADVAPI32.@]
290 * SystemFunction018 [ADVAPI32.@]
291 * SystemFunction020 [ADVAPI32.@]
292 * SystemFunction022 [ADVAPI32.@]
294 * Encrypts two DES blocks with two keys
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)
302 * Success: STATUS_SUCCESS
303 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
305 NTSTATUS WINAPI
SystemFunction012(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
308 return STATUS_UNSUCCESSFUL
;
310 CRYPT_DEShash(out
, key
, in
);
311 CRYPT_DEShash(out
+8, key
+7, in
+8);
312 return STATUS_SUCCESS
;
315 /******************************************************************************
316 * SystemFunction013 [ADVAPI32.@]
317 * SystemFunction015 [ADVAPI32.@]
318 * SystemFunction017 [ADVAPI32.@]
319 * SystemFunction019 [ADVAPI32.@]
320 * SystemFunction021 [ADVAPI32.@]
321 * SystemFunction023 [ADVAPI32.@]
323 * Decrypts two DES blocks with two keys
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)
331 * Success: STATUS_SUCCESS
332 * Failure: STATUS_UNSUCCESSFUL if the input or output buffer is NULL
334 NTSTATUS WINAPI
SystemFunction013(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
337 return STATUS_UNSUCCESSFUL
;
339 CRYPT_DESunhash(out
, key
, in
);
340 CRYPT_DESunhash(out
+8, key
+7, in
+8);
341 return STATUS_SUCCESS
;
344 /******************************************************************************
345 * SystemFunction024 [ADVAPI32.@]
347 * Encrypts two DES blocks with a 32 bit key...
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)
355 * Success: STATUS_SUCCESS
357 NTSTATUS WINAPI
SystemFunction024(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
361 memcpy(deskey
, key
, 4);
362 memcpy(deskey
+4, key
, 4);
363 memcpy(deskey
+8, key
, 4);
364 memcpy(deskey
+12, key
, 4);
366 CRYPT_DEShash(out
, deskey
, in
);
367 CRYPT_DEShash(out
+8, deskey
+7, in
+8);
369 return STATUS_SUCCESS
;
372 /******************************************************************************
373 * SystemFunction025 [ADVAPI32.@]
375 * Decrypts two DES blocks with a 32 bit key...
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)
383 * Success: STATUS_SUCCESS
385 NTSTATUS WINAPI
SystemFunction025(const BYTE
*in
, const BYTE
*key
, LPBYTE out
)
389 memcpy(deskey
, key
, 4);
390 memcpy(deskey
+4, key
, 4);
391 memcpy(deskey
+8, key
, 4);
392 memcpy(deskey
+12, key
, 4);
394 CRYPT_DESunhash(out
, deskey
, in
);
395 CRYPT_DESunhash(out
+8, deskey
+7, in
+8);
397 return STATUS_SUCCESS
;
399 #endif /* !__REACTOS__ */