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