Blame view

fs/cifs/smbencrypt.c 5.99 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
80
81
82
83
84
85
86
87
88
89
90
91
92
  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);
  		cERROR(1, "could not allocate des crypto API
  ");
  		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...
93
  	if (rc)
43988d768   Steve French   [CIFS] Use ecb de...
94
95
  		cERROR(1, "could not encrypt crypt key rc: %d
  ", rc);
43988d768   Steve French   [CIFS] Use ecb de...
96

e4fb0edb7   Jeff Layton   cifs: free blkcip...
97
  	crypto_free_blkcipher(tfm_des);
43988d768   Steve French   [CIFS] Use ecb de...
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
128
129
  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...
130
131
132
133
134
135
136
137
138
139
140
  /* 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...
141
  		rc = PTR_ERR(md4);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
142
143
  		cERROR(1, "%s: Crypto md4 allocation error %d
  ", __func__, rc);
ffeb414a5   Jeff Layton   cifs: fix two com...
144
  		return rc;
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  	}
  	size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
  	sdescmd4 = kmalloc(size, GFP_KERNEL);
  	if (!sdescmd4) {
  		rc = -ENOMEM;
  		cERROR(1, "%s: Memory allocation failure
  ", __func__);
  		goto mdfour_err;
  	}
  	sdescmd4->shash.tfm = md4;
  	sdescmd4->shash.flags = 0x0;
  
  	rc = crypto_shash_init(&sdescmd4->shash);
  	if (rc) {
  		cERROR(1, "%s: Could not init md4 shash
  ", __func__);
  		goto mdfour_err;
  	}
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
163
164
165
166
167
168
  	rc = crypto_shash_update(&sdescmd4->shash, link_str, link_len);
  	if (rc) {
  		cERROR(1, "%s: Could not update with link_str
  ", __func__);
  		goto mdfour_err;
  	}
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
169
  	rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
170
171
172
  	if (rc)
  		cERROR(1, "%s: Could not genereate md4 hash
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173

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

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

43988d768   Steve French   [CIFS] Use ecb de...
195
196
197
198
  	memcpy(p14, passwd, 14);
  	rc = E_P16(p14, p16);
  	if (rc)
  		return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199

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

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

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

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