Merge branch 'postmerge' into for-linus
[linux-2.6-block.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);
f96637be 81 cifs_dbg(VFS, "could not allocate des crypto API\n");
43988d76
SF
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)
f96637be 94 cifs_dbg(VFS, "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);
f96637be
JP
142 cifs_dbg(VFS, "%s: Crypto md4 allocation error %d\n",
143 __func__, rc);
ffeb414a 144 return rc;
ee2c9258
SP
145 }
146 size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
147 sdescmd4 = kmalloc(size, GFP_KERNEL);
148 if (!sdescmd4) {
149 rc = -ENOMEM;
ee2c9258
SP
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) {
f96637be 157 cifs_dbg(VFS, "%s: Could not init md4 shash\n", __func__);
ee2c9258
SP
158 goto mdfour_err;
159 }
14cae324
SP
160 rc = crypto_shash_update(&sdescmd4->shash, link_str, link_len);
161 if (rc) {
f96637be 162 cifs_dbg(VFS, "%s: Could not update with link_str\n", __func__);
14cae324
SP
163 goto mdfour_err;
164 }
ee2c9258 165 rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
14cae324 166 if (rc)
f96637be 167 cifs_dbg(VFS, "%s: Could not generate 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
790fe579 202/*
1da177e4
LT
203 * Creates the MD4 Hash of the users password in NT UNICODE.
204 */
205
ee2c9258 206int
9ef5992e
SP
207E_md4hash(const unsigned char *passwd, unsigned char *p16,
208 const struct nls_table *codepage)
1da177e4 209{
ee2c9258 210 int rc;
1da177e4 211 int len;
9c32c63b 212 __le16 wpwd[129];
1da177e4
LT
213
214 /* Password cannot be longer than 128 characters */
9ef5992e 215 if (passwd) /* Password must be converted to NT unicode */
acbbb76a 216 len = cifs_strtoUTF16(wpwd, passwd, 128, codepage);
9ef5992e 217 else {
1da177e4 218 len = 0;
9ef5992e
SP
219 *wpwd = 0; /* Ensure string is null terminated */
220 }
1da177e4 221
9c32c63b
SF
222 rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16));
223 memset(wpwd, 0, 129 * sizeof(__le16));
ee2c9258
SP
224
225 return rc;
1da177e4
LT
226}
227
1da177e4 228/* Does the NT MD4 hash then des encryption. */
ee2c9258 229int
9ef5992e
SP
230SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
231 const struct nls_table *codepage)
1da177e4 232{
ee2c9258 233 int rc;
43988d76 234 unsigned char p16[16], p21[21];
1da177e4 235
43988d76 236 memset(p16, '\0', 16);
1da177e4
LT
237 memset(p21, '\0', 21);
238
9ef5992e 239 rc = E_md4hash(passwd, p16, codepage);
ee2c9258 240 if (rc) {
f96637be
JP
241 cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
242 __func__, rc);
ee2c9258
SP
243 return rc;
244 }
43988d76
SF
245 memcpy(p21, p16, 16);
246 rc = E_P24(p21, c8, p24);
ee2c9258 247 return rc;
1da177e4 248}