Merge branch 'depends/rmk/gpio' into next/devel
[deliverable/linux.git] / fs / cifs / smbencrypt.c
CommitLineData
790fe579 1/*
1da177e4
LT
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB parameters and setup
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
7 Modified by Jeremy Allison 1995.
8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
9 Modified by Steve French (sfrench@us.ibm.com) 2002-2003
50c2f753 10
1da177e4
LT
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
50c2f753 15
1da177e4
LT
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
50c2f753 20
1da177e4
LT
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/
25
26#include <linux/module.h>
5a0e3ad6 27#include <linux/slab.h>
1da177e4
LT
28#include <linux/fs.h>
29#include <linux/string.h>
30#include <linux/kernel.h>
31#include <linux/random.h>
32#include "cifs_unicode.h"
33#include "cifspdu.h"
3979877e 34#include "cifsglob.h"
1da177e4 35#include "cifs_debug.h"
ee2c9258 36#include "cifsproto.h"
1da177e4 37
4b18f2a9
SF
38#ifndef false
39#define false 0
1da177e4 40#endif
4b18f2a9
SF
41#ifndef true
42#define true 1
1da177e4
LT
43#endif
44
45/* following came from the other byteorder.h to avoid include conflicts */
46#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
47#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
48#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
49
43988d76
SF
50static void
51str_to_key(unsigned char *str, unsigned char *key)
52{
53 int i;
54
55 key[0] = str[0] >> 1;
56 key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
57 key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
58 key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
59 key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
60 key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
61 key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
62 key[7] = str[6] & 0x7F;
63 for (i = 0; i < 8; i++)
64 key[i] = (key[i] << 1);
65}
66
67static int
68smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
69{
70 int rc;
71 unsigned char key2[8];
72 struct crypto_blkcipher *tfm_des;
73 struct scatterlist sgin, sgout;
74 struct blkcipher_desc desc;
75
76 str_to_key(key, key2);
77
78 tfm_des = crypto_alloc_blkcipher("ecb(des)", 0, CRYPTO_ALG_ASYNC);
79 if (IS_ERR(tfm_des)) {
80 rc = PTR_ERR(tfm_des);
81 cERROR(1, "could not allocate des crypto API\n");
82 goto smbhash_err;
83 }
84
85 desc.tfm = tfm_des;
86
87 crypto_blkcipher_setkey(tfm_des, key2, 8);
88
89 sg_init_one(&sgin, in, 8);
90 sg_init_one(&sgout, out, 8);
91
92 rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, 8);
e4fb0edb 93 if (rc)
43988d76 94 cERROR(1, "could not encrypt crypt key rc: %d\n", rc);
43988d76 95
e4fb0edb 96 crypto_free_blkcipher(tfm_des);
43988d76
SF
97smbhash_err:
98 return rc;
99}
100
101static int
102E_P16(unsigned char *p14, unsigned char *p16)
103{
104 int rc;
105 unsigned char sp8[8] =
106 { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
107
108 rc = smbhash(p16, sp8, p14);
109 if (rc)
110 return rc;
111 rc = smbhash(p16 + 8, sp8, p14 + 7);
112 return rc;
113}
114
115static int
116E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
117{
118 int rc;
119
120 rc = smbhash(p24, c8, p21);
121 if (rc)
122 return rc;
123 rc = smbhash(p24 + 8, c8, p21 + 7);
124 if (rc)
125 return rc;
126 rc = smbhash(p24 + 16, c8, p21 + 14);
127 return rc;
128}
129
ee2c9258
SP
130/* produce a md4 message digest from data of length n bytes */
131int
132mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
133{
134 int rc;
135 unsigned int size;
136 struct crypto_shash *md4;
137 struct sdesc *sdescmd4;
138
139 md4 = crypto_alloc_shash("md4", 0, 0);
140 if (IS_ERR(md4)) {
ffeb414a 141 rc = PTR_ERR(md4);
ee2c9258 142 cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc);
ffeb414a 143 return rc;
ee2c9258
SP
144 }
145 size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
146 sdescmd4 = kmalloc(size, GFP_KERNEL);
147 if (!sdescmd4) {
148 rc = -ENOMEM;
149 cERROR(1, "%s: Memory allocation failure\n", __func__);
150 goto mdfour_err;
151 }
152 sdescmd4->shash.tfm = md4;
153 sdescmd4->shash.flags = 0x0;
154
155 rc = crypto_shash_init(&sdescmd4->shash);
156 if (rc) {
157 cERROR(1, "%s: Could not init md4 shash\n", __func__);
158 goto mdfour_err;
159 }
14cae324
SP
160 rc = crypto_shash_update(&sdescmd4->shash, link_str, link_len);
161 if (rc) {
162 cERROR(1, "%s: Could not update with link_str\n", __func__);
163 goto mdfour_err;
164 }
ee2c9258 165 rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
14cae324
SP
166 if (rc)
167 cERROR(1, "%s: Could not genereate md4 hash\n", __func__);
1da177e4 168
ee2c9258
SP
169mdfour_err:
170 crypto_free_shash(md4);
171 kfree(sdescmd4);
172
173 return rc;
174}
175
1da177e4
LT
176/*
177 This implements the X/Open SMB password encryption
790fe579 178 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
1da177e4
LT
179 encrypted password into p24 */
180/* Note that password must be uppercased and null terminated */
43988d76 181int
4e53a3fb 182SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
1da177e4 183{
43988d76
SF
184 int rc;
185 unsigned char p14[14], p16[16], p21[21];
1da177e4 186
1da177e4 187 memset(p14, '\0', 14);
43988d76
SF
188 memset(p16, '\0', 16);
189 memset(p21, '\0', 21);
1da177e4 190
43988d76
SF
191 memcpy(p14, passwd, 14);
192 rc = E_P16(p14, p16);
193 if (rc)
194 return rc;
1da177e4 195
43988d76
SF
196 memcpy(p21, p16, 16);
197 rc = E_P24(p21, c8, p24);
50c2f753 198
43988d76 199 return rc;
1da177e4
LT
200}
201
202/* Routines for Windows NT MD4 Hash functions. */
203static int
63d2583f 204_my_wcslen(__u16 *str)
1da177e4
LT
205{
206 int len = 0;
207 while (*str++ != 0)
208 len++;
209 return len;
210}
211
212/*
213 * Convert a string into an NT UNICODE string.
790fe579 214 * Note that regardless of processor type
1da177e4
LT
215 * this must be in intel (little-endian)
216 * format.
217 */
218
219static int
63d2583f 220_my_mbstowcs(__u16 *dst, const unsigned char *src, int len)
790fe579 221{ /* BB not a very good conversion routine - change/fix */
1da177e4
LT
222 int i;
223 __u16 val;
224
225 for (i = 0; i < len; i++) {
226 val = *src;
227 SSVAL(dst, 0, val);
228 dst++;
229 src++;
230 if (val == 0)
231 break;
232 }
233 return i;
234}
235
790fe579 236/*
1da177e4
LT
237 * Creates the MD4 Hash of the users password in NT UNICODE.
238 */
239
ee2c9258 240int
1da177e4
LT
241E_md4hash(const unsigned char *passwd, unsigned char *p16)
242{
ee2c9258 243 int rc;
1da177e4
LT
244 int len;
245 __u16 wpwd[129];
246
247 /* Password cannot be longer than 128 characters */
790fe579 248 if (passwd) {
1da177e4 249 len = strlen((char *) passwd);
63d2583f 250 if (len > 128)
1da177e4 251 len = 128;
63d2583f 252
1da177e4
LT
253 /* Password must be converted to NT unicode */
254 _my_mbstowcs(wpwd, passwd, len);
255 } else
256 len = 0;
257
258 wpwd[len] = 0; /* Ensure string is null terminated */
259 /* Calculate length in bytes */
630f3f0c 260 len = _my_wcslen(wpwd) * sizeof(__u16);
1da177e4 261
ee2c9258 262 rc = mdfour(p16, (unsigned char *) wpwd, len);
790fe579 263 memset(wpwd, 0, 129 * 2);
ee2c9258
SP
264
265 return rc;
1da177e4
LT
266}
267
e10847ed 268#if 0 /* currently unused */
1da177e4 269/* Does both the NT and LM owfs of a user's password */
2cd646a2 270static void
1da177e4
LT
271nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
272{
273 char passwd[514];
274
275 memset(passwd, '\0', 514);
276 if (strlen(pwd) < 513)
277 strcpy(passwd, pwd);
278 else
279 memcpy(passwd, pwd, 512);
280 /* Calculate the MD4 hash (NT compatible) of the password */
281 memset(nt_p16, '\0', 16);
282 E_md4hash(passwd, nt_p16);
283
284 /* Mangle the passwords into Lanman format */
285 passwd[14] = '\0';
286/* strupper(passwd); */
287
288 /* Calculate the SMB (lanman) hash functions of the password */
289
290 memset(p16, '\0', 16);
291 E_P16((unsigned char *) passwd, (unsigned char *) p16);
292
293 /* clear out local copy of user's password (just being paranoid). */
630f3f0c 294 memset(passwd, '\0', sizeof(passwd));
1da177e4 295}
e10847ed 296#endif
1da177e4
LT
297
298/* Does the NTLMv2 owfs of a user's password */
299#if 0 /* function not needed yet - but will be soon */
300static void
301ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
302 const char *domain_n, unsigned char kr_buf[16],
303 const struct nls_table *nls_codepage)
304{
50c2f753
SF
305 wchar_t *user_u;
306 wchar_t *dom_u;
1da177e4
LT
307 int user_l, domain_l;
308 struct HMACMD5Context ctx;
309
310 /* might as well do one alloc to hold both (user_u and dom_u) */
790fe579
SF
311 user_u = kmalloc(2048 * sizeof(wchar_t), GFP_KERNEL);
312 if (user_u == NULL)
1da177e4
LT
313 return;
314 dom_u = user_u + 1024;
50c2f753 315
63d2583f
SF
316 /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2,
317 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
318 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2,
319 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
1da177e4
LT
320
321 /* BB user and domain may need to be uppercased */
322 user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
323 domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
324
325 user_l++; /* trailing null */
326 domain_l++;
327
328 hmac_md5_init_limK_to_64(owf, 16, &ctx);
329 hmac_md5_update((const unsigned char *) user_u, user_l * 2, &ctx);
330 hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &ctx);
331 hmac_md5_final(kr_buf, &ctx);
332
333 kfree(user_u);
334}
790fe579 335#endif
1da177e4 336
1da177e4 337/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
e10847ed 338#if 0 /* currently unused */
2cd646a2 339static void
1da177e4
LT
340NTLMSSPOWFencrypt(unsigned char passwd[8],
341 unsigned char *ntlmchalresp, unsigned char p24[24])
342{
343 unsigned char p21[21];
344
345 memset(p21, '\0', 21);
346 memcpy(p21, passwd, 8);
347 memset(p21 + 8, 0xbd, 8);
348
349 E_P24(p21, ntlmchalresp, p24);
350}
e10847ed 351#endif
1da177e4
LT
352
353/* Does the NT MD4 hash then des encryption. */
ee2c9258 354int
1da177e4
LT
355SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
356{
ee2c9258 357 int rc;
43988d76 358 unsigned char p16[16], p21[21];
1da177e4 359
43988d76 360 memset(p16, '\0', 16);
1da177e4
LT
361 memset(p21, '\0', 21);
362
43988d76 363 rc = E_md4hash(passwd, p16);
ee2c9258
SP
364 if (rc) {
365 cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
366 return rc;
367 }
43988d76
SF
368 memcpy(p21, p16, 16);
369 rc = E_P24(p21, c8, p24);
ee2c9258 370 return rc;
1da177e4
LT
371}
372
373
374/* Does the md5 encryption from the NT hash for NTLMv2. */
375/* These routines will be needed later */
376#if 0
377static void
378SMBOWFencrypt_ntv2(const unsigned char kr[16],
790fe579
SF
379 const struct data_blob *srv_chal,
380 const struct data_blob *cli_chal, unsigned char resp_buf[16])
1da177e4 381{
790fe579 382 struct HMACMD5Context ctx;
1da177e4 383
790fe579
SF
384 hmac_md5_init_limK_to_64(kr, 16, &ctx);
385 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
386 hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
387 hmac_md5_final(resp_buf, &ctx);
1da177e4
LT
388}
389
390static void
391SMBsesskeygen_ntv2(const unsigned char kr[16],
392 const unsigned char *nt_resp, __u8 sess_key[16])
393{
394 struct HMACMD5Context ctx;
395
396 hmac_md5_init_limK_to_64(kr, 16, &ctx);
397 hmac_md5_update(nt_resp, 16, &ctx);
398 hmac_md5_final((unsigned char *) sess_key, &ctx);
399}
400
401static void
402SMBsesskeygen_ntv1(const unsigned char kr[16],
403 const unsigned char *nt_resp, __u8 sess_key[16])
404{
405 mdfour((unsigned char *) sess_key, (unsigned char *) kr, 16);
406}
407#endif
This page took 0.481378 seconds and 5 git commands to generate.