Blame view

fs/cifs/smbencrypt.c 5.73 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
     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.
  */
7aa58e7ad   Andy Lutomirski   cifs: Fix smbencr...
25
  #include <linux/crypto.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
  #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
  #include <linux/fs.h>
  #include <linux/string.h>
  #include <linux/kernel.h>
  #include <linux/random.h>
2baa26825   Steve French   Remap reserved po...
32
  #include "cifs_fs_sb.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
  #include "cifs_unicode.h"
  #include "cifspdu.h"
3979877e5   Steve French   [CIFS] Support fo...
35
  #include "cifsglob.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  #include "cifs_debug.h"
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
37
  #include "cifsproto.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38

4b18f2a9c   Steve French   [CIFS] convert us...
39
40
  #ifndef false
  #define false 0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
  #endif
4b18f2a9c   Steve French   [CIFS] convert us...
42
43
  #ifndef true
  #define true 1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
45
46
47
48
49
  #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...
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  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)
  {
43988d768   Steve French   [CIFS] Use ecb de...
70
  	unsigned char key2[8];
7aa58e7ad   Andy Lutomirski   cifs: Fix smbencr...
71
  	struct crypto_cipher *tfm_des;
43988d768   Steve French   [CIFS] Use ecb de...
72
73
  
  	str_to_key(key, key2);
7aa58e7ad   Andy Lutomirski   cifs: Fix smbencr...
74
  	tfm_des = crypto_alloc_cipher("des", 0, 0);
43988d768   Steve French   [CIFS] Use ecb de...
75
  	if (IS_ERR(tfm_des)) {
9651ddbac   Herbert Xu   cifs: Use skcipher
76
77
  		cifs_dbg(VFS, "could not allocate des crypto API
  ");
7aa58e7ad   Andy Lutomirski   cifs: Fix smbencr...
78
  		return PTR_ERR(tfm_des);
9651ddbac   Herbert Xu   cifs: Use skcipher
79
  	}
43988d768   Steve French   [CIFS] Use ecb de...
80

7aa58e7ad   Andy Lutomirski   cifs: Fix smbencr...
81
82
83
  	crypto_cipher_setkey(tfm_des, key2, 8);
  	crypto_cipher_encrypt_one(tfm_des, out, in);
  	crypto_free_cipher(tfm_des);
9651ddbac   Herbert Xu   cifs: Use skcipher
84

7aa58e7ad   Andy Lutomirski   cifs: Fix smbencr...
85
  	return 0;
43988d768   Steve French   [CIFS] Use ecb de...
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  }
  
  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...
116
117
118
119
120
121
122
123
124
125
126
  /* 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...
127
  		rc = PTR_ERR(md4);
f96637be0   Joe Perches   [CIFS] cifs: Rena...
128
129
130
  		cifs_dbg(VFS, "%s: Crypto md4 allocation error %d
  ",
  			 __func__, rc);
ffeb414a5   Jeff Layton   cifs: fix two com...
131
  		return rc;
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
132
133
134
135
136
  	}
  	size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
  	sdescmd4 = kmalloc(size, GFP_KERNEL);
  	if (!sdescmd4) {
  		rc = -ENOMEM;
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
137
138
139
140
141
142
143
  		goto mdfour_err;
  	}
  	sdescmd4->shash.tfm = md4;
  	sdescmd4->shash.flags = 0x0;
  
  	rc = crypto_shash_init(&sdescmd4->shash);
  	if (rc) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
144
145
  		cifs_dbg(VFS, "%s: Could not init md4 shash
  ", __func__);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
146
147
  		goto mdfour_err;
  	}
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
148
149
  	rc = crypto_shash_update(&sdescmd4->shash, link_str, link_len);
  	if (rc) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
150
151
  		cifs_dbg(VFS, "%s: Could not update with link_str
  ", __func__);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
152
153
  		goto mdfour_err;
  	}
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
154
  	rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
155
  	if (rc)
f96637be0   Joe Perches   [CIFS] cifs: Rena...
156
157
  		cifs_dbg(VFS, "%s: Could not generate md4 hash
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158

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

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

43988d768   Steve French   [CIFS] Use ecb de...
180
181
182
183
  	memcpy(p14, passwd, 14);
  	rc = E_P16(p14, p16);
  	if (rc)
  		return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184

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

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

9c32c63bb   Steve French   cifs: Fix sparse ...
209
  	rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16));
f99dbfa4b   Giel van Schijndel   cifs: use memzero...
210
  	memzero_explicit(wpwd, sizeof(wpwd));
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
211
212
  
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
  /* Does the NT MD4 hash then des encryption. */
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
215
  int
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
216
217
  SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
  		const struct nls_table *codepage)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  {
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
219
  	int rc;
43988d768   Steve French   [CIFS] Use ecb de...
220
  	unsigned char p16[16], p21[21];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221

43988d768   Steve French   [CIFS] Use ecb de...
222
  	memset(p16, '\0', 16);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
  	memset(p21, '\0', 21);
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
224
  	rc = E_md4hash(passwd, p16, codepage);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
225
  	if (rc) {
f96637be0   Joe Perches   [CIFS] cifs: Rena...
226
227
228
  		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d
  ",
  			 __func__, rc);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
229
230
  		return rc;
  	}
43988d768   Steve French   [CIFS] Use ecb de...
231
232
  	memcpy(p21, p16, 16);
  	rc = E_P24(p21, c8, p24);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
233
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  }