Merge branch 'for-linus' of git://git.kernel.dk/linux-block
[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);
93 if (rc) {
94 cERROR(1, "could not encrypt crypt key rc: %d\n", rc);
95 crypto_free_blkcipher(tfm_des);
96 goto smbhash_err;
97 }
98
99smbhash_err:
100 return rc;
101}
102
103static int
104E_P16(unsigned char *p14, unsigned char *p16)
105{
106 int rc;
107 unsigned char sp8[8] =
108 { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
109
110 rc = smbhash(p16, sp8, p14);
111 if (rc)
112 return rc;
113 rc = smbhash(p16 + 8, sp8, p14 + 7);
114 return rc;
115}
116
117static int
118E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
119{
120 int rc;
121
122 rc = smbhash(p24, c8, p21);
123 if (rc)
124 return rc;
125 rc = smbhash(p24 + 8, c8, p21 + 7);
126 if (rc)
127 return rc;
128 rc = smbhash(p24 + 16, c8, p21 + 14);
129 return rc;
130}
131
ee2c9258
SP
132/* produce a md4 message digest from data of length n bytes */
133int
134mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
135{
136 int rc;
137 unsigned int size;
138 struct crypto_shash *md4;
139 struct sdesc *sdescmd4;
140
141 md4 = crypto_alloc_shash("md4", 0, 0);
142 if (IS_ERR(md4)) {
ffeb414a 143 rc = PTR_ERR(md4);
ee2c9258 144 cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc);
ffeb414a 145 return rc;
ee2c9258
SP
146 }
147 size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
148 sdescmd4 = kmalloc(size, GFP_KERNEL);
149 if (!sdescmd4) {
150 rc = -ENOMEM;
151 cERROR(1, "%s: Memory allocation failure\n", __func__);
152 goto mdfour_err;
153 }
154 sdescmd4->shash.tfm = md4;
155 sdescmd4->shash.flags = 0x0;
156
157 rc = crypto_shash_init(&sdescmd4->shash);
158 if (rc) {
159 cERROR(1, "%s: Could not init md4 shash\n", __func__);
160 goto mdfour_err;
161 }
162 crypto_shash_update(&sdescmd4->shash, link_str, link_len);
163 rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
1da177e4 164
ee2c9258
SP
165mdfour_err:
166 crypto_free_shash(md4);
167 kfree(sdescmd4);
168
169 return rc;
170}
171
1da177e4
LT
172/*
173 This implements the X/Open SMB password encryption
790fe579 174 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
1da177e4
LT
175 encrypted password into p24 */
176/* Note that password must be uppercased and null terminated */
43988d76 177int
4e53a3fb 178SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
1da177e4 179{
43988d76
SF
180 int rc;
181 unsigned char p14[14], p16[16], p21[21];
1da177e4 182
1da177e4 183 memset(p14, '\0', 14);
43988d76
SF
184 memset(p16, '\0', 16);
185 memset(p21, '\0', 21);
1da177e4 186
43988d76
SF
187 memcpy(p14, passwd, 14);
188 rc = E_P16(p14, p16);
189 if (rc)
190 return rc;
1da177e4 191
43988d76
SF
192 memcpy(p21, p16, 16);
193 rc = E_P24(p21, c8, p24);
50c2f753 194
43988d76 195 return rc;
1da177e4
LT
196}
197
198/* Routines for Windows NT MD4 Hash functions. */
199static int
63d2583f 200_my_wcslen(__u16 *str)
1da177e4
LT
201{
202 int len = 0;
203 while (*str++ != 0)
204 len++;
205 return len;
206}
207
208/*
209 * Convert a string into an NT UNICODE string.
790fe579 210 * Note that regardless of processor type
1da177e4
LT
211 * this must be in intel (little-endian)
212 * format.
213 */
214
215static int
63d2583f 216_my_mbstowcs(__u16 *dst, const unsigned char *src, int len)
790fe579 217{ /* BB not a very good conversion routine - change/fix */
1da177e4
LT
218 int i;
219 __u16 val;
220
221 for (i = 0; i < len; i++) {
222 val = *src;
223 SSVAL(dst, 0, val);
224 dst++;
225 src++;
226 if (val == 0)
227 break;
228 }
229 return i;
230}
231
790fe579 232/*
1da177e4
LT
233 * Creates the MD4 Hash of the users password in NT UNICODE.
234 */
235
ee2c9258 236int
1da177e4
LT
237E_md4hash(const unsigned char *passwd, unsigned char *p16)
238{
ee2c9258 239 int rc;
1da177e4
LT
240 int len;
241 __u16 wpwd[129];
242
243 /* Password cannot be longer than 128 characters */
790fe579 244 if (passwd) {
1da177e4 245 len = strlen((char *) passwd);
63d2583f 246 if (len > 128)
1da177e4 247 len = 128;
63d2583f 248
1da177e4
LT
249 /* Password must be converted to NT unicode */
250 _my_mbstowcs(wpwd, passwd, len);
251 } else
252 len = 0;
253
254 wpwd[len] = 0; /* Ensure string is null terminated */
255 /* Calculate length in bytes */
630f3f0c 256 len = _my_wcslen(wpwd) * sizeof(__u16);
1da177e4 257
ee2c9258 258 rc = mdfour(p16, (unsigned char *) wpwd, len);
790fe579 259 memset(wpwd, 0, 129 * 2);
ee2c9258
SP
260
261 return rc;
1da177e4
LT
262}
263
e10847ed 264#if 0 /* currently unused */
1da177e4 265/* Does both the NT and LM owfs of a user's password */
2cd646a2 266static void
1da177e4
LT
267nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
268{
269 char passwd[514];
270
271 memset(passwd, '\0', 514);
272 if (strlen(pwd) < 513)
273 strcpy(passwd, pwd);
274 else
275 memcpy(passwd, pwd, 512);
276 /* Calculate the MD4 hash (NT compatible) of the password */
277 memset(nt_p16, '\0', 16);
278 E_md4hash(passwd, nt_p16);
279
280 /* Mangle the passwords into Lanman format */
281 passwd[14] = '\0';
282/* strupper(passwd); */
283
284 /* Calculate the SMB (lanman) hash functions of the password */
285
286 memset(p16, '\0', 16);
287 E_P16((unsigned char *) passwd, (unsigned char *) p16);
288
289 /* clear out local copy of user's password (just being paranoid). */
630f3f0c 290 memset(passwd, '\0', sizeof(passwd));
1da177e4 291}
e10847ed 292#endif
1da177e4
LT
293
294/* Does the NTLMv2 owfs of a user's password */
295#if 0 /* function not needed yet - but will be soon */
296static void
297ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
298 const char *domain_n, unsigned char kr_buf[16],
299 const struct nls_table *nls_codepage)
300{
50c2f753
SF
301 wchar_t *user_u;
302 wchar_t *dom_u;
1da177e4
LT
303 int user_l, domain_l;
304 struct HMACMD5Context ctx;
305
306 /* might as well do one alloc to hold both (user_u and dom_u) */
790fe579
SF
307 user_u = kmalloc(2048 * sizeof(wchar_t), GFP_KERNEL);
308 if (user_u == NULL)
1da177e4
LT
309 return;
310 dom_u = user_u + 1024;
50c2f753 311
63d2583f
SF
312 /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2,
313 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
314 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2,
315 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
1da177e4
LT
316
317 /* BB user and domain may need to be uppercased */
318 user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
319 domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
320
321 user_l++; /* trailing null */
322 domain_l++;
323
324 hmac_md5_init_limK_to_64(owf, 16, &ctx);
325 hmac_md5_update((const unsigned char *) user_u, user_l * 2, &ctx);
326 hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &ctx);
327 hmac_md5_final(kr_buf, &ctx);
328
329 kfree(user_u);
330}
790fe579 331#endif
1da177e4 332
1da177e4 333/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
e10847ed 334#if 0 /* currently unused */
2cd646a2 335static void
1da177e4
LT
336NTLMSSPOWFencrypt(unsigned char passwd[8],
337 unsigned char *ntlmchalresp, unsigned char p24[24])
338{
339 unsigned char p21[21];
340
341 memset(p21, '\0', 21);
342 memcpy(p21, passwd, 8);
343 memset(p21 + 8, 0xbd, 8);
344
345 E_P24(p21, ntlmchalresp, p24);
346}
e10847ed 347#endif
1da177e4
LT
348
349/* Does the NT MD4 hash then des encryption. */
ee2c9258 350int
1da177e4
LT
351SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
352{
ee2c9258 353 int rc;
43988d76 354 unsigned char p16[16], p21[21];
1da177e4 355
43988d76 356 memset(p16, '\0', 16);
1da177e4
LT
357 memset(p21, '\0', 21);
358
43988d76 359 rc = E_md4hash(passwd, p16);
ee2c9258
SP
360 if (rc) {
361 cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
362 return rc;
363 }
43988d76
SF
364 memcpy(p21, p16, 16);
365 rc = E_P24(p21, c8, p24);
ee2c9258 366 return rc;
1da177e4
LT
367}
368
369
370/* Does the md5 encryption from the NT hash for NTLMv2. */
371/* These routines will be needed later */
372#if 0
373static void
374SMBOWFencrypt_ntv2(const unsigned char kr[16],
790fe579
SF
375 const struct data_blob *srv_chal,
376 const struct data_blob *cli_chal, unsigned char resp_buf[16])
1da177e4 377{
790fe579 378 struct HMACMD5Context ctx;
1da177e4 379
790fe579
SF
380 hmac_md5_init_limK_to_64(kr, 16, &ctx);
381 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
382 hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
383 hmac_md5_final(resp_buf, &ctx);
1da177e4
LT
384}
385
386static void
387SMBsesskeygen_ntv2(const unsigned char kr[16],
388 const unsigned char *nt_resp, __u8 sess_key[16])
389{
390 struct HMACMD5Context ctx;
391
392 hmac_md5_init_limK_to_64(kr, 16, &ctx);
393 hmac_md5_update(nt_resp, 16, &ctx);
394 hmac_md5_final((unsigned char *) sess_key, &ctx);
395}
396
397static void
398SMBsesskeygen_ntv1(const unsigned char kr[16],
399 const unsigned char *nt_resp, __u8 sess_key[16])
400{
401 mdfour((unsigned char *) sess_key, (unsigned char *) kr, 16);
402}
403#endif
This page took 0.538299 seconds and 5 git commands to generate.