Merge branch 'omap-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[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
ee2c9258
SP
50/* produce a md4 message digest from data of length n bytes */
51int
52mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
53{
54 int rc;
55 unsigned int size;
56 struct crypto_shash *md4;
57 struct sdesc *sdescmd4;
58
59 md4 = crypto_alloc_shash("md4", 0, 0);
60 if (IS_ERR(md4)) {
61 cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc);
62 return PTR_ERR(md4);
63 }
64 size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
65 sdescmd4 = kmalloc(size, GFP_KERNEL);
66 if (!sdescmd4) {
67 rc = -ENOMEM;
68 cERROR(1, "%s: Memory allocation failure\n", __func__);
69 goto mdfour_err;
70 }
71 sdescmd4->shash.tfm = md4;
72 sdescmd4->shash.flags = 0x0;
73
74 rc = crypto_shash_init(&sdescmd4->shash);
75 if (rc) {
76 cERROR(1, "%s: Could not init md4 shash\n", __func__);
77 goto mdfour_err;
78 }
79 crypto_shash_update(&sdescmd4->shash, link_str, link_len);
80 rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
1da177e4 81
ee2c9258
SP
82mdfour_err:
83 crypto_free_shash(md4);
84 kfree(sdescmd4);
85
86 return rc;
87}
88
89/* Does the des encryption from the NT or LM MD4 hash. */
90static void
91SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
92 unsigned char p24[24])
93{
94 unsigned char p21[21];
95
96 memset(p21, '\0', 21);
97
98 memcpy(p21, passwd, 16);
99 E_P24(p21, c8, p24);
100}
1da177e4
LT
101
102/*
103 This implements the X/Open SMB password encryption
790fe579 104 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
1da177e4
LT
105 encrypted password into p24 */
106/* Note that password must be uppercased and null terminated */
107void
4e53a3fb 108SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
1da177e4
LT
109{
110 unsigned char p14[15], p21[21];
111
112 memset(p21, '\0', 21);
113 memset(p14, '\0', 14);
114 strncpy((char *) p14, (char *) passwd, 14);
115
116/* strupper((char *)p14); *//* BB at least uppercase the easy range */
117 E_P16(p14, p21);
118
119 SMBOWFencrypt(p21, c8, p24);
50c2f753 120
790fe579
SF
121 memset(p14, 0, 15);
122 memset(p21, 0, 21);
1da177e4
LT
123}
124
125/* Routines for Windows NT MD4 Hash functions. */
126static int
63d2583f 127_my_wcslen(__u16 *str)
1da177e4
LT
128{
129 int len = 0;
130 while (*str++ != 0)
131 len++;
132 return len;
133}
134
135/*
136 * Convert a string into an NT UNICODE string.
790fe579 137 * Note that regardless of processor type
1da177e4
LT
138 * this must be in intel (little-endian)
139 * format.
140 */
141
142static int
63d2583f 143_my_mbstowcs(__u16 *dst, const unsigned char *src, int len)
790fe579 144{ /* BB not a very good conversion routine - change/fix */
1da177e4
LT
145 int i;
146 __u16 val;
147
148 for (i = 0; i < len; i++) {
149 val = *src;
150 SSVAL(dst, 0, val);
151 dst++;
152 src++;
153 if (val == 0)
154 break;
155 }
156 return i;
157}
158
790fe579 159/*
1da177e4
LT
160 * Creates the MD4 Hash of the users password in NT UNICODE.
161 */
162
ee2c9258 163int
1da177e4
LT
164E_md4hash(const unsigned char *passwd, unsigned char *p16)
165{
ee2c9258 166 int rc;
1da177e4
LT
167 int len;
168 __u16 wpwd[129];
169
170 /* Password cannot be longer than 128 characters */
790fe579 171 if (passwd) {
1da177e4 172 len = strlen((char *) passwd);
63d2583f 173 if (len > 128)
1da177e4 174 len = 128;
63d2583f 175
1da177e4
LT
176 /* Password must be converted to NT unicode */
177 _my_mbstowcs(wpwd, passwd, len);
178 } else
179 len = 0;
180
181 wpwd[len] = 0; /* Ensure string is null terminated */
182 /* Calculate length in bytes */
630f3f0c 183 len = _my_wcslen(wpwd) * sizeof(__u16);
1da177e4 184
ee2c9258 185 rc = mdfour(p16, (unsigned char *) wpwd, len);
790fe579 186 memset(wpwd, 0, 129 * 2);
ee2c9258
SP
187
188 return rc;
1da177e4
LT
189}
190
e10847ed 191#if 0 /* currently unused */
1da177e4 192/* Does both the NT and LM owfs of a user's password */
2cd646a2 193static void
1da177e4
LT
194nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
195{
196 char passwd[514];
197
198 memset(passwd, '\0', 514);
199 if (strlen(pwd) < 513)
200 strcpy(passwd, pwd);
201 else
202 memcpy(passwd, pwd, 512);
203 /* Calculate the MD4 hash (NT compatible) of the password */
204 memset(nt_p16, '\0', 16);
205 E_md4hash(passwd, nt_p16);
206
207 /* Mangle the passwords into Lanman format */
208 passwd[14] = '\0';
209/* strupper(passwd); */
210
211 /* Calculate the SMB (lanman) hash functions of the password */
212
213 memset(p16, '\0', 16);
214 E_P16((unsigned char *) passwd, (unsigned char *) p16);
215
216 /* clear out local copy of user's password (just being paranoid). */
630f3f0c 217 memset(passwd, '\0', sizeof(passwd));
1da177e4 218}
e10847ed 219#endif
1da177e4
LT
220
221/* Does the NTLMv2 owfs of a user's password */
222#if 0 /* function not needed yet - but will be soon */
223static void
224ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
225 const char *domain_n, unsigned char kr_buf[16],
226 const struct nls_table *nls_codepage)
227{
50c2f753
SF
228 wchar_t *user_u;
229 wchar_t *dom_u;
1da177e4
LT
230 int user_l, domain_l;
231 struct HMACMD5Context ctx;
232
233 /* might as well do one alloc to hold both (user_u and dom_u) */
790fe579
SF
234 user_u = kmalloc(2048 * sizeof(wchar_t), GFP_KERNEL);
235 if (user_u == NULL)
1da177e4
LT
236 return;
237 dom_u = user_u + 1024;
50c2f753 238
63d2583f
SF
239 /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2,
240 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
241 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2,
242 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
1da177e4
LT
243
244 /* BB user and domain may need to be uppercased */
245 user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
246 domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
247
248 user_l++; /* trailing null */
249 domain_l++;
250
251 hmac_md5_init_limK_to_64(owf, 16, &ctx);
252 hmac_md5_update((const unsigned char *) user_u, user_l * 2, &ctx);
253 hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &ctx);
254 hmac_md5_final(kr_buf, &ctx);
255
256 kfree(user_u);
257}
790fe579 258#endif
1da177e4 259
1da177e4 260/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
e10847ed 261#if 0 /* currently unused */
2cd646a2 262static void
1da177e4
LT
263NTLMSSPOWFencrypt(unsigned char passwd[8],
264 unsigned char *ntlmchalresp, unsigned char p24[24])
265{
266 unsigned char p21[21];
267
268 memset(p21, '\0', 21);
269 memcpy(p21, passwd, 8);
270 memset(p21 + 8, 0xbd, 8);
271
272 E_P24(p21, ntlmchalresp, p24);
273}
e10847ed 274#endif
1da177e4
LT
275
276/* Does the NT MD4 hash then des encryption. */
ee2c9258 277int
1da177e4
LT
278SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
279{
ee2c9258 280 int rc;
1da177e4
LT
281 unsigned char p21[21];
282
283 memset(p21, '\0', 21);
284
ee2c9258
SP
285 rc = E_md4hash(passwd, p21);
286 if (rc) {
287 cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
288 return rc;
289 }
1da177e4 290 SMBOWFencrypt(p21, c8, p24);
ee2c9258 291 return rc;
1da177e4
LT
292}
293
294
295/* Does the md5 encryption from the NT hash for NTLMv2. */
296/* These routines will be needed later */
297#if 0
298static void
299SMBOWFencrypt_ntv2(const unsigned char kr[16],
790fe579
SF
300 const struct data_blob *srv_chal,
301 const struct data_blob *cli_chal, unsigned char resp_buf[16])
1da177e4 302{
790fe579 303 struct HMACMD5Context ctx;
1da177e4 304
790fe579
SF
305 hmac_md5_init_limK_to_64(kr, 16, &ctx);
306 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
307 hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
308 hmac_md5_final(resp_buf, &ctx);
1da177e4
LT
309}
310
311static void
312SMBsesskeygen_ntv2(const unsigned char kr[16],
313 const unsigned char *nt_resp, __u8 sess_key[16])
314{
315 struct HMACMD5Context ctx;
316
317 hmac_md5_init_limK_to_64(kr, 16, &ctx);
318 hmac_md5_update(nt_resp, 16, &ctx);
319 hmac_md5_final((unsigned char *) sess_key, &ctx);
320}
321
322static void
323SMBsesskeygen_ntv1(const unsigned char kr[16],
324 const unsigned char *nt_resp, __u8 sess_key[16])
325{
326 mdfour((unsigned char *) sess_key, (unsigned char *) kr, 16);
327}
328#endif
This page took 0.789535 seconds and 5 git commands to generate.