wined3d: Correctly define the number of possible parameters.
[wine/multimedia.git] / dlls / advapi32 / crypt_lmhash.c
blob4760e97d493d80b9f32febbfbeecb5c1207d0e74
1 /*
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <stdarg.h>
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"
32 #include "crypt.h"
34 static const unsigned char CRYPT_LMhash_Magic[8] =
35 { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
37 static void CRYPT_LMhash( unsigned char *dst, const unsigned char *pwd, const int len )
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 };
42 max = len > max ? max : len;
44 for (i = 0; i < max; i++)
45 tmp_pwd[i] = pwd[i];
47 CRYPT_DEShash( dst, tmp_pwd, CRYPT_LMhash_Magic );
48 CRYPT_DEShash( &dst[8], &tmp_pwd[7], CRYPT_LMhash_Magic );
51 NTSTATUS WINAPI SystemFunction006( LPCSTR password, LPSTR hash )
53 CRYPT_LMhash( (unsigned char*)hash, (unsigned char*)password, strlen(password) );
55 return STATUS_SUCCESS;
58 /******************************************************************************
59 * SystemFunction008 [ADVAPI32.@]
61 * Creates a LM response from a challenge and a password hash
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
68 * RETURNS
69 * Success: STATUS_SUCCESS
70 * Failure: STATUS_UNSUCCESSFUL
72 * NOTES
73 * see http://davenport.sourceforge.net/ntlm.html#theLmResponse
76 NTSTATUS WINAPI SystemFunction008(const LPBYTE challenge, const LPBYTE hash, LPBYTE response)
78 BYTE key[7*3];
80 if (!challenge || !response)
81 return STATUS_UNSUCCESSFUL;
83 memset(key, 0, sizeof key);
84 memcpy(key, hash, 0x10);
86 CRYPT_DEShash(response, key, challenge);
87 CRYPT_DEShash(response+8, key+7, challenge);
88 CRYPT_DEShash(response+16, key+14, challenge);
90 return STATUS_SUCCESS;
93 /******************************************************************************
94 * SystemFunction001 [ADVAPI32.@]
96 * Encrypts a single block of data using DES
98 * PARAMS
99 * data [I] data to encrypt (8 bytes)
100 * key [I] key data (7 bytes)
101 * output [O] the encrypted data (8 bytes)
103 * RETURNS
104 * Success: STATUS_SUCCESS
105 * Failure: STATUS_UNSUCCESSFUL
108 NTSTATUS WINAPI SystemFunction001(const LPBYTE data, const LPBYTE key, LPBYTE output)
110 if (!data || !output)
111 return STATUS_UNSUCCESSFUL;
112 CRYPT_DEShash(output, key, data);
113 return STATUS_SUCCESS;
116 /******************************************************************************
117 * SystemFunction002 [ADVAPI32.@]
119 * Decrypts a single block of data using DES
121 * PARAMS
122 * data [I] data to decrypt (8 bytes)
123 * key [I] key data (7 bytes)
124 * output [O] the decrypted data (8 bytes)
126 * RETURNS
127 * Success: STATUS_SUCCESS
128 * Failure: STATUS_UNSUCCESSFUL
131 NTSTATUS WINAPI SystemFunction002(const LPBYTE data, const LPBYTE key, LPBYTE output)
133 if (!data || !output)
134 return STATUS_UNSUCCESSFUL;
135 CRYPT_DESunhash(output, key, data);
136 return STATUS_SUCCESS;
139 /******************************************************************************
140 * SystemFunction003 [ADVAPI32.@]
142 * Hashes a key using DES and a fixed datablock
144 * PARAMS
145 * key [I] key data (7 bytes)
146 * output [O] hashed key (8 bytes)
148 * RETURNS
149 * Success: STATUS_SUCCESS
150 * Failure: STATUS_UNSUCCESSFUL
153 NTSTATUS WINAPI SystemFunction003(const LPBYTE key, LPBYTE output)
155 if (!output)
156 return STATUS_UNSUCCESSFUL;
157 CRYPT_DEShash(output, key, CRYPT_LMhash_Magic);
158 return STATUS_SUCCESS;
161 /******************************************************************************
162 * SystemFunction004 [ADVAPI32.@]
164 * Encrypts a block of data with DES in ECB mode, preserving the length
166 * PARAMS
167 * data [I] data to encrypt
168 * key [I] key data (up to 7 bytes)
169 * output [O] buffer to receive encrypted data
171 * RETURNS
172 * Success: STATUS_SUCCESS
173 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
174 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
176 * NOTES
177 * Encrypt buffer size should be input size rounded up to 8 bytes
178 * plus an extra 8 bytes.
180 NTSTATUS WINAPI SystemFunction004(const struct ustring *in,
181 const struct ustring *key,
182 struct ustring *out)
184 union {
185 unsigned char uc[8];
186 unsigned int ui[2];
187 } data;
188 unsigned char deskey[7];
189 int crypt_len, ofs;
191 if (key->Length<=0)
192 return STATUS_INVALID_PARAMETER_2;
194 crypt_len = ((in->Length+7)&~7);
195 if (out->MaximumLength < (crypt_len+8))
196 return STATUS_BUFFER_TOO_SMALL;
198 data.ui[0] = in->Length;
199 data.ui[1] = 1;
201 if (key->Length<sizeof deskey)
203 memset(deskey, 0, sizeof deskey);
204 memcpy(deskey, key->Buffer, key->Length);
206 else
207 memcpy(deskey, key->Buffer, sizeof deskey);
209 CRYPT_DEShash(out->Buffer, deskey, data.uc);
211 for(ofs=0; ofs<(crypt_len-8); ofs+=8)
212 CRYPT_DEShash(out->Buffer+8+ofs, deskey, in->Buffer+ofs);
214 memset(data.uc, 0, sizeof data.uc);
215 memcpy(data.uc, in->Buffer+ofs, in->Length +8-crypt_len);
216 CRYPT_DEShash(out->Buffer+8+ofs, deskey, data.uc);
218 out->Length = crypt_len+8;
220 return STATUS_SUCCESS;
223 /******************************************************************************
224 * SystemFunction005 [ADVAPI32.@]
226 * Decrypts a block of data with DES in ECB mode
228 * PARAMS
229 * data [I] data to decrypt
230 * key [I] key data (up to 7 bytes)
231 * output [O] buffer to receive decrypted data
233 * RETURNS
234 * Success: STATUS_SUCCESS
235 * Failure: STATUS_BUFFER_TOO_SMALL if the output buffer is too small
236 * Failure: STATUS_INVALID_PARAMETER_2 if the key is zero length
239 NTSTATUS WINAPI SystemFunction005(const struct ustring *in,
240 const struct ustring *key,
241 struct ustring *out)
243 union {
244 unsigned char uc[8];
245 unsigned int ui[2];
246 } data;
247 unsigned char deskey[7];
248 int ofs, crypt_len;
250 if (key->Length<=0)
251 return STATUS_INVALID_PARAMETER_2;
253 if (key->Length<sizeof deskey)
255 memset(deskey, 0, sizeof deskey);
256 memcpy(deskey, key->Buffer, key->Length);
258 else
259 memcpy(deskey, key->Buffer, sizeof deskey);
261 CRYPT_DESunhash(data.uc, deskey, in->Buffer);
263 if (data.ui[1] != 1)
264 return STATUS_UNKNOWN_REVISION;
266 crypt_len = data.ui[0];
267 if (crypt_len > out->MaximumLength)
268 return STATUS_BUFFER_TOO_SMALL;
270 for (ofs=0; (ofs+8)<crypt_len; ofs+=8)
271 CRYPT_DESunhash(out->Buffer+ofs, deskey, in->Buffer+ofs+8);
273 if (ofs<crypt_len)
275 CRYPT_DESunhash(data.uc, deskey, in->Buffer+ofs+8);
276 memcpy(out->Buffer+ofs, data.uc, crypt_len-ofs);
279 out->Length = crypt_len;
281 return STATUS_SUCCESS;