Merge tag 'dm-3.19-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device...
[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>
2baa2682 32#include "cifs_fs_sb.h"
1da177e4
LT
33#include "cifs_unicode.h"
34#include "cifspdu.h"
3979877e 35#include "cifsglob.h"
1da177e4 36#include "cifs_debug.h"
ee2c9258 37#include "cifsproto.h"
1da177e4 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
43988d76
SF
51static void
52str_to_key(unsigned char *str, unsigned char *key)
53{
54 int i;
55
56 key[0] = str[0] >> 1;
57 key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
58 key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
59 key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
60 key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
61 key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
62 key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
63 key[7] = str[6] & 0x7F;
64 for (i = 0; i < 8; i++)
65 key[i] = (key[i] << 1);
66}
67
68static int
69smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
70{
71 int rc;
72 unsigned char key2[8];
73 struct crypto_blkcipher *tfm_des;
74 struct scatterlist sgin, sgout;
75 struct blkcipher_desc desc;
76
77 str_to_key(key, key2);
78
79 tfm_des = crypto_alloc_blkcipher("ecb(des)", 0, CRYPTO_ALG_ASYNC);
80 if (IS_ERR(tfm_des)) {
81 rc = PTR_ERR(tfm_des);
f96637be 82 cifs_dbg(VFS, "could not allocate des crypto API\n");
43988d76
SF
83 goto smbhash_err;
84 }
85
86 desc.tfm = tfm_des;
87
88 crypto_blkcipher_setkey(tfm_des, key2, 8);
89
90 sg_init_one(&sgin, in, 8);
91 sg_init_one(&sgout, out, 8);
92
93 rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, 8);
e4fb0edb 94 if (rc)
f96637be 95 cifs_dbg(VFS, "could not encrypt crypt key rc: %d\n", rc);
43988d76 96
e4fb0edb 97 crypto_free_blkcipher(tfm_des);
43988d76
SF
98smbhash_err:
99 return rc;
100}
101
102static int
103E_P16(unsigned char *p14, unsigned char *p16)
104{
105 int rc;
106 unsigned char sp8[8] =
107 { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
108
109 rc = smbhash(p16, sp8, p14);
110 if (rc)
111 return rc;
112 rc = smbhash(p16 + 8, sp8, p14 + 7);
113 return rc;
114}
115
116static int
117E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
118{
119 int rc;
120
121 rc = smbhash(p24, c8, p21);
122 if (rc)
123 return rc;
124 rc = smbhash(p24 + 8, c8, p21 + 7);
125 if (rc)
126 return rc;
127 rc = smbhash(p24 + 16, c8, p21 + 14);
128 return rc;
129}
130
ee2c9258
SP
131/* produce a md4 message digest from data of length n bytes */
132int
133mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
134{
135 int rc;
136 unsigned int size;
137 struct crypto_shash *md4;
138 struct sdesc *sdescmd4;
139
140 md4 = crypto_alloc_shash("md4", 0, 0);
141 if (IS_ERR(md4)) {
ffeb414a 142 rc = PTR_ERR(md4);
f96637be
JP
143 cifs_dbg(VFS, "%s: Crypto md4 allocation error %d\n",
144 __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;
ee2c9258
SP
151 goto mdfour_err;
152 }
153 sdescmd4->shash.tfm = md4;
154 sdescmd4->shash.flags = 0x0;
155
156 rc = crypto_shash_init(&sdescmd4->shash);
157 if (rc) {
f96637be 158 cifs_dbg(VFS, "%s: Could not init md4 shash\n", __func__);
ee2c9258
SP
159 goto mdfour_err;
160 }
14cae324
SP
161 rc = crypto_shash_update(&sdescmd4->shash, link_str, link_len);
162 if (rc) {
f96637be 163 cifs_dbg(VFS, "%s: Could not update with link_str\n", __func__);
14cae324
SP
164 goto mdfour_err;
165 }
ee2c9258 166 rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
14cae324 167 if (rc)
f96637be 168 cifs_dbg(VFS, "%s: Could not generate md4 hash\n", __func__);
1da177e4 169
ee2c9258
SP
170mdfour_err:
171 crypto_free_shash(md4);
172 kfree(sdescmd4);
173
174 return rc;
175}
176
1da177e4
LT
177/*
178 This implements the X/Open SMB password encryption
790fe579 179 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
1da177e4
LT
180 encrypted password into p24 */
181/* Note that password must be uppercased and null terminated */
43988d76 182int
4e53a3fb 183SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
1da177e4 184{
43988d76
SF
185 int rc;
186 unsigned char p14[14], p16[16], p21[21];
1da177e4 187
1da177e4 188 memset(p14, '\0', 14);
43988d76
SF
189 memset(p16, '\0', 16);
190 memset(p21, '\0', 21);
1da177e4 191
43988d76
SF
192 memcpy(p14, passwd, 14);
193 rc = E_P16(p14, p16);
194 if (rc)
195 return rc;
1da177e4 196
43988d76
SF
197 memcpy(p21, p16, 16);
198 rc = E_P24(p21, c8, p24);
50c2f753 199
43988d76 200 return rc;
1da177e4
LT
201}
202
790fe579 203/*
1da177e4
LT
204 * Creates the MD4 Hash of the users password in NT UNICODE.
205 */
206
ee2c9258 207int
9ef5992e
SP
208E_md4hash(const unsigned char *passwd, unsigned char *p16,
209 const struct nls_table *codepage)
1da177e4 210{
ee2c9258 211 int rc;
1da177e4 212 int len;
9c32c63b 213 __le16 wpwd[129];
1da177e4
LT
214
215 /* Password cannot be longer than 128 characters */
9ef5992e 216 if (passwd) /* Password must be converted to NT unicode */
acbbb76a 217 len = cifs_strtoUTF16(wpwd, passwd, 128, codepage);
9ef5992e 218 else {
1da177e4 219 len = 0;
9ef5992e
SP
220 *wpwd = 0; /* Ensure string is null terminated */
221 }
1da177e4 222
9c32c63b
SF
223 rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16));
224 memset(wpwd, 0, 129 * sizeof(__le16));
ee2c9258
SP
225
226 return rc;
1da177e4
LT
227}
228
1da177e4 229/* Does the NT MD4 hash then des encryption. */
ee2c9258 230int
9ef5992e
SP
231SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
232 const struct nls_table *codepage)
1da177e4 233{
ee2c9258 234 int rc;
43988d76 235 unsigned char p16[16], p21[21];
1da177e4 236
43988d76 237 memset(p16, '\0', 16);
1da177e4
LT
238 memset(p21, '\0', 21);
239
9ef5992e 240 rc = E_md4hash(passwd, p16, codepage);
ee2c9258 241 if (rc) {
f96637be
JP
242 cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
243 __func__, rc);
ee2c9258
SP
244 return rc;
245 }
43988d76
SF
246 memcpy(p21, p16, 16);
247 rc = E_P24(p21, c8, p24);
ee2c9258 248 return rc;
1da177e4 249}