Blame view

fs/cifs/cifsencrypt.c 20.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /*
   *   fs/cifs/cifsencrypt.c
   *
12b3b8ffb   Steve French   [CIFS] Cleanup NT...
4
   *   Copyright (C) International Business Machines  Corp., 2005,2006
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   *   Author(s): Steve French (sfrench@us.ibm.com)
   *
   *   This library is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU Lesser General Public License as published
   *   by the Free Software Foundation; either version 2.1 of the License, or
   *   (at your option) any later version.
   *
   *   This library 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 Lesser General Public License for more details.
   *
   *   You should have received a copy of the GNU Lesser General Public License
   *   along with this library; if not, write to the Free Software
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   */
  
  #include <linux/fs.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
23
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
  #include "cifspdu.h"
ffdd6e4d1   Steve French   [CIFS] fix whites...
25
  #include "cifsglob.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
  #include "cifs_debug.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
  #include "cifs_unicode.h"
  #include "cifsproto.h"
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
29
  #include "ntlmssp.h"
7c7b25bc8   Steve French   [CIFS] Support fo...
30
  #include <linux/ctype.h>
6d027cfdb   Steve French   [CIFS] NTLMv2 sup...
31
  #include <linux/random.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32

157c24911   Jeff Layton   cifs: wrap receiv...
33
34
35
36
37
38
39
  /*
   * Calculate and return the CIFS signature based on the mac key and SMB PDU.
   * The 16 byte signature must be allocated by the caller. Note we only use the
   * 1st eight bytes and that the smb header signature field on input contains
   * the sequence number before this function is called. Also, this function
   * should be called with the server->srv_mutex held.
   */
826a95e4a   Jeff Layton   cifs: consolidate...
40
41
  static int cifs_calc_signature(const struct kvec *iov, int n_vec,
  			struct TCP_Server_Info *server, char *signature)
84afc29b1   Steve French   [CIFS] Readpages ...
42
  {
e9917a000   Steve French   [CIFS] Incorrect ...
43
  	int i;
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
44
  	int rc;
84afc29b1   Steve French   [CIFS] Readpages ...
45

21e733930   Shirish Pargaonkar   NTLM auth and sig...
46
  	if (iov == NULL || signature == NULL || server == NULL)
e9917a000   Steve French   [CIFS] Incorrect ...
47
  		return -EINVAL;
84afc29b1   Steve French   [CIFS] Readpages ...
48

307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
49
50
51
52
53
54
55
56
  	if (!server->secmech.sdescmd5) {
  		cERROR(1, "%s: Can't generate signature
  ", __func__);
  		return -1;
  	}
  
  	rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
  	if (rc) {
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
57
58
  		cERROR(1, "%s: Could not init md5
  ", __func__);
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
59
60
  		return rc;
  	}
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
61
  	rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
62
  		server->session_key.response, server->session_key.len);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
63
64
65
66
67
  	if (rc) {
  		cERROR(1, "%s: Could not update with response
  ", __func__);
  		return rc;
  	}
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
68

50c2f7538   Steve French   [CIFS] whitespace...
69
  	for (i = 0; i < n_vec; i++) {
745542e21   Jeff Layton   [CIFS] allow cifs...
70
71
  		if (iov[i].iov_len == 0)
  			continue;
ffdd6e4d1   Steve French   [CIFS] fix whites...
72
  		if (iov[i].iov_base == NULL) {
56234e276   Steve French   Revert "Eliminate...
73
  			cERROR(1, "null iovec entry");
e9917a000   Steve French   [CIFS] Incorrect ...
74
  			return -EIO;
745542e21   Jeff Layton   [CIFS] allow cifs...
75
  		}
ffdd6e4d1   Steve French   [CIFS] fix whites...
76
  		/* The first entry includes a length field (which does not get
e9917a000   Steve French   [CIFS] Incorrect ...
77
  		   signed that occupies the first 4 bytes before the header */
ffdd6e4d1   Steve French   [CIFS] fix whites...
78
  		if (i == 0) {
63d2583f5   Steve French   [CIFS] Fix walkin...
79
  			if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
e9917a000   Steve French   [CIFS] Incorrect ...
80
  				break; /* nothing to sign or corrupt header */
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
81
  			rc =
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
82
83
  			crypto_shash_update(&server->secmech.sdescmd5->shash,
  				iov[i].iov_base + 4, iov[i].iov_len - 4);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
84
85
  		} else {
  			rc =
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
86
87
  			crypto_shash_update(&server->secmech.sdescmd5->shash,
  				iov[i].iov_base, iov[i].iov_len);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
88
89
90
91
92
93
94
  		}
  		if (rc) {
  			cERROR(1, "%s: Could not update with payload
  ",
  							__func__);
  			return rc;
  		}
e9917a000   Steve French   [CIFS] Incorrect ...
95
  	}
84afc29b1   Steve French   [CIFS] Readpages ...
96

307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
97
  	rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
98
99
100
  	if (rc)
  		cERROR(1, "%s: Could not generate md5 hash
  ", __func__);
84afc29b1   Steve French   [CIFS] Readpages ...
101

307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
102
  	return rc;
84afc29b1   Steve French   [CIFS] Readpages ...
103
  }
a0f8b4fb4   Jeff Layton   cifs: remove unne...
104
  /* must be called with server->srv_mutex held */
ffdd6e4d1   Steve French   [CIFS] fix whites...
105
  int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
63d2583f5   Steve French   [CIFS] Fix walkin...
106
  		   __u32 *pexpected_response_sequence_number)
84afc29b1   Steve French   [CIFS] Readpages ...
107
108
109
  {
  	int rc = 0;
  	char smb_signature[20];
826a95e4a   Jeff Layton   cifs: consolidate...
110
  	struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base;
84afc29b1   Steve French   [CIFS] Readpages ...
111

ffdd6e4d1   Steve French   [CIFS] fix whites...
112
  	if ((cifs_pdu == NULL) || (server == NULL))
84afc29b1   Steve French   [CIFS] Readpages ...
113
  		return -EINVAL;
998d6fcb2   Jeff Layton   cifs: don't start...
114
115
  	if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
  	    server->tcpStatus == CifsNeedNegotiate)
84afc29b1   Steve French   [CIFS] Readpages ...
116
  		return rc;
998d6fcb2   Jeff Layton   cifs: don't start...
117
  	if (!server->session_estab) {
b4dacbc28   Jeff Layton   cifs: use memcpy ...
118
  		memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
998d6fcb2   Jeff Layton   cifs: don't start...
119
120
  		return rc;
  	}
ffdd6e4d1   Steve French   [CIFS] fix whites...
121
  	cifs_pdu->Signature.Sequence.SequenceNumber =
84afc29b1   Steve French   [CIFS] Readpages ...
122
  				cpu_to_le32(server->sequence_number);
ffdd6e4d1   Steve French   [CIFS] fix whites...
123
  	cifs_pdu->Signature.Sequence.Reserved = 0;
84afc29b1   Steve French   [CIFS] Readpages ...
124

ffdd6e4d1   Steve French   [CIFS] fix whites...
125
126
  	*pexpected_response_sequence_number = server->sequence_number++;
  	server->sequence_number++;
84afc29b1   Steve French   [CIFS] Readpages ...
127

826a95e4a   Jeff Layton   cifs: consolidate...
128
  	rc = cifs_calc_signature(iov, n_vec, server, smb_signature);
ffdd6e4d1   Steve French   [CIFS] fix whites...
129
130
131
132
  	if (rc)
  		memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
  	else
  		memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
84afc29b1   Steve French   [CIFS] Readpages ...
133

ffdd6e4d1   Steve French   [CIFS] fix whites...
134
  	return rc;
84afc29b1   Steve French   [CIFS] Readpages ...
135
  }
826a95e4a   Jeff Layton   cifs: consolidate...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  /* must be called with server->srv_mutex held */
  int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
  		  __u32 *pexpected_response_sequence_number)
  {
  	struct kvec iov;
  
  	iov.iov_base = cifs_pdu;
  	iov.iov_len = be32_to_cpu(cifs_pdu->smb_buf_length) + 4;
  
  	return cifs_sign_smb2(&iov, 1, server,
  			      pexpected_response_sequence_number);
  }
  
  int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
21e733930   Shirish Pargaonkar   NTLM auth and sig...
150
  			  struct TCP_Server_Info *server,
ffdd6e4d1   Steve French   [CIFS] fix whites...
151
  			  __u32 expected_sequence_number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  {
c8e56f1f4   Steve French   Revert "[CIFS] Fi...
153
  	unsigned int rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
  	char server_response_sig[8];
  	char what_we_think_sig_should_be[20];
826a95e4a   Jeff Layton   cifs: consolidate...
156
  	struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157

21e733930   Shirish Pargaonkar   NTLM auth and sig...
158
  	if (cifs_pdu == NULL || server == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
  		return -EINVAL;
9c4843ea5   Jeff Layton   cifs: silence pri...
160
  	if (!server->session_estab)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
163
  		return 0;
  
  	if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
50c2f7538   Steve French   [CIFS] whitespace...
164
  		struct smb_com_lock_req *pSMB =
ffdd6e4d1   Steve French   [CIFS] fix whites...
165
166
  			(struct smb_com_lock_req *)cifs_pdu;
  	    if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
168
  			return 0;
  	}
50c2f7538   Steve French   [CIFS] whitespace...
169
170
  	/* BB what if signatures are supposed to be on for session but
  	   server does not send one? BB */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
  	/* Do not need to verify session setups with signature "BSRSPYL "  */
50c2f7538   Steve French   [CIFS] whitespace...
172
  	if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
b6b38f704   Joe Perches   [CIFS] Neaten cER...
173
174
  		cFYI(1, "dummy signature received for smb command 0x%x",
  			cifs_pdu->Command);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
176
177
  
  	/* save off the origiginal signature so we can modify the smb and check
  		its signature against what the server sent */
50c2f7538   Steve French   [CIFS] whitespace...
178
  	memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179

50c2f7538   Steve French   [CIFS] whitespace...
180
181
  	cifs_pdu->Signature.Sequence.SequenceNumber =
  					cpu_to_le32(expected_sequence_number);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
  	cifs_pdu->Signature.Sequence.Reserved = 0;
157c24911   Jeff Layton   cifs: wrap receiv...
183
  	mutex_lock(&server->srv_mutex);
826a95e4a   Jeff Layton   cifs: consolidate...
184
185
  	rc = cifs_calc_signature(iov, nr_iov, server,
  				 what_we_think_sig_should_be);
157c24911   Jeff Layton   cifs: wrap receiv...
186
  	mutex_unlock(&server->srv_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187

50c2f7538   Steve French   [CIFS] whitespace...
188
  	if (rc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
  		return rc;
50c2f7538   Steve French   [CIFS] whitespace...
190
191
  /*	cifs_dump_mem("what we think it should be: ",
  		      what_we_think_sig_should_be, 16); */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192

50c2f7538   Steve French   [CIFS] whitespace...
193
  	if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
195
196
197
198
  		return -EACCES;
  	else
  		return 0;
  
  }
21e733930   Shirish Pargaonkar   NTLM auth and sig...
199
  /* first calculate 24 bytes ntlm response and then 16 byte session key */
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
200
  int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
  {
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
202
  	int rc = 0;
21e733930   Shirish Pargaonkar   NTLM auth and sig...
203
204
205
206
  	unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
  	char temp_key[CIFS_SESS_KEY_SIZE];
  
  	if (!ses)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
  		return -EINVAL;
21e733930   Shirish Pargaonkar   NTLM auth and sig...
208
209
210
211
212
213
  	ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
  	if (!ses->auth_key.response) {
  		cERROR(1, "NTLM can't allocate (%u bytes) memory", temp_len);
  		return -ENOMEM;
  	}
  	ses->auth_key.len = temp_len;
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
214
  	rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
215
  			ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
216
217
218
219
220
  	if (rc) {
  		cFYI(1, "%s Can't generate NTLM response, error: %d",
  			__func__, rc);
  		return rc;
  	}
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
221
  	rc = E_md4hash(ses->password, temp_key, nls_cp);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
222
223
224
225
  	if (rc) {
  		cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
  		return rc;
  	}
21e733930   Shirish Pargaonkar   NTLM auth and sig...
226

ee2c92585   Shirish Pargaonkar   cifs: More crypto...
227
228
229
230
  	rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
  	if (rc)
  		cFYI(1, "%s Can't generate NTLM session key, error: %d",
  			__func__, rc);
21e733930   Shirish Pargaonkar   NTLM auth and sig...
231

ee2c92585   Shirish Pargaonkar   cifs: More crypto...
232
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
  }
7c7b25bc8   Steve French   [CIFS] Support fo...
234
  #ifdef CONFIG_CIFS_WEAK_PW_HASH
43988d768   Steve French   [CIFS] Use ecb de...
235
  int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
4e53a3fb9   Jeff Layton   cifs: have calc_l...
236
  			char *lnm_session_key)
7c7b25bc8   Steve French   [CIFS] Support fo...
237
238
  {
  	int i;
43988d768   Steve French   [CIFS] Use ecb de...
239
  	int rc;
7c7b25bc8   Steve French   [CIFS] Support fo...
240
241
242
  	char password_with_pad[CIFS_ENCPWD_SIZE];
  
  	memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
4e53a3fb9   Jeff Layton   cifs: have calc_l...
243
244
  	if (password)
  		strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
04912d6a2   Jeff Layton   cifs: rename "ext...
245
  	if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
4e53a3fb9   Jeff Layton   cifs: have calc_l...
246
247
248
  		memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE);
  		memcpy(lnm_session_key, password_with_pad,
  			CIFS_ENCPWD_SIZE);
43988d768   Steve French   [CIFS] Use ecb de...
249
  		return 0;
4e53a3fb9   Jeff Layton   cifs: have calc_l...
250
  	}
bdc4bf6e8   Steve French   [CIFS] Support fo...
251

7c7b25bc8   Steve French   [CIFS] Support fo...
252
253
254
255
256
257
258
259
260
261
  	/* calculate old style session key */
  	/* calling toupper is less broken than repeatedly
  	calling nls_toupper would be since that will never
  	work for UTF8, but neither handles multibyte code pages
  	but the only alternative would be converting to UCS-16 (Unicode)
  	(using a routine something like UniStrupr) then
  	uppercasing and then converting back from Unicode - which
  	would only worth doing it if we knew it were utf8. Basically
  	utf8 and other multibyte codepages each need their own strupper
  	function since a byte at a time will ont work. */
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
262
  	for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
7c7b25bc8   Steve French   [CIFS] Support fo...
263
  		password_with_pad[i] = toupper(password_with_pad[i]);
7c7b25bc8   Steve French   [CIFS] Support fo...
264

43988d768   Steve French   [CIFS] Use ecb de...
265
  	rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
4e53a3fb9   Jeff Layton   cifs: have calc_l...
266

43988d768   Steve French   [CIFS] Use ecb de...
267
  	return rc;
7c7b25bc8   Steve French   [CIFS] Support fo...
268
269
  }
  #endif /* CIFS_WEAK_PW_HASH */
9daa42e22   Shirish Pargaonkar   CIFS ntlm authent...
270
271
272
273
  /* Build a proper attribute value/target info pairs blob.
   * Fill in netbios and dns domain name and workstation name
   * and client time (total five av pairs and + one end of fields indicator.
   * Allocate domain name which gets freed when session struct is deallocated.
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
274
275
   */
  static int
96daf2b09   Steve French   [CIFS] Rename thr...
276
  build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
277
  {
9daa42e22   Shirish Pargaonkar   CIFS ntlm authent...
278
  	unsigned int dlen;
cfbd6f84c   Shirish Pargaonkar   cifs: Fix broken ...
279
  	unsigned int size = 2 * sizeof(struct ntlmssp2_name);
9daa42e22   Shirish Pargaonkar   CIFS ntlm authent...
280
281
  	char *defdmname = "WORKGROUP";
  	unsigned char *blobptr;
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
282
  	struct ntlmssp2_name *attrptr;
9daa42e22   Shirish Pargaonkar   CIFS ntlm authent...
283
284
285
286
287
288
289
  	if (!ses->domainName) {
  		ses->domainName = kstrdup(defdmname, GFP_KERNEL);
  		if (!ses->domainName)
  			return -ENOMEM;
  	}
  
  	dlen = strlen(ses->domainName);
9daa42e22   Shirish Pargaonkar   CIFS ntlm authent...
290

cfbd6f84c   Shirish Pargaonkar   cifs: Fix broken ...
291
292
293
294
295
  	/*
  	 * The length of this blob is two times the size of a
  	 * structure (av pair) which holds name/size
  	 * ( for NTLMSSP_AV_NB_DOMAIN_NAME followed by NTLMSSP_AV_EOL ) +
  	 * unicode length of a netbios domain name
9daa42e22   Shirish Pargaonkar   CIFS ntlm authent...
296
  	 */
cfbd6f84c   Shirish Pargaonkar   cifs: Fix broken ...
297
  	ses->auth_key.len = size + 2 * dlen;
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
298
299
300
  	ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
  	if (!ses->auth_key.response) {
  		ses->auth_key.len = 0;
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
301
302
303
  		cERROR(1, "Challenge target info allocation failure");
  		return -ENOMEM;
  	}
9daa42e22   Shirish Pargaonkar   CIFS ntlm authent...
304

d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
305
  	blobptr = ses->auth_key.response;
9daa42e22   Shirish Pargaonkar   CIFS ntlm authent...
306
  	attrptr = (struct ntlmssp2_name *) blobptr;
cfbd6f84c   Shirish Pargaonkar   cifs: Fix broken ...
307
308
309
310
  	/*
  	 * As defined in MS-NTLM 3.3.2, just this av pair field
  	 * is sufficient as part of the temp
  	 */
9daa42e22   Shirish Pargaonkar   CIFS ntlm authent...
311
312
313
314
  	attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
  	attrptr->length = cpu_to_le16(2 * dlen);
  	blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
  	cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
315
316
317
318
319
320
321
322
323
324
325
326
327
328
  	return 0;
  }
  
  /* Server has provided av pairs/target info in the type 2 challenge
   * packet and we have plucked it and stored within smb session.
   * We parse that blob here to find netbios domain name to be used
   * as part of ntlmv2 authentication (in Target String), if not already
   * specified on the command line.
   * If this function returns without any error but without fetching
   * domain name, authentication may fail against some server but
   * may not fail against other (those who are not very particular
   * about target string i.e. for some, just user name might suffice.
   */
  static int
96daf2b09   Steve French   [CIFS] Rename thr...
329
  find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
330
331
332
333
334
335
336
  {
  	unsigned int attrsize;
  	unsigned int type;
  	unsigned int onesize = sizeof(struct ntlmssp2_name);
  	unsigned char *blobptr;
  	unsigned char *blobend;
  	struct ntlmssp2_name *attrptr;
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
337
  	if (!ses->auth_key.len || !ses->auth_key.response)
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
338
  		return 0;
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
339
340
  	blobptr = ses->auth_key.response;
  	blobend = blobptr + ses->auth_key.len;
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  
  	while (blobptr + onesize < blobend) {
  		attrptr = (struct ntlmssp2_name *) blobptr;
  		type = le16_to_cpu(attrptr->type);
  		if (type == NTLMSSP_AV_EOL)
  			break;
  		blobptr += 2; /* advance attr type */
  		attrsize = le16_to_cpu(attrptr->length);
  		blobptr += 2; /* advance attr size */
  		if (blobptr + attrsize > blobend)
  			break;
  		if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
  			if (!attrsize)
  				break;
  			if (!ses->domainName) {
  				ses->domainName =
  					kmalloc(attrsize + 1, GFP_KERNEL);
  				if (!ses->domainName)
  						return -ENOMEM;
  				cifs_from_ucs2(ses->domainName,
  					(__le16 *)blobptr, attrsize, attrsize,
f7c5445a9   Shirish Pargaonkar   NTLM auth and sig...
362
  					nls_cp, false);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
363
364
365
366
367
368
369
370
  				break;
  			}
  		}
  		blobptr += attrsize; /* advance attr  value */
  	}
  
  	return 0;
  }
96daf2b09   Steve French   [CIFS] Rename thr...
371
  static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
50c2f7538   Steve French   [CIFS] whitespace...
372
  			    const struct nls_table *nls_cp)
a8ee03441   Steve French   [CIFS] NTLMv2 sup...
373
374
375
  {
  	int rc = 0;
  	int len;
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
376
  	char nt_hash[CIFS_NTHASH_SIZE];
50c2f7538   Steve French   [CIFS] whitespace...
377
378
  	wchar_t *user;
  	wchar_t *domain;
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
379
  	wchar_t *server;
a8ee03441   Steve French   [CIFS] NTLMv2 sup...
380

307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
381
382
383
384
385
  	if (!ses->server->secmech.sdeschmacmd5) {
  		cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash
  ");
  		return -1;
  	}
56234e276   Steve French   Revert "Eliminate...
386

c8e56f1f4   Steve French   Revert "[CIFS] Fi...
387
  	/* calculate md4 hash of password */
9ef5992e4   Shirish Pargaonkar   cifs: Assume pass...
388
  	E_md4hash(ses->password, nt_hash, nls_cp);
9fbc59086   Steve French   [CIFS] Fix ntlmv2...
389

14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
390
  	rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
391
  				CIFS_NTHASH_SIZE);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
392
393
394
395
  	if (rc) {
  		cERROR(1, "%s: Could not set NT Hash as a key", __func__);
  		return rc;
  	}
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
396
397
398
399
400
401
402
  
  	rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
  	if (rc) {
  		cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5
  ");
  		return rc;
  	}
a8ee03441   Steve French   [CIFS] NTLMv2 sup...
403

8727c8a85   Steve French   Allow user names ...
404
405
  	/* convert ses->user_name to unicode and uppercase */
  	len = strlen(ses->user_name);
1717ffc58   Steve French   [CIFS] NTLMv2 sup...
406
  	user = kmalloc(2 + (len * 2), GFP_KERNEL);
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
407
408
409
410
  	if (user == NULL) {
  		cERROR(1, "calc_ntlmv2_hash: user mem alloc failure
  ");
  		rc = -ENOMEM;
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
411
  		return rc;
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
412
  	}
8727c8a85   Steve French   Allow user names ...
413
  	len = cifs_strtoUCS((__le16 *)user, ses->user_name, len, nls_cp);
1717ffc58   Steve French   [CIFS] NTLMv2 sup...
414
  	UniStrupr(user);
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
415

14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
416
  	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
417
  				(char *)user, 2 * len);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
418
419
420
421
422
423
  	kfree(user);
  	if (rc) {
  		cERROR(1, "%s: Could not update with user
  ", __func__);
  		return rc;
  	}
a8ee03441   Steve French   [CIFS] NTLMv2 sup...
424
425
  
  	/* convert ses->domainName to unicode and uppercase */
50c2f7538   Steve French   [CIFS] whitespace...
426
  	if (ses->domainName) {
1717ffc58   Steve French   [CIFS] NTLMv2 sup...
427
  		len = strlen(ses->domainName);
a8ee03441   Steve French   [CIFS] NTLMv2 sup...
428

50c2f7538   Steve French   [CIFS] whitespace...
429
  		domain = kmalloc(2 + (len * 2), GFP_KERNEL);
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
430
431
432
  		if (domain == NULL) {
  			cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure");
  			rc = -ENOMEM;
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
433
  			return rc;
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
434
  		}
8f2376adf   Cyril Gorcunov   [CIFS] Fix endian...
435
436
  		len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
  					nls_cp);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
437
  		rc =
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
438
439
  		crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
  					(char *)domain, 2 * len);
1717ffc58   Steve French   [CIFS] NTLMv2 sup...
440
  		kfree(domain);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
441
442
443
444
445
446
  		if (rc) {
  			cERROR(1, "%s: Could not update with domain
  ",
  								__func__);
  			return rc;
  		}
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
447
448
449
450
451
452
453
  	} else if (ses->serverName) {
  		len = strlen(ses->serverName);
  
  		server = kmalloc(2 + (len * 2), GFP_KERNEL);
  		if (server == NULL) {
  			cERROR(1, "calc_ntlmv2_hash: server mem alloc failure");
  			rc = -ENOMEM;
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
454
  			return rc;
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
455
456
457
  		}
  		len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
  					nls_cp);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
458
  		rc =
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
459
460
461
  		crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
  					(char *)server, 2 * len);
  		kfree(server);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
462
463
464
465
466
467
  		if (rc) {
  			cERROR(1, "%s: Could not update with server
  ",
  								__func__);
  			return rc;
  		}
1717ffc58   Steve French   [CIFS] NTLMv2 sup...
468
  	}
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
469
470
  
  	rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
471
  					ntlmv2_hash);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
472
473
474
  	if (rc)
  		cERROR(1, "%s: Could not generate md5 hash
  ", __func__);
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
475

307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
476
477
478
479
  	return rc;
  }
  
  static int
96daf2b09   Steve French   [CIFS] Rename thr...
480
  CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
481
482
483
484
485
486
487
488
489
  {
  	int rc;
  	unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
  
  	if (!ses->server->secmech.sdeschmacmd5) {
  		cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash
  ");
  		return -1;
  	}
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
490
  	rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
491
  				ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
492
493
494
495
  	if (rc) {
  		cERROR(1, "%s: Could not set NTLMV2 Hash as a key", __func__);
  		return rc;
  	}
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
496
497
498
499
500
501
  
  	rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
  	if (rc) {
  		cERROR(1, "CalcNTLMv2_response: could not init hmacmd5");
  		return rc;
  	}
d3ba50b17   Shirish Pargaonkar   NTLM auth and sig...
502
503
  	if (ses->server->secType == RawNTLMSSP)
  		memcpy(ses->auth_key.response + offset,
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
504
  			ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
d3ba50b17   Shirish Pargaonkar   NTLM auth and sig...
505
506
507
  	else
  		memcpy(ses->auth_key.response + offset,
  			ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
508
  	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
509
  		ses->auth_key.response + offset, ses->auth_key.len - offset);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
510
511
512
513
514
  	if (rc) {
  		cERROR(1, "%s: Could not update with response
  ", __func__);
  		return rc;
  	}
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
515
516
517
  
  	rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
  		ses->auth_key.response + CIFS_SESS_KEY_SIZE);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
518
519
520
  	if (rc)
  		cERROR(1, "%s: Could not generate md5 hash
  ", __func__);
9fbc59086   Steve French   [CIFS] Fix ntlmv2...
521
522
523
  
  	return rc;
  }
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
524

2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
525
  int
96daf2b09   Steve French   [CIFS] Rename thr...
526
  setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
9fbc59086   Steve French   [CIFS] Fix ntlmv2...
527
  {
c8e56f1f4   Steve French   Revert "[CIFS] Fi...
528
  	int rc;
21e733930   Shirish Pargaonkar   NTLM auth and sig...
529
  	int baselen;
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
530
  	unsigned int tilen;
21e733930   Shirish Pargaonkar   NTLM auth and sig...
531
  	struct ntlmv2_resp *buf;
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
532
533
  	char ntlmv2_hash[16];
  	unsigned char *tiblob = NULL; /* target info blob */
6d027cfdb   Steve French   [CIFS] NTLMv2 sup...
534

2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
535
536
  	if (ses->server->secType == RawNTLMSSP) {
  		if (!ses->domainName) {
f7c5445a9   Shirish Pargaonkar   NTLM auth and sig...
537
  			rc = find_domain_name(ses, nls_cp);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
538
539
540
541
542
543
  			if (rc) {
  				cERROR(1, "error %d finding domain name", rc);
  				goto setup_ntlmv2_rsp_ret;
  			}
  		}
  	} else {
9daa42e22   Shirish Pargaonkar   CIFS ntlm authent...
544
  		rc = build_avpair_blob(ses, nls_cp);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
545
546
  		if (rc) {
  			cERROR(1, "error %d building av pair blob", rc);
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
547
  			goto setup_ntlmv2_rsp_ret;
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
548
549
  		}
  	}
a8ee03441   Steve French   [CIFS] NTLMv2 sup...
550

21e733930   Shirish Pargaonkar   NTLM auth and sig...
551
  	baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
552
553
554
555
  	tilen = ses->auth_key.len;
  	tiblob = ses->auth_key.response;
  
  	ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
21e733930   Shirish Pargaonkar   NTLM auth and sig...
556
557
  	if (!ses->auth_key.response) {
  		rc = ENOMEM;
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
558
  		ses->auth_key.len = 0;
21e733930   Shirish Pargaonkar   NTLM auth and sig...
559
560
561
  		cERROR(1, "%s: Can't allocate auth blob", __func__);
  		goto setup_ntlmv2_rsp_ret;
  	}
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
562
  	ses->auth_key.len += baselen;
21e733930   Shirish Pargaonkar   NTLM auth and sig...
563
564
565
566
567
568
569
570
  
  	buf = (struct ntlmv2_resp *)
  			(ses->auth_key.response + CIFS_SESS_KEY_SIZE);
  	buf->blob_signature = cpu_to_le32(0x00000101);
  	buf->reserved = 0;
  	buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
  	get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
  	buf->reserved2 = 0;
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
571
  	memcpy(ses->auth_key.response + baselen, tiblob, tilen);
21e733930   Shirish Pargaonkar   NTLM auth and sig...
572

f7c5445a9   Shirish Pargaonkar   NTLM auth and sig...
573
  	/* calculate ntlmv2_hash */
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
574
  	rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
575
  	if (rc) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
576
  		cERROR(1, "could not get v2 hash rc %d", rc);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
577
578
  		goto setup_ntlmv2_rsp_ret;
  	}
f7c5445a9   Shirish Pargaonkar   NTLM auth and sig...
579
580
  
  	/* calculate first part of the client response (CR1) */
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
581
  	rc = CalcNTLMv2_response(ses, ntlmv2_hash);
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
582
583
584
585
  	if (rc) {
  		cERROR(1, "Could not calculate CR1  rc: %d", rc);
  		goto setup_ntlmv2_rsp_ret;
  	}
b609f06ac   Steve French   [CIFS] Fix packet...
586

5d0d28824   Shirish Pargaonkar   NTLM authenticati...
587
  	/* now calculate the session key for NTLMv2 */
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
588
  	rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
589
  		ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
590
591
592
593
  	if (rc) {
  		cERROR(1, "%s: Could not set NTLMV2 Hash as a key", __func__);
  		goto setup_ntlmv2_rsp_ret;
  	}
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
594
595
596
597
598
599
600
  
  	rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
  	if (rc) {
  		cERROR(1, "%s: Could not init hmacmd5
  ", __func__);
  		goto setup_ntlmv2_rsp_ret;
  	}
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
601
  	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
602
603
  		ses->auth_key.response + CIFS_SESS_KEY_SIZE,
  		CIFS_HMAC_MD5_HASH_SIZE);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
604
605
606
607
608
  	if (rc) {
  		cERROR(1, "%s: Could not update with response
  ", __func__);
  		goto setup_ntlmv2_rsp_ret;
  	}
307fbd31b   Shirish Pargaonkar   NTLM auth and sig...
609
610
611
  
  	rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
  		ses->auth_key.response);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
612
613
614
  	if (rc)
  		cERROR(1, "%s: Could not generate md5 hash
  ", __func__);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
615

2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
616
  setup_ntlmv2_rsp_ret:
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
617
  	kfree(tiblob);
2b149f119   Shirish Pargaonkar   cifs NTLMv2/NTLMS...
618
619
  
  	return rc;
6d027cfdb   Steve French   [CIFS] NTLMv2 sup...
620
  }
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
621
  int
96daf2b09   Steve French   [CIFS] Rename thr...
622
  calc_seckey(struct cifs_ses *ses)
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
623
624
625
626
627
628
629
630
631
632
  {
  	int rc;
  	struct crypto_blkcipher *tfm_arc4;
  	struct scatterlist sgin, sgout;
  	struct blkcipher_desc desc;
  	unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */
  
  	get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);
  
  	tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
7a8587e7c   Shirish Pargaonkar   cifs: No need to ...
633
634
  	if (IS_ERR(tfm_arc4)) {
  		rc = PTR_ERR(tfm_arc4);
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
635
636
  		cERROR(1, "could not allocate crypto API arc4
  ");
7a8587e7c   Shirish Pargaonkar   cifs: No need to ...
637
  		return rc;
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
638
639
640
  	}
  
  	desc.tfm = tfm_arc4;
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
641
  	rc = crypto_blkcipher_setkey(tfm_arc4, ses->auth_key.response,
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
642
  					CIFS_SESS_KEY_SIZE);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
643
644
645
646
  	if (rc) {
  		cERROR(1, "%s: Could not set response as a key", __func__);
  		return rc;
  	}
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
647
648
  
  	sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE);
d3686d54c   Shirish Pargaonkar   cifs: Cleanup and...
649
  	sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
  
  	rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE);
  	if (rc) {
  		cERROR(1, "could not encrypt session key rc: %d
  ", rc);
  		crypto_free_blkcipher(tfm_arc4);
  		return rc;
  	}
  
  	/* make secondary_key/nonce as session key */
  	memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE);
  	/* and make len as that of session key only */
  	ses->auth_key.len = CIFS_SESS_KEY_SIZE;
  
  	crypto_free_blkcipher(tfm_arc4);
14cae3243   Shirish Pargaonkar   cifs: Cleanup: ch...
665
  	return rc;
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
  }
  
  void
  cifs_crypto_shash_release(struct TCP_Server_Info *server)
  {
  	if (server->secmech.md5)
  		crypto_free_shash(server->secmech.md5);
  
  	if (server->secmech.hmacmd5)
  		crypto_free_shash(server->secmech.hmacmd5);
  
  	kfree(server->secmech.sdeschmacmd5);
  
  	kfree(server->secmech.sdescmd5);
  }
  
  int
  cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
  {
  	int rc;
  	unsigned int size;
  
  	server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
689
  	if (IS_ERR(server->secmech.hmacmd5)) {
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
690
691
692
693
694
695
  		cERROR(1, "could not allocate crypto hmacmd5
  ");
  		return PTR_ERR(server->secmech.hmacmd5);
  	}
  
  	server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
ee2c92585   Shirish Pargaonkar   cifs: More crypto...
696
  	if (IS_ERR(server->secmech.md5)) {
d2b915210   Shirish Pargaonkar   NTLM auth and sig...
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
  		cERROR(1, "could not allocate crypto md5
  ");
  		rc = PTR_ERR(server->secmech.md5);
  		goto crypto_allocate_md5_fail;
  	}
  
  	size = sizeof(struct shash_desc) +
  			crypto_shash_descsize(server->secmech.hmacmd5);
  	server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
  	if (!server->secmech.sdeschmacmd5) {
  		cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5
  ");
  		rc = -ENOMEM;
  		goto crypto_allocate_hmacmd5_sdesc_fail;
  	}
  	server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
  	server->secmech.sdeschmacmd5->shash.flags = 0x0;
  
  
  	size = sizeof(struct shash_desc) +
  			crypto_shash_descsize(server->secmech.md5);
  	server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
  	if (!server->secmech.sdescmd5) {
  		cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5
  ");
  		rc = -ENOMEM;
  		goto crypto_allocate_md5_sdesc_fail;
  	}
  	server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
  	server->secmech.sdescmd5->shash.flags = 0x0;
  
  	return 0;
  
  crypto_allocate_md5_sdesc_fail:
  	kfree(server->secmech.sdeschmacmd5);
  
  crypto_allocate_hmacmd5_sdesc_fail:
  	crypto_free_shash(server->secmech.md5);
  
  crypto_allocate_md5_fail:
  	crypto_free_shash(server->secmech.hmacmd5);
  
  	return rc;
  }