Blame view

fs/cifs/smbencrypt.c 5.97 KB
790fe579f   Steve French   [CIFS] more white...
1
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
     Unix SMB/Netbios implementation.
     Version 1.9.
     SMB parameters and setup
     Copyright (C) Andrew Tridgell 1992-2000
     Copyright (C) Luke Kenneth Casson Leighton 1996-2000
     Modified by Jeremy Allison 1995.
     Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
     Modified by Steve French (sfrench@us.ibm.com) 2002-2003
50c2f7538   Steve French   [CIFS] whitespace...
10

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
50c2f7538   Steve French   [CIFS] whitespace...
15

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
18
19
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
50c2f7538   Steve French   [CIFS] whitespace...
20

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
23
24
25
26
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
  
  #include <linux/module.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
27
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
29
30
31
32
33
  #include <linux/fs.h>
  #include <linux/string.h>
  #include <linux/kernel.h>
  #include <linux/random.h>
  #include "cifs_unicode.h"
  #include "cifspdu.h"
3979877e5   Steve French   [CIFS] Support fo...
34
  #include "cifsglob.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
  #include "cifs_debug.h"
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
36
  #include "cifsproto.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37

4b18f2a9c   Steve French   [CIFS] convert us...
38
39
  #ifndef false
  #define false 0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
  #endif
4b18f2a9c   Steve French   [CIFS] convert us...
41
42
  #ifndef true
  #define true 1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
46
47
48
  #endif
  
  /* following came from the other byteorder.h to avoid include conflicts */
  #define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
  #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
  #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
43988d768   Steve French   [CIFS] Use ecb de...
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
  static void
  str_to_key(unsigned char *str, unsigned char *key)
  {
  	int i;
  
  	key[0] = str[0] >> 1;
  	key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
  	key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
  	key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
  	key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
  	key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
  	key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
  	key[7] = str[6] & 0x7F;
  	for (i = 0; i < 8; i++)
  		key[i] = (key[i] << 1);
  }
  
  static int
  smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
  {
  	int rc;
  	unsigned char key2[8];
  	struct crypto_blkcipher *tfm_des;
  	struct scatterlist sgin, sgout;
  	struct blkcipher_desc desc;
  
  	str_to_key(key, key2);
  
  	tfm_des = crypto_alloc_blkcipher("ecb(des)", 0, CRYPTO_ALG_ASYNC);
  	if (IS_ERR(tfm_des)) {
  		rc = PTR_ERR(tfm_des);
ac3aa2f8a   Jeff Layton   cifs: remove extr...
80
  		cERROR(1, "could not allocate des crypto API");
43988d768   Steve French   [CIFS] Use ecb de...
81
82
83
84
85
86
87
88
89
90
91
  		goto smbhash_err;
  	}
  
  	desc.tfm = tfm_des;
  
  	crypto_blkcipher_setkey(tfm_des, key2, 8);
  
  	sg_init_one(&sgin, in, 8);
  	sg_init_one(&sgout, out, 8);
  
  	rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, 8);
e4fb0edb7   Jeff Layton   cifs: free blkcip...
92
  	if (rc)
ac3aa2f8a   Jeff Layton   cifs: remove extr...
93
  		cERROR(1, "could not encrypt crypt key rc: %d", rc);
43988d768   Steve French   [CIFS] Use ecb de...
94

e4fb0edb7   Jeff Layton   cifs: free blkcip...
95
  	crypto_free_blkcipher(tfm_des);
43988d768   Steve French   [CIFS] Use ecb de...
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  smbhash_err:
  	return rc;
  }
  
  static int
  E_P16(unsigned char *p14, unsigned char *p16)
  {
  	int rc;
  	unsigned char sp8[8] =
  	    { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
  
  	rc = smbhash(p16, sp8, p14);
  	if (rc)
  		return rc;
  	rc = smbhash(p16 + 8, sp8, p14 + 7);
  	return rc;
  }
  
  static int
  E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
  {
  	int rc;
  
  	rc = smbhash(p24, c8, p21);
  	if (rc)
  		return rc;
  	rc = smbhash(p24 + 8, c8, p21 + 7);
  	if (rc)
  		return rc;
  	rc = smbhash(p24 + 16, c8, p21 + 14);
  	return rc;
  }
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
128
129
130
131
132
133
134
135
136
137
138
  /* produce a md4 message digest from data of length n bytes */
  int
  mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
  {
  	int rc;
  	unsigned int size;
  	struct crypto_shash *md4;
  	struct sdesc *sdescmd4;
  
  	md4 = crypto_alloc_shash("md4", 0, 0);
  	if (IS_ERR(md4)) {
ffeb414a5   Jeff Layton   cifs: fix two com...
139
  		rc = PTR_ERR(md4);
ac3aa2f8a   Jeff Layton   cifs: remove extr...
140
  		cERROR(1, "%s: Crypto md4 allocation error %d", __func__, rc);
ffeb414a5   Jeff Layton   cifs: fix two com...
141
  		return rc;
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
142
143
144
145
146
  	}
  	size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
  	sdescmd4 = kmalloc(size, GFP_KERNEL);
  	if (!sdescmd4) {
  		rc = -ENOMEM;
ac3aa2f8a   Jeff Layton   cifs: remove extr...
147
  		cERROR(1, "%s: Memory allocation failure", __func__);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
148
149
150
151
152
153
154
  		goto mdfour_err;
  	}
  	sdescmd4->shash.tfm = md4;
  	sdescmd4->shash.flags = 0x0;
  
  	rc = crypto_shash_init(&sdescmd4->shash);
  	if (rc) {
ac3aa2f8a   Jeff Layton   cifs: remove extr...
155
  		cERROR(1, "%s: Could not init md4 shash", __func__);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
156
157
  		goto mdfour_err;
  	}
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
158
159
  	rc = crypto_shash_update(&sdescmd4->shash, link_str, link_len);
  	if (rc) {
ac3aa2f8a   Jeff Layton   cifs: remove extr...
160
  		cERROR(1, "%s: Could not update with link_str", __func__);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
161
162
  		goto mdfour_err;
  	}
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
163
  	rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
164
  	if (rc)
ac3aa2f8a   Jeff Layton   cifs: remove extr...
165
  		cERROR(1, "%s: Could not genereate md4 hash", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166

ee2c92585   Shirish Pargaonkar   cifs: More crypto...
167
168
169
170
171
172
  mdfour_err:
  	crypto_free_shash(md4);
  	kfree(sdescmd4);
  
  	return rc;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
  /*
     This implements the X/Open SMB password encryption
790fe579f   Steve French   [CIFS] more white...
175
     It takes a password, a 8 byte "crypt key" and puts 24 bytes of
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
177
     encrypted password into p24 */
  /* Note that password must be uppercased and null terminated */
43988d768   Steve French   [CIFS] Use ecb de...
178
  int
4e53a3fb9   Jeff Layton   cifs: have calc_l...
179
  SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
  {
43988d768   Steve French   [CIFS] Use ecb de...
181
182
  	int rc;
  	unsigned char p14[14], p16[16], p21[21];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
  	memset(p14, '\0', 14);
43988d768   Steve French   [CIFS] Use ecb de...
185
186
  	memset(p16, '\0', 16);
  	memset(p21, '\0', 21);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187

43988d768   Steve French   [CIFS] Use ecb de...
188
189
190
191
  	memcpy(p14, passwd, 14);
  	rc = E_P16(p14, p16);
  	if (rc)
  		return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192

43988d768   Steve French   [CIFS] Use ecb de...
193
194
  	memcpy(p21, p16, 16);
  	rc = E_P24(p21, c8, p24);
50c2f7538   Steve French   [CIFS] whitespace...
195

43988d768   Steve French   [CIFS] Use ecb de...
196
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
  }
790fe579f   Steve French   [CIFS] more white...
198
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
   * Creates the MD4 Hash of the users password in NT UNICODE.
   */
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
201
  int
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
202
203
  E_md4hash(const unsigned char *passwd, unsigned char *p16,
  	const struct nls_table *codepage)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
  {
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
205
  	int rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  	int len;
9c32c63bb   Steve French   cifs: Fix sparse ...
207
  	__le16 wpwd[129];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
209
  
  	/* Password cannot be longer than 128 characters */
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
210
  	if (passwd) /* Password must be converted to NT unicode */
acbbb76a2   Steve French   CIFS: Rename *UCS...
211
  		len = cifs_strtoUTF16(wpwd, passwd, 128, codepage);
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
212
  	else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  		len = 0;
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
214
215
  		*wpwd = 0; /* Ensure string is null terminated */
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216

9c32c63bb   Steve French   cifs: Fix sparse ...
217
218
  	rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16));
  	memset(wpwd, 0, 129 * sizeof(__le16));
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
219
220
  
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  /* Does the NT MD4 hash then des encryption. */
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
223
  int
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
224
225
  SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
  		const struct nls_table *codepage)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
  {
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
227
  	int rc;
43988d768   Steve French   [CIFS] Use ecb de...
228
  	unsigned char p16[16], p21[21];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229

43988d768   Steve French   [CIFS] Use ecb de...
230
  	memset(p16, '\0', 16);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
  	memset(p21, '\0', 21);
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
232
  	rc = E_md4hash(passwd, p16, codepage);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
233
234
235
236
  	if (rc) {
  		cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
  		return rc;
  	}
43988d768   Steve French   [CIFS] Use ecb de...
237
238
  	memcpy(p21, p16, 16);
  	rc = E_P24(p21, c8, p24);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
239
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
  }