]> bbs.cooldavid.org Git - net-next-2.6.git/blame - fs/cifs/smbencrypt.c
xps: Transmit Packet Steering
[net-next-2.6.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
LT
35#include "md5.h"
36#include "cifs_debug.h"
37#include "cifsencrypt.h"
38
4b18f2a9
SF
39#ifndef false
40#define false 0
1da177e4 41#endif
4b18f2a9
SF
42#ifndef true
43#define true 1
1da177e4
LT
44#endif
45
46/* following came from the other byteorder.h to avoid include conflicts */
47#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
48#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
49#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
50
51/*The following definitions come from libsmb/smbencrypt.c */
52
4e53a3fb
JL
53void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
54 unsigned char *p24);
1da177e4 55void E_md4hash(const unsigned char *passwd, unsigned char *p16);
4e53a3fb 56static void SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
1da177e4 57 unsigned char p24[24]);
1da177e4
LT
58void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
59
60/*
61 This implements the X/Open SMB password encryption
790fe579 62 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
1da177e4
LT
63 encrypted password into p24 */
64/* Note that password must be uppercased and null terminated */
65void
4e53a3fb 66SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
1da177e4
LT
67{
68 unsigned char p14[15], p21[21];
69
70 memset(p21, '\0', 21);
71 memset(p14, '\0', 14);
72 strncpy((char *) p14, (char *) passwd, 14);
73
74/* strupper((char *)p14); *//* BB at least uppercase the easy range */
75 E_P16(p14, p21);
76
77 SMBOWFencrypt(p21, c8, p24);
50c2f753 78
790fe579
SF
79 memset(p14, 0, 15);
80 memset(p21, 0, 21);
1da177e4
LT
81}
82
83/* Routines for Windows NT MD4 Hash functions. */
84static int
63d2583f 85_my_wcslen(__u16 *str)
1da177e4
LT
86{
87 int len = 0;
88 while (*str++ != 0)
89 len++;
90 return len;
91}
92
93/*
94 * Convert a string into an NT UNICODE string.
790fe579 95 * Note that regardless of processor type
1da177e4
LT
96 * this must be in intel (little-endian)
97 * format.
98 */
99
100static int
63d2583f 101_my_mbstowcs(__u16 *dst, const unsigned char *src, int len)
790fe579 102{ /* BB not a very good conversion routine - change/fix */
1da177e4
LT
103 int i;
104 __u16 val;
105
106 for (i = 0; i < len; i++) {
107 val = *src;
108 SSVAL(dst, 0, val);
109 dst++;
110 src++;
111 if (val == 0)
112 break;
113 }
114 return i;
115}
116
790fe579 117/*
1da177e4
LT
118 * Creates the MD4 Hash of the users password in NT UNICODE.
119 */
120
121void
122E_md4hash(const unsigned char *passwd, unsigned char *p16)
123{
124 int len;
125 __u16 wpwd[129];
126
127 /* Password cannot be longer than 128 characters */
790fe579 128 if (passwd) {
1da177e4 129 len = strlen((char *) passwd);
63d2583f 130 if (len > 128)
1da177e4 131 len = 128;
63d2583f 132
1da177e4
LT
133 /* Password must be converted to NT unicode */
134 _my_mbstowcs(wpwd, passwd, len);
135 } else
136 len = 0;
137
138 wpwd[len] = 0; /* Ensure string is null terminated */
139 /* Calculate length in bytes */
630f3f0c 140 len = _my_wcslen(wpwd) * sizeof(__u16);
1da177e4
LT
141
142 mdfour(p16, (unsigned char *) wpwd, len);
790fe579 143 memset(wpwd, 0, 129 * 2);
1da177e4
LT
144}
145
e10847ed 146#if 0 /* currently unused */
1da177e4 147/* Does both the NT and LM owfs of a user's password */
2cd646a2 148static void
1da177e4
LT
149nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
150{
151 char passwd[514];
152
153 memset(passwd, '\0', 514);
154 if (strlen(pwd) < 513)
155 strcpy(passwd, pwd);
156 else
157 memcpy(passwd, pwd, 512);
158 /* Calculate the MD4 hash (NT compatible) of the password */
159 memset(nt_p16, '\0', 16);
160 E_md4hash(passwd, nt_p16);
161
162 /* Mangle the passwords into Lanman format */
163 passwd[14] = '\0';
164/* strupper(passwd); */
165
166 /* Calculate the SMB (lanman) hash functions of the password */
167
168 memset(p16, '\0', 16);
169 E_P16((unsigned char *) passwd, (unsigned char *) p16);
170
171 /* clear out local copy of user's password (just being paranoid). */
630f3f0c 172 memset(passwd, '\0', sizeof(passwd));
1da177e4 173}
e10847ed 174#endif
1da177e4
LT
175
176/* Does the NTLMv2 owfs of a user's password */
177#if 0 /* function not needed yet - but will be soon */
178static void
179ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
180 const char *domain_n, unsigned char kr_buf[16],
181 const struct nls_table *nls_codepage)
182{
50c2f753
SF
183 wchar_t *user_u;
184 wchar_t *dom_u;
1da177e4
LT
185 int user_l, domain_l;
186 struct HMACMD5Context ctx;
187
188 /* might as well do one alloc to hold both (user_u and dom_u) */
790fe579
SF
189 user_u = kmalloc(2048 * sizeof(wchar_t), GFP_KERNEL);
190 if (user_u == NULL)
1da177e4
LT
191 return;
192 dom_u = user_u + 1024;
50c2f753 193
63d2583f
SF
194 /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2,
195 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
196 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2,
197 STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
1da177e4
LT
198
199 /* BB user and domain may need to be uppercased */
200 user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
201 domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
202
203 user_l++; /* trailing null */
204 domain_l++;
205
206 hmac_md5_init_limK_to_64(owf, 16, &ctx);
207 hmac_md5_update((const unsigned char *) user_u, user_l * 2, &ctx);
208 hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &ctx);
209 hmac_md5_final(kr_buf, &ctx);
210
211 kfree(user_u);
212}
790fe579 213#endif
1da177e4
LT
214
215/* Does the des encryption from the NT or LM MD4 hash. */
216static void
4e53a3fb 217SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
1da177e4
LT
218 unsigned char p24[24])
219{
220 unsigned char p21[21];
221
222 memset(p21, '\0', 21);
223
224 memcpy(p21, passwd, 16);
225 E_P24(p21, c8, p24);
226}
227
228/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
e10847ed 229#if 0 /* currently unused */
2cd646a2 230static void
1da177e4
LT
231NTLMSSPOWFencrypt(unsigned char passwd[8],
232 unsigned char *ntlmchalresp, unsigned char p24[24])
233{
234 unsigned char p21[21];
235
236 memset(p21, '\0', 21);
237 memcpy(p21, passwd, 8);
238 memset(p21 + 8, 0xbd, 8);
239
240 E_P24(p21, ntlmchalresp, p24);
241}
e10847ed 242#endif
1da177e4
LT
243
244/* Does the NT MD4 hash then des encryption. */
245
246void
247SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
248{
249 unsigned char p21[21];
250
251 memset(p21, '\0', 21);
252
253 E_md4hash(passwd, p21);
254 SMBOWFencrypt(p21, c8, p24);
255}
256
257
258/* Does the md5 encryption from the NT hash for NTLMv2. */
259/* These routines will be needed later */
260#if 0
261static void
262SMBOWFencrypt_ntv2(const unsigned char kr[16],
790fe579
SF
263 const struct data_blob *srv_chal,
264 const struct data_blob *cli_chal, unsigned char resp_buf[16])
1da177e4 265{
790fe579 266 struct HMACMD5Context ctx;
1da177e4 267
790fe579
SF
268 hmac_md5_init_limK_to_64(kr, 16, &ctx);
269 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
270 hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
271 hmac_md5_final(resp_buf, &ctx);
1da177e4
LT
272}
273
274static void
275SMBsesskeygen_ntv2(const unsigned char kr[16],
276 const unsigned char *nt_resp, __u8 sess_key[16])
277{
278 struct HMACMD5Context ctx;
279
280 hmac_md5_init_limK_to_64(kr, 16, &ctx);
281 hmac_md5_update(nt_resp, 16, &ctx);
282 hmac_md5_final((unsigned char *) sess_key, &ctx);
283}
284
285static void
286SMBsesskeygen_ntv1(const unsigned char kr[16],
287 const unsigned char *nt_resp, __u8 sess_key[16])
288{
289 mdfour((unsigned char *) sess_key, (unsigned char *) kr, 16);
290}
291#endif