aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2010-09-08 17:10:58 -0400
committerSteve French <sfrench@us.ibm.com>2010-09-08 17:10:58 -0400
commitc8e56f1f4fb9f82f63e4ce6d73a14501d0432c76 (patch)
tree6d0988317a6eaf4b454c73a1dd95f89184f5b1ed
parent745e507a9c79c6e1385d3414d5e56f3d4621a375 (diff)
Revert "[CIFS] Fix ntlmv2 auth with ntlmssp"
This reverts commit 9fbc590860e75785bdaf8b83e48fabfe4d4f7d58. The change to kernel crypto and fixes to ntlvm2 and ntlmssp series, introduced a regression. Deferring this patch series to 2.6.37 after Shirish fixes it. Signed-off-by: Steve French <sfrench@us.ibm.com> Acked-by: Jeff Layton <jlayton@redhat.com> CC: Shirish Pargaonkar <shirishp@us.ibm.com>
-rw-r--r--fs/cifs/Kconfig2
-rw-r--r--fs/cifs/asn1.c6
-rw-r--r--fs/cifs/cifsencrypt.c416
-rw-r--r--fs/cifs/cifsglob.h18
-rw-r--r--fs/cifs/cifspdu.h7
-rw-r--r--fs/cifs/cifsproto.h12
-rw-r--r--fs/cifs/cifssmb.c13
-rw-r--r--fs/cifs/connect.c13
-rw-r--r--fs/cifs/ntlmssp.h13
-rw-r--r--fs/cifs/sess.c118
-rw-r--r--fs/cifs/transport.c6
11 files changed, 172 insertions, 452 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 0da1debd499..917b7d449bb 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -2,8 +2,6 @@ config CIFS
2 tristate "CIFS support (advanced network filesystem, SMBFS successor)" 2 tristate "CIFS support (advanced network filesystem, SMBFS successor)"
3 depends on INET 3 depends on INET
4 select NLS 4 select NLS
5 select CRYPTO_MD5
6 select CRYPTO_ARC4
7 help 5 help
8 This is the client VFS module for the Common Internet File System 6 This is the client VFS module for the Common Internet File System
9 (CIFS) protocol which is the successor to the Server Message Block 7 (CIFS) protocol which is the successor to the Server Message Block
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index 21f0fbd8698..cfd1ce34e0b 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -597,13 +597,13 @@ decode_negTokenInit(unsigned char *security_blob, int length,
597 if (compare_oid(oid, oidlen, MSKRB5_OID, 597 if (compare_oid(oid, oidlen, MSKRB5_OID,
598 MSKRB5_OID_LEN)) 598 MSKRB5_OID_LEN))
599 server->sec_mskerberos = true; 599 server->sec_mskerberos = true;
600 if (compare_oid(oid, oidlen, KRB5U2U_OID, 600 else if (compare_oid(oid, oidlen, KRB5U2U_OID,
601 KRB5U2U_OID_LEN)) 601 KRB5U2U_OID_LEN))
602 server->sec_kerberosu2u = true; 602 server->sec_kerberosu2u = true;
603 if (compare_oid(oid, oidlen, KRB5_OID, 603 else if (compare_oid(oid, oidlen, KRB5_OID,
604 KRB5_OID_LEN)) 604 KRB5_OID_LEN))
605 server->sec_kerberos = true; 605 server->sec_kerberos = true;
606 if (compare_oid(oid, oidlen, NTLMSSP_OID, 606 else if (compare_oid(oid, oidlen, NTLMSSP_OID,
607 NTLMSSP_OID_LEN)) 607 NTLMSSP_OID_LEN))
608 server->sec_ntlmssp = true; 608 server->sec_ntlmssp = true;
609 609
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 051d00011ca..847628dfdc4 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -27,7 +27,6 @@
27#include "md5.h" 27#include "md5.h"
28#include "cifs_unicode.h" 28#include "cifs_unicode.h"
29#include "cifsproto.h" 29#include "cifsproto.h"
30#include "ntlmssp.h"
31#include <linux/ctype.h> 30#include <linux/ctype.h>
32#include <linux/random.h> 31#include <linux/random.h>
33 32
@@ -43,44 +42,21 @@ extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
43 unsigned char *p24); 42 unsigned char *p24);
44 43
45static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 44static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
46 struct TCP_Server_Info *server, char *signature) 45 const struct mac_key *key, char *signature)
47{ 46{
48 int rc = 0; 47 struct MD5Context context;
49 struct {
50 struct shash_desc shash;
51 char ctx[crypto_shash_descsize(server->ntlmssp.md5)];
52 } sdesc;
53 48
54 if (cifs_pdu == NULL || server == NULL || signature == NULL) 49 if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL))
55 return -EINVAL; 50 return -EINVAL;
56 51
57 sdesc.shash.tfm = server->ntlmssp.md5; 52 cifs_MD5_init(&context);
58 sdesc.shash.flags = 0x0; 53 cifs_MD5_update(&context, (char *)&key->data, key->len);
59 54 cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
60 rc = crypto_shash_init(&sdesc.shash);
61 if (rc) {
62 cERROR(1, "could not initialize master crypto API hmacmd5\n");
63 return rc;
64 }
65
66 if (server->secType == RawNTLMSSP)
67 crypto_shash_update(&sdesc.shash,
68 server->session_key.data.ntlmv2.key,
69 CIFS_NTLMV2_SESSKEY_SIZE);
70 else
71 crypto_shash_update(&sdesc.shash,
72 (char *)&server->session_key.data,
73 server->session_key.len);
74
75 crypto_shash_update(&sdesc.shash,
76 cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
77
78 rc = crypto_shash_final(&sdesc.shash, signature);
79 55
56 cifs_MD5_final(signature, &context);
80 return 0; 57 return 0;
81} 58}
82 59
83
84int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, 60int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
85 __u32 *pexpected_response_sequence_number) 61 __u32 *pexpected_response_sequence_number)
86{ 62{
@@ -102,7 +78,8 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
102 server->sequence_number++; 78 server->sequence_number++;
103 spin_unlock(&GlobalMid_Lock); 79 spin_unlock(&GlobalMid_Lock);
104 80
105 rc = cifs_calculate_signature(cifs_pdu, server, smb_signature); 81 rc = cifs_calculate_signature(cifs_pdu, &server->mac_signing_key,
82 smb_signature);
106 if (rc) 83 if (rc)
107 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 84 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
108 else 85 else
@@ -112,36 +89,16 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
112} 89}
113 90
114static int cifs_calc_signature2(const struct kvec *iov, int n_vec, 91static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
115 struct TCP_Server_Info *server, char *signature) 92 const struct mac_key *key, char *signature)
116{ 93{
94 struct MD5Context context;
117 int i; 95 int i;
118 int rc = 0;
119 struct {
120 struct shash_desc shash;
121 char ctx[crypto_shash_descsize(server->ntlmssp.md5)];
122 } sdesc;
123 96
124 if (iov == NULL || server == NULL || signature == NULL) 97 if ((iov == NULL) || (signature == NULL) || (key == NULL))
125 return -EINVAL; 98 return -EINVAL;
126 99
127 sdesc.shash.tfm = server->ntlmssp.md5; 100 cifs_MD5_init(&context);
128 sdesc.shash.flags = 0x0; 101 cifs_MD5_update(&context, (char *)&key->data, key->len);
129
130 rc = crypto_shash_init(&sdesc.shash);
131 if (rc) {
132 cERROR(1, "could not initialize master crypto API hmacmd5\n");
133 return rc;
134 }
135
136 if (server->secType == RawNTLMSSP)
137 crypto_shash_update(&sdesc.shash,
138 server->session_key.data.ntlmv2.key,
139 CIFS_NTLMV2_SESSKEY_SIZE);
140 else
141 crypto_shash_update(&sdesc.shash,
142 (char *)&server->session_key.data,
143 server->session_key.len);
144
145 for (i = 0; i < n_vec; i++) { 102 for (i = 0; i < n_vec; i++) {
146 if (iov[i].iov_len == 0) 103 if (iov[i].iov_len == 0)
147 continue; 104 continue;
@@ -154,18 +111,18 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
154 if (i == 0) { 111 if (i == 0) {
155 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 112 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
156 break; /* nothing to sign or corrupt header */ 113 break; /* nothing to sign or corrupt header */
157 crypto_shash_update(&sdesc.shash, 114 cifs_MD5_update(&context, iov[0].iov_base+4,
158 iov[i].iov_base + 4, iov[i].iov_len - 4); 115 iov[0].iov_len-4);
159 } else 116 } else
160 crypto_shash_update(&sdesc.shash, 117 cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len);
161 iov[i].iov_base, iov[i].iov_len);
162 } 118 }
163 119
164 rc = crypto_shash_final(&sdesc.shash, signature); 120 cifs_MD5_final(signature, &context);
165 121
166 return 0; 122 return 0;
167} 123}
168 124
125
169int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 126int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
170 __u32 *pexpected_response_sequence_number) 127 __u32 *pexpected_response_sequence_number)
171{ 128{
@@ -188,7 +145,8 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
188 server->sequence_number++; 145 server->sequence_number++;
189 spin_unlock(&GlobalMid_Lock); 146 spin_unlock(&GlobalMid_Lock);
190 147
191 rc = cifs_calc_signature2(iov, n_vec, server, smb_signature); 148 rc = cifs_calc_signature2(iov, n_vec, &server->mac_signing_key,
149 smb_signature);
192 if (rc) 150 if (rc)
193 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 151 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
194 else 152 else
@@ -198,14 +156,14 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
198} 156}
199 157
200int cifs_verify_signature(struct smb_hdr *cifs_pdu, 158int cifs_verify_signature(struct smb_hdr *cifs_pdu,
201 struct TCP_Server_Info *server, 159 const struct mac_key *mac_key,
202 __u32 expected_sequence_number) 160 __u32 expected_sequence_number)
203{ 161{
204 int rc; 162 unsigned int rc;
205 char server_response_sig[8]; 163 char server_response_sig[8];
206 char what_we_think_sig_should_be[20]; 164 char what_we_think_sig_should_be[20];
207 165
208 if (cifs_pdu == NULL || server == NULL) 166 if ((cifs_pdu == NULL) || (mac_key == NULL))
209 return -EINVAL; 167 return -EINVAL;
210 168
211 if (cifs_pdu->Command == SMB_COM_NEGOTIATE) 169 if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
@@ -234,7 +192,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
234 cpu_to_le32(expected_sequence_number); 192 cpu_to_le32(expected_sequence_number);
235 cifs_pdu->Signature.Sequence.Reserved = 0; 193 cifs_pdu->Signature.Sequence.Reserved = 0;
236 194
237 rc = cifs_calculate_signature(cifs_pdu, server, 195 rc = cifs_calculate_signature(cifs_pdu, mac_key,
238 what_we_think_sig_should_be); 196 what_we_think_sig_should_be);
239 197
240 if (rc) 198 if (rc)
@@ -251,7 +209,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
251} 209}
252 210
253/* We fill in key by putting in 40 byte array which was allocated by caller */ 211/* We fill in key by putting in 40 byte array which was allocated by caller */
254int cifs_calculate_session_key(struct session_key *key, const char *rn, 212int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
255 const char *password) 213 const char *password)
256{ 214{
257 char temp_key[16]; 215 char temp_key[16];
@@ -265,6 +223,63 @@ int cifs_calculate_session_key(struct session_key *key, const char *rn,
265 return 0; 223 return 0;
266} 224}
267 225
226int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *ses,
227 const struct nls_table *nls_info)
228{
229 char temp_hash[16];
230 struct HMACMD5Context ctx;
231 char *ucase_buf;
232 __le16 *unicode_buf;
233 unsigned int i, user_name_len, dom_name_len;
234
235 if (ses == NULL)
236 return -EINVAL;
237
238 E_md4hash(ses->password, temp_hash);
239
240 hmac_md5_init_limK_to_64(temp_hash, 16, &ctx);
241 user_name_len = strlen(ses->userName);
242 if (user_name_len > MAX_USERNAME_SIZE)
243 return -EINVAL;
244 if (ses->domainName == NULL)
245 return -EINVAL; /* BB should we use CIFS_LINUX_DOM */
246 dom_name_len = strlen(ses->domainName);
247 if (dom_name_len > MAX_USERNAME_SIZE)
248 return -EINVAL;
249
250 ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL);
251 if (ucase_buf == NULL)
252 return -ENOMEM;
253 unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL);
254 if (unicode_buf == NULL) {
255 kfree(ucase_buf);
256 return -ENOMEM;
257 }
258
259 for (i = 0; i < user_name_len; i++)
260 ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]];
261 ucase_buf[i] = 0;
262 user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf,
263 MAX_USERNAME_SIZE*2, nls_info);
264 unicode_buf[user_name_len] = 0;
265 user_name_len++;
266
267 for (i = 0; i < dom_name_len; i++)
268 ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]];
269 ucase_buf[i] = 0;
270 dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf,
271 MAX_USERNAME_SIZE*2, nls_info);
272
273 unicode_buf[user_name_len + dom_name_len] = 0;
274 hmac_md5_update((const unsigned char *) unicode_buf,
275 (user_name_len+dom_name_len)*2, &ctx);
276
277 hmac_md5_final(ses->server->ntlmv2_hash, &ctx);
278 kfree(ucase_buf);
279 kfree(unicode_buf);
280 return 0;
281}
282
268#ifdef CONFIG_CIFS_WEAK_PW_HASH 283#ifdef CONFIG_CIFS_WEAK_PW_HASH
269void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, 284void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
270 char *lnm_session_key) 285 char *lnm_session_key)
@@ -309,29 +324,21 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
309{ 324{
310 int rc = 0; 325 int rc = 0;
311 int len; 326 int len;
312 char nt_hash[CIFS_NTHASH_SIZE]; 327 char nt_hash[16];
328 struct HMACMD5Context *pctxt;
313 wchar_t *user; 329 wchar_t *user;
314 wchar_t *domain; 330 wchar_t *domain;
315 wchar_t *server;
316 struct {
317 struct shash_desc shash;
318 char ctx[crypto_shash_descsize(ses->server->ntlmssp.hmacmd5)];
319 } sdesc;
320 331
321 /* calculate md4 hash of password */ 332 pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL);
322 E_md4hash(ses->password, nt_hash);
323 333
324 sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5; 334 if (pctxt == NULL)
325 sdesc.shash.flags = 0x0; 335 return -ENOMEM;
326 336
327 crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash, 337 /* calculate md4 hash of password */
328 CIFS_NTHASH_SIZE); 338 E_md4hash(ses->password, nt_hash);
329 339
330 rc = crypto_shash_init(&sdesc.shash); 340 /* convert Domainname to unicode and uppercase */
331 if (rc) { 341 hmac_md5_init_limK_to_64(nt_hash, 16, pctxt);
332 cERROR(1, "could not initialize master crypto API hmacmd5\n");
333 return rc;
334 }
335 342
336 /* convert ses->userName to unicode and uppercase */ 343 /* convert ses->userName to unicode and uppercase */
337 len = strlen(ses->userName); 344 len = strlen(ses->userName);
@@ -340,8 +347,7 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
340 goto calc_exit_2; 347 goto calc_exit_2;
341 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); 348 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
342 UniStrupr(user); 349 UniStrupr(user);
343 350 hmac_md5_update((char *)user, 2*len, pctxt);
344 crypto_shash_update(&sdesc.shash, (char *)user, 2 * len);
345 351
346 /* convert ses->domainName to unicode and uppercase */ 352 /* convert ses->domainName to unicode and uppercase */
347 if (ses->domainName) { 353 if (ses->domainName) {
@@ -357,243 +363,65 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
357 Maybe converting the domain name earlier makes sense */ 363 Maybe converting the domain name earlier makes sense */
358 /* UniStrupr(domain); */ 364 /* UniStrupr(domain); */
359 365
360 crypto_shash_update(&sdesc.shash, (char *)domain, 2 * len); 366 hmac_md5_update((char *)domain, 2*len, pctxt);
361 367
362 kfree(domain); 368 kfree(domain);
363 } else if (ses->serverName) {
364 len = strlen(ses->serverName);
365
366 server = kmalloc(2 + (len * 2), GFP_KERNEL);
367 if (server == NULL)
368 goto calc_exit_1;
369 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
370 nls_cp);
371 /* the following line was removed since it didn't work well
372 with lower cased domain name that passed as an option.
373 Maybe converting the domain name earlier makes sense */
374 /* UniStrupr(domain); */
375
376 crypto_shash_update(&sdesc.shash, (char *)server, 2 * len);
377
378 kfree(server);
379 } 369 }
380calc_exit_1: 370calc_exit_1:
381 kfree(user); 371 kfree(user);
382calc_exit_2: 372calc_exit_2:
383 /* BB FIXME what about bytes 24 through 40 of the signing key? 373 /* BB FIXME what about bytes 24 through 40 of the signing key?
384 compare with the NTLM example */ 374 compare with the NTLM example */
385 rc = crypto_shash_final(&sdesc.shash, ses->server->ntlmv2_hash); 375 hmac_md5_final(ses->server->ntlmv2_hash, pctxt);
386
387 return rc;
388}
389
390static int
391find_domain_name(struct cifsSesInfo *ses)
392{
393 int rc = 0;
394 unsigned int attrsize;
395 unsigned int type;
396 unsigned char *blobptr;
397 struct ntlmssp2_name *attrptr;
398
399 if (ses->server->tiblob) {
400 blobptr = ses->server->tiblob;
401 attrptr = (struct ntlmssp2_name *) blobptr;
402
403 while ((type = attrptr->type) != 0) {
404 blobptr += 2; /* advance attr type */
405 attrsize = attrptr->length;
406 blobptr += 2; /* advance attr size */
407 if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
408 if (!ses->domainName) {
409 ses->domainName =
410 kmalloc(attrptr->length + 1,
411 GFP_KERNEL);
412 if (!ses->domainName)
413 return -ENOMEM;
414 cifs_from_ucs2(ses->domainName,
415 (__le16 *)blobptr,
416 attrptr->length,
417 attrptr->length,
418 load_nls_default(), false);
419 }
420 }
421 blobptr += attrsize; /* advance attr value */
422 attrptr = (struct ntlmssp2_name *) blobptr;
423 }
424 } else {
425 ses->server->tilen = 2 * sizeof(struct ntlmssp2_name);
426 ses->server->tiblob = kmalloc(ses->server->tilen, GFP_KERNEL);
427 if (!ses->server->tiblob) {
428 ses->server->tilen = 0;
429 cERROR(1, "Challenge target info allocation failure");
430 return -ENOMEM;
431 }
432 memset(ses->server->tiblob, 0x0, ses->server->tilen);
433 attrptr = (struct ntlmssp2_name *) ses->server->tiblob;
434 attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE);
435 }
436 376
377 kfree(pctxt);
437 return rc; 378 return rc;
438} 379}
439 380
440static int 381void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
441CalcNTLMv2_response(const struct TCP_Server_Info *server,
442 char *v2_session_response)
443{
444 int rc;
445 struct {
446 struct shash_desc shash;
447 char ctx[crypto_shash_descsize(server->ntlmssp.hmacmd5)];
448 } sdesc;
449
450 sdesc.shash.tfm = server->ntlmssp.hmacmd5;
451 sdesc.shash.flags = 0x0;
452
453 crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash,
454 CIFS_HMAC_MD5_HASH_SIZE);
455
456 rc = crypto_shash_init(&sdesc.shash);
457 if (rc) {
458 cERROR(1, "could not initialize master crypto API hmacmd5\n");
459 return rc;
460 }
461
462 memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE,
463 server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE);
464 crypto_shash_update(&sdesc.shash,
465 v2_session_response + CIFS_SERVER_CHALLENGE_SIZE,
466 sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE);
467
468 if (server->tilen)
469 crypto_shash_update(&sdesc.shash,
470 server->tiblob, server->tilen);
471
472 rc = crypto_shash_final(&sdesc.shash, v2_session_response);
473
474 return rc;
475}
476
477int
478setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
479 const struct nls_table *nls_cp) 382 const struct nls_table *nls_cp)
480{ 383{
481 int rc = 0; 384 int rc;
482 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; 385 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf;
483 struct { 386 struct HMACMD5Context context;
484 struct shash_desc shash;
485 char ctx[crypto_shash_descsize(ses->server->ntlmssp.hmacmd5)];
486 } sdesc;
487 387
488 buf->blob_signature = cpu_to_le32(0x00000101); 388 buf->blob_signature = cpu_to_le32(0x00000101);
489 buf->reserved = 0; 389 buf->reserved = 0;
490 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 390 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
491 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); 391 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
492 buf->reserved2 = 0; 392 buf->reserved2 = 0;
493 393 buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE);
494 if (!ses->domainName) { 394 buf->names[0].length = 0;
495 rc = find_domain_name(ses); 395 buf->names[1].type = 0;
496 if (rc) { 396 buf->names[1].length = 0;
497 cERROR(1, "could not get domain/server name rc %d", rc);
498 return rc;
499 }
500 }
501 397
502 /* calculate buf->ntlmv2_hash */ 398 /* calculate buf->ntlmv2_hash */
503 rc = calc_ntlmv2_hash(ses, nls_cp); 399 rc = calc_ntlmv2_hash(ses, nls_cp);
504 if (rc) { 400 if (rc)
505 cERROR(1, "could not get v2 hash rc %d", rc);
506 return rc;
507 }
508 rc = CalcNTLMv2_response(ses->server, resp_buf);
509 if (rc) {
510 cERROR(1, "could not get v2 hash rc %d", rc); 401 cERROR(1, "could not get v2 hash rc %d", rc);
511 return rc; 402 CalcNTLMv2_response(ses, resp_buf);
512 }
513
514 crypto_shash_setkey(ses->server->ntlmssp.hmacmd5,
515 ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
516
517 sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5;
518 sdesc.shash.flags = 0x0;
519
520 rc = crypto_shash_init(&sdesc.shash);
521 if (rc) {
522 cERROR(1, "could not initialize master crypto API hmacmd5\n");
523 return rc;
524 }
525
526 crypto_shash_update(&sdesc.shash, resp_buf, CIFS_HMAC_MD5_HASH_SIZE);
527 403
528 rc = crypto_shash_final(&sdesc.shash, 404 /* now calculate the MAC key for NTLMv2 */
529 ses->server->session_key.data.ntlmv2.key); 405 hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
406 hmac_md5_update(resp_buf, 16, &context);
407 hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context);
530 408
531 memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf, 409 memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf,
532 sizeof(struct ntlmv2_resp)); 410 sizeof(struct ntlmv2_resp));
533 ses->server->session_key.len = 16 + sizeof(struct ntlmv2_resp); 411 ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp);
534
535 return rc;
536} 412}
537 413
538int 414void CalcNTLMv2_response(const struct cifsSesInfo *ses,
539calc_seckey(struct TCP_Server_Info *server) 415 char *v2_session_response)
540{
541 int rc;
542 unsigned char sec_key[CIFS_NTLMV2_SESSKEY_SIZE];
543 struct crypto_blkcipher *tfm_arc4;
544 struct scatterlist sgin, sgout;
545 struct blkcipher_desc desc;
546
547 get_random_bytes(sec_key, CIFS_NTLMV2_SESSKEY_SIZE);
548
549 tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)",
550 0, CRYPTO_ALG_ASYNC);
551 if (!tfm_arc4 || IS_ERR(tfm_arc4)) {
552 cERROR(1, "could not allocate " "master crypto API arc4\n");
553 return 1;
554 }
555
556 crypto_blkcipher_setkey(tfm_arc4,
557 server->session_key.data.ntlmv2.key, CIFS_CPHTXT_SIZE);
558 sg_init_one(&sgin, sec_key, CIFS_CPHTXT_SIZE);
559 sg_init_one(&sgout, server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE);
560 rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE);
561
562 if (!rc)
563 memcpy(server->session_key.data.ntlmv2.key,
564 sec_key, CIFS_NTLMV2_SESSKEY_SIZE);
565
566 crypto_free_blkcipher(tfm_arc4);
567
568 return 0;
569}
570
571void
572cifs_crypto_shash_release(struct TCP_Server_Info *server)
573{
574 if (server->ntlmssp.md5)
575 crypto_free_shash(server->ntlmssp.md5);
576
577 if (server->ntlmssp.hmacmd5)
578 crypto_free_shash(server->ntlmssp.hmacmd5);
579}
580
581int
582cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
583{ 416{
584 server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); 417 struct HMACMD5Context context;
585 if (!server->ntlmssp.hmacmd5 || 418 /* rest of v2 struct already generated */
586 IS_ERR(server->ntlmssp.hmacmd5)) { 419 memcpy(v2_session_response + 8, ses->server->cryptKey, 8);
587 cERROR(1, "could not allocate master crypto API hmacmd5\n"); 420 hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
588 return 1;
589 }
590 421
591 server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0); 422 hmac_md5_update(v2_session_response+8,
592 if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) { 423 sizeof(struct ntlmv2_resp) - 8, &context);
593 crypto_free_shash(server->ntlmssp.hmacmd5);
594 cERROR(1, "could not allocate master crypto API md5\n");
595 return 1;
596 }
597 424
598 return 0; 425 hmac_md5_final(v2_session_response, &context);
426/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */
599} 427}
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 49563e0c172..0cdfb8c32ac 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -25,9 +25,6 @@
25#include <linux/workqueue.h> 25#include <linux/workqueue.h>
26#include "cifs_fs_sb.h" 26#include "cifs_fs_sb.h"
27#include "cifsacl.h" 27#include "cifsacl.h"
28#include <crypto/internal/hash.h>
29#include <linux/scatterlist.h>
30
31/* 28/*
32 * The sizes of various internal tables and strings 29 * The sizes of various internal tables and strings
33 */ 30 */
@@ -100,7 +97,7 @@ enum protocolEnum {
100 /* Netbios frames protocol not supported at this time */ 97 /* Netbios frames protocol not supported at this time */
101}; 98};
102 99
103struct session_key { 100struct mac_key {
104 unsigned int len; 101 unsigned int len;
105 union { 102 union {
106 char ntlm[CIFS_SESS_KEY_SIZE + 16]; 103 char ntlm[CIFS_SESS_KEY_SIZE + 16];
@@ -123,14 +120,6 @@ struct cifs_cred {
123 struct cifs_ace *aces; 120 struct cifs_ace *aces;
124}; 121};
125 122
126struct ntlmssp_auth {
127 __u32 client_flags;
128 __u32 server_flags;
129 unsigned char ciphertext[CIFS_CPHTXT_SIZE];
130 struct crypto_shash *hmacmd5;
131 struct crypto_shash *md5;
132};
133
134/* 123/*
135 ***************************************************************** 124 *****************************************************************
136 * Except the CIFS PDUs themselves all the 125 * Except the CIFS PDUs themselves all the
@@ -193,14 +182,11 @@ struct TCP_Server_Info {
193 /* 16th byte of RFC1001 workstation name is always null */ 182 /* 16th byte of RFC1001 workstation name is always null */
194 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 183 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
195 __u32 sequence_number; /* needed for CIFS PDU signature */ 184 __u32 sequence_number; /* needed for CIFS PDU signature */
196 struct session_key session_key; 185 struct mac_key mac_signing_key;
197 char ntlmv2_hash[16]; 186 char ntlmv2_hash[16];
198 unsigned long lstrp; /* when we got last response from this server */ 187 unsigned long lstrp; /* when we got last response from this server */
199 u16 dialect; /* dialect index that server chose */ 188 u16 dialect; /* dialect index that server chose */
200 /* extended security flavors that server supports */ 189 /* extended security flavors that server supports */
201 unsigned int tilen; /* length of the target info blob */
202 unsigned char *tiblob; /* target info blob in challenge response */
203 struct ntlmssp_auth ntlmssp; /* various keys, ciphers, flags */
204 bool sec_kerberos; /* supports plain Kerberos */ 190 bool sec_kerberos; /* supports plain Kerberos */
205 bool sec_mskerberos; /* supports legacy MS Kerberos */ 191 bool sec_mskerberos; /* supports legacy MS Kerberos */
206 bool sec_kerberosu2u; /* supports U2U Kerberos */ 192 bool sec_kerberosu2u; /* supports U2U Kerberos */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 320e0fd0ba7..14d036d8db1 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -134,12 +134,6 @@
134 * Size of the session key (crypto key encrypted with the password 134 * Size of the session key (crypto key encrypted with the password
135 */ 135 */
136#define CIFS_SESS_KEY_SIZE (24) 136#define CIFS_SESS_KEY_SIZE (24)
137#define CIFS_CLIENT_CHALLENGE_SIZE (8)
138#define CIFS_SERVER_CHALLENGE_SIZE (8)
139#define CIFS_HMAC_MD5_HASH_SIZE (16)
140#define CIFS_CPHTXT_SIZE (16)
141#define CIFS_NTLMV2_SESSKEY_SIZE (16)
142#define CIFS_NTHASH_SIZE (16)
143 137
144/* 138/*
145 * Maximum user name length 139 * Maximum user name length
@@ -669,6 +663,7 @@ struct ntlmv2_resp {
669 __le64 time; 663 __le64 time;
670 __u64 client_chal; /* random */ 664 __u64 client_chal; /* random */
671 __u32 reserved2; 665 __u32 reserved2;
666 struct ntlmssp2_name names[2];
672 /* array of name entries could follow ending in minimum 4 byte struct */ 667 /* array of name entries could follow ending in minimum 4 byte struct */
673} __attribute__((packed)); 668} __attribute__((packed));
674 669
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 1378d913384..1f545081408 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -361,15 +361,15 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
361extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 361extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
362 __u32 *); 362 __u32 *);
363extern int cifs_verify_signature(struct smb_hdr *, 363extern int cifs_verify_signature(struct smb_hdr *,
364 struct TCP_Server_Info *server, 364 const struct mac_key *mac_key,
365 __u32 expected_sequence_number); 365 __u32 expected_sequence_number);
366extern int cifs_calculate_session_key(struct session_key *key, const char *rn, 366extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
367 const char *pass); 367 const char *pass);
368extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 368extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *,
369 const struct nls_table *);
370extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *);
371extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
369 const struct nls_table *); 372 const struct nls_table *);
370extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
371extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
372extern int calc_seckey(struct TCP_Server_Info *);
373#ifdef CONFIG_CIFS_WEAK_PW_HASH 373#ifdef CONFIG_CIFS_WEAK_PW_HASH
374extern void calc_lanman_hash(const char *password, const char *cryptkey, 374extern void calc_lanman_hash(const char *password, const char *cryptkey,
375 bool encrypt, char *lnm_session_key); 375 bool encrypt, char *lnm_session_key);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 4bda920d1f7..c65c3419dd3 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -604,14 +604,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
604 else 604 else
605 rc = -EINVAL; 605 rc = -EINVAL;
606 606
607 if (server->secType == Kerberos) { 607 if (server->sec_kerberos || server->sec_mskerberos)
608 if (!server->sec_kerberos && 608 server->secType = Kerberos;
609 !server->sec_mskerberos) 609 else if (server->sec_ntlmssp)
610 rc = -EOPNOTSUPP; 610 server->secType = RawNTLMSSP;
611 } else if (server->secType == RawNTLMSSP) { 611 else
612 if (!server->sec_ntlmssp)
613 rc = -EOPNOTSUPP;
614 } else
615 rc = -EOPNOTSUPP; 612 rc = -EOPNOTSUPP;
616 } 613 }
617 } else 614 } else
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index ec0ea4a43bd..0ea52e9f906 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1708,7 +1708,6 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
1708 CIFSSMBLogoff(xid, ses); 1708 CIFSSMBLogoff(xid, ses);
1709 _FreeXid(xid); 1709 _FreeXid(xid);
1710 } 1710 }
1711 cifs_crypto_shash_release(server);
1712 sesInfoFree(ses); 1711 sesInfoFree(ses);
1713 cifs_put_tcp_session(server); 1712 cifs_put_tcp_session(server);
1714} 1713}
@@ -1788,23 +1787,13 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1788 ses->linux_uid = volume_info->linux_uid; 1787 ses->linux_uid = volume_info->linux_uid;
1789 ses->overrideSecFlg = volume_info->secFlg; 1788 ses->overrideSecFlg = volume_info->secFlg;
1790 1789
1791 rc = cifs_crypto_shash_allocate(server);
1792 if (rc) {
1793 cERROR(1, "could not setup hash structures rc %d", rc);
1794 goto get_ses_fail;
1795 }
1796 server->tilen = 0;
1797 server->tiblob = NULL;
1798
1799 mutex_lock(&ses->session_mutex); 1790 mutex_lock(&ses->session_mutex);
1800 rc = cifs_negotiate_protocol(xid, ses); 1791 rc = cifs_negotiate_protocol(xid, ses);
1801 if (!rc) 1792 if (!rc)
1802 rc = cifs_setup_session(xid, ses, volume_info->local_nls); 1793 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
1803 mutex_unlock(&ses->session_mutex); 1794 mutex_unlock(&ses->session_mutex);
1804 if (rc) { 1795 if (rc)
1805 cifs_crypto_shash_release(ses->server);
1806 goto get_ses_fail; 1796 goto get_ses_fail;
1807 }
1808 1797
1809 /* success, put it on the list */ 1798 /* success, put it on the list */
1810 write_lock(&cifs_tcp_ses_lock); 1799 write_lock(&cifs_tcp_ses_lock);
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 1db0f0746a5..49c9a4e7531 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -61,19 +61,6 @@
61#define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000 61#define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000
62#define NTLMSSP_NEGOTIATE_56 0x80000000 62#define NTLMSSP_NEGOTIATE_56 0x80000000
63 63
64/* Define AV Pair Field IDs */
65#define NTLMSSP_AV_EOL 0
66#define NTLMSSP_AV_NB_COMPUTER_NAME 1
67#define NTLMSSP_AV_NB_DOMAIN_NAME 2
68#define NTLMSSP_AV_DNS_COMPUTER_NAME 3
69#define NTLMSSP_AV_DNS_DOMAIN_NAME 4
70#define NTLMSSP_AV_DNS_TREE_NAME 5
71#define NTLMSSP_AV_FLAGS 6
72#define NTLMSSP_AV_TIMESTAMP 7
73#define NTLMSSP_AV_RESTRICTION 8
74#define NTLMSSP_AV_TARGET_NAME 9
75#define NTLMSSP_AV_CHANNEL_BINDINGS 10
76
77/* Although typedefs are not commonly used for structure definitions */ 64/* Although typedefs are not commonly used for structure definitions */
78/* in the Linux kernel, in this particular case they are useful */ 65/* in the Linux kernel, in this particular case they are useful */
79/* to more closely match the standards document for NTLMSSP from */ 66/* to more closely match the standards document for NTLMSSP from */
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 41fc5328120..0a57cb7db5d 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -383,9 +383,6 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
383static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, 383static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
384 struct cifsSesInfo *ses) 384 struct cifsSesInfo *ses)
385{ 385{
386 unsigned int tioffset; /* challeng message target info area */
387 unsigned int tilen; /* challeng message target info area length */
388
389 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; 386 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
390 387
391 if (blob_len < sizeof(CHALLENGE_MESSAGE)) { 388 if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
@@ -408,18 +405,6 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
408 /* BB spec says that if AvId field of MsvAvTimestamp is populated then 405 /* BB spec says that if AvId field of MsvAvTimestamp is populated then
409 we must set the MIC field of the AUTHENTICATE_MESSAGE */ 406 we must set the MIC field of the AUTHENTICATE_MESSAGE */
410 407
411 tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset);
412 tilen = cpu_to_le16(pblob->TargetInfoArray.Length);
413 ses->server->tilen = tilen;
414 if (tilen) {
415 ses->server->tiblob = kmalloc(tilen, GFP_KERNEL);
416 if (!ses->server->tiblob) {
417 cERROR(1, "Challenge target info allocation failure");
418 return -ENOMEM;
419 }
420 memcpy(ses->server->tiblob, bcc_ptr + tioffset, tilen);
421 }
422
423 return 0; 408 return 0;
424} 409}
425 410
@@ -466,12 +451,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
466 struct cifsSesInfo *ses, 451 struct cifsSesInfo *ses,
467 const struct nls_table *nls_cp, bool first) 452 const struct nls_table *nls_cp, bool first)
468{ 453{
469 int rc;
470 unsigned int size;
471 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; 454 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
472 __u32 flags; 455 __u32 flags;
473 unsigned char *tmp; 456 unsigned char *tmp;
474 struct ntlmv2_resp ntlmv2_response = {}; 457 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
475 458
476 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 459 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
477 sec_blob->MessageType = NtLmAuthenticate; 460 sec_blob->MessageType = NtLmAuthenticate;
@@ -494,25 +477,19 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
494 sec_blob->LmChallengeResponse.Length = 0; 477 sec_blob->LmChallengeResponse.Length = 0;
495 sec_blob->LmChallengeResponse.MaximumLength = 0; 478 sec_blob->LmChallengeResponse.MaximumLength = 0;
496 479
497 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); 480 /* calculate session key, BB what about adding similar ntlmv2 path? */
498 rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp); 481 SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key);
499 if (rc) { 482 if (first)
500 cERROR(1, "error rc: %d during ntlmssp ntlmv2 setup", rc); 483 cifs_calculate_mac_key(&ses->server->mac_signing_key,
501 goto setup_ntlmv2_ret; 484 ntlm_session_key, ses->password);
502 }
503 size = sizeof(struct ntlmv2_resp);
504 memcpy(tmp, (char *)&ntlmv2_response, size);
505 tmp += size;
506 if (ses->server->tilen > 0) {
507 memcpy(tmp, ses->server->tiblob, ses->server->tilen);
508 tmp += ses->server->tilen;
509 } else
510 ses->server->tilen = 0;
511 485
512 sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + 486 memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE);
513 ses->server->tilen); 487 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
488 sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE);
514 sec_blob->NtChallengeResponse.MaximumLength = 489 sec_blob->NtChallengeResponse.MaximumLength =
515 cpu_to_le16(size + ses->server->tilen); 490 cpu_to_le16(CIFS_SESS_KEY_SIZE);
491
492 tmp += CIFS_SESS_KEY_SIZE;
516 493
517 if (ses->domainName == NULL) { 494 if (ses->domainName == NULL) {
518 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 495 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
@@ -524,6 +501,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
524 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, 501 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
525 MAX_USERNAME_SIZE, nls_cp); 502 MAX_USERNAME_SIZE, nls_cp);
526 len *= 2; /* unicode is 2 bytes each */ 503 len *= 2; /* unicode is 2 bytes each */
504 len += 2; /* trailing null */
527 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 505 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
528 sec_blob->DomainName.Length = cpu_to_le16(len); 506 sec_blob->DomainName.Length = cpu_to_le16(len);
529 sec_blob->DomainName.MaximumLength = cpu_to_le16(len); 507 sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
@@ -540,6 +518,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
540 len = cifs_strtoUCS((__le16 *)tmp, ses->userName, 518 len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
541 MAX_USERNAME_SIZE, nls_cp); 519 MAX_USERNAME_SIZE, nls_cp);
542 len *= 2; /* unicode is 2 bytes each */ 520 len *= 2; /* unicode is 2 bytes each */
521 len += 2; /* trailing null */
543 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); 522 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
544 sec_blob->UserName.Length = cpu_to_le16(len); 523 sec_blob->UserName.Length = cpu_to_le16(len);
545 sec_blob->UserName.MaximumLength = cpu_to_le16(len); 524 sec_blob->UserName.MaximumLength = cpu_to_le16(len);
@@ -551,26 +530,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
551 sec_blob->WorkstationName.MaximumLength = 0; 530 sec_blob->WorkstationName.MaximumLength = 0;
552 tmp += 2; 531 tmp += 2;
553 532
554 if ((ses->server->ntlmssp.server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && 533 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
555 !calc_seckey(ses->server)) { 534 sec_blob->SessionKey.Length = 0;
556 memcpy(tmp, ses->server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); 535 sec_blob->SessionKey.MaximumLength = 0;
557 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
558 sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
559 sec_blob->SessionKey.MaximumLength =
560 cpu_to_le16(CIFS_CPHTXT_SIZE);
561 tmp += CIFS_CPHTXT_SIZE;
562 } else {
563 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
564 sec_blob->SessionKey.Length = 0;
565 sec_blob->SessionKey.MaximumLength = 0;
566 }
567
568 ses->server->sequence_number = 0;
569
570setup_ntlmv2_ret:
571 if (ses->server->tilen > 0)
572 kfree(ses->server->tiblob);
573
574 return tmp - pbuffer; 536 return tmp - pbuffer;
575} 537}
576 538
@@ -584,14 +546,15 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
584 return; 546 return;
585} 547}
586 548
587static int setup_ntlmssp_auth_req(char *ntlmsspblob, 549static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
588 struct cifsSesInfo *ses, 550 struct cifsSesInfo *ses,
589 const struct nls_table *nls, bool first_time) 551 const struct nls_table *nls, bool first_time)
590{ 552{
591 int bloblen; 553 int bloblen;
592 554
593 bloblen = build_ntlmssp_auth_blob(ntlmsspblob, ses, nls, 555 bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls,
594 first_time); 556 first_time);
557 pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen);
595 558
596 return bloblen; 559 return bloblen;
597} 560}
@@ -617,7 +580,6 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
617 struct key *spnego_key = NULL; 580 struct key *spnego_key = NULL;
618 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 581 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
619 bool first_time; 582 bool first_time;
620 char *ntlmsspblob;
621 583
622 if (ses == NULL) 584 if (ses == NULL)
623 return -EINVAL; 585 return -EINVAL;
@@ -728,7 +690,7 @@ ssetup_ntlmssp_authenticate:
728 690
729 if (first_time) /* should this be moved into common code 691 if (first_time) /* should this be moved into common code
730 with similar ntlmv2 path? */ 692 with similar ntlmv2 path? */
731 cifs_calculate_session_key(&ses->server->session_key, 693 cifs_calculate_mac_key(&ses->server->mac_signing_key,
732 ntlm_session_key, ses->password); 694 ntlm_session_key, ses->password);
733 /* copy session key */ 695 /* copy session key */
734 696
@@ -767,21 +729,12 @@ ssetup_ntlmssp_authenticate:
767 cpu_to_le16(sizeof(struct ntlmv2_resp)); 729 cpu_to_le16(sizeof(struct ntlmv2_resp));
768 730
769 /* calculate session key */ 731 /* calculate session key */
770 rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 732 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
771 if (rc) {
772 kfree(v2_sess_key);
773 goto ssetup_exit;
774 }
775 /* FIXME: calculate MAC key */ 733 /* FIXME: calculate MAC key */
776 memcpy(bcc_ptr, (char *)v2_sess_key, 734 memcpy(bcc_ptr, (char *)v2_sess_key,
777 sizeof(struct ntlmv2_resp)); 735 sizeof(struct ntlmv2_resp));
778 bcc_ptr += sizeof(struct ntlmv2_resp); 736 bcc_ptr += sizeof(struct ntlmv2_resp);
779 kfree(v2_sess_key); 737 kfree(v2_sess_key);
780 if (ses->server->tilen > 0) {
781 memcpy(bcc_ptr, ses->server->tiblob,
782 ses->server->tilen);
783 bcc_ptr += ses->server->tilen;
784 }
785 if (ses->capabilities & CAP_UNICODE) { 738 if (ses->capabilities & CAP_UNICODE) {
786 if (iov[0].iov_len % 2) { 739 if (iov[0].iov_len % 2) {
787 *bcc_ptr = 0; 740 *bcc_ptr = 0;
@@ -812,15 +765,15 @@ ssetup_ntlmssp_authenticate:
812 } 765 }
813 /* bail out if key is too long */ 766 /* bail out if key is too long */
814 if (msg->sesskey_len > 767 if (msg->sesskey_len >
815 sizeof(ses->server->session_key.data.krb5)) { 768 sizeof(ses->server->mac_signing_key.data.krb5)) {
816 cERROR(1, "Kerberos signing key too long (%u bytes)", 769 cERROR(1, "Kerberos signing key too long (%u bytes)",
817 msg->sesskey_len); 770 msg->sesskey_len);
818 rc = -EOVERFLOW; 771 rc = -EOVERFLOW;
819 goto ssetup_exit; 772 goto ssetup_exit;
820 } 773 }
821 if (first_time) { 774 if (first_time) {
822 ses->server->session_key.len = msg->sesskey_len; 775 ses->server->mac_signing_key.len = msg->sesskey_len;
823 memcpy(ses->server->session_key.data.krb5, 776 memcpy(ses->server->mac_signing_key.data.krb5,
824 msg->data, msg->sesskey_len); 777 msg->data, msg->sesskey_len);
825 } 778 }
826 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 779 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
@@ -862,26 +815,12 @@ ssetup_ntlmssp_authenticate:
862 if (phase == NtLmNegotiate) { 815 if (phase == NtLmNegotiate) {
863 setup_ntlmssp_neg_req(pSMB, ses); 816 setup_ntlmssp_neg_req(pSMB, ses);
864 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); 817 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
865 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
866 } else if (phase == NtLmAuthenticate) { 818 } else if (phase == NtLmAuthenticate) {
867 int blob_len; 819 int blob_len;
868 ntlmsspblob = kmalloc(5 * 820 blob_len = setup_ntlmssp_auth_req(pSMB, ses,
869 sizeof(struct _AUTHENTICATE_MESSAGE), 821 nls_cp,
870 GFP_KERNEL); 822 first_time);
871 if (!ntlmsspblob) {
872 cERROR(1, "Can't allocate NTLMSSP");
873 rc = -ENOMEM;
874 goto ssetup_exit;
875 }
876
877 blob_len = setup_ntlmssp_auth_req(ntlmsspblob,
878 ses,
879 nls_cp,
880 first_time);
881 iov[1].iov_len = blob_len; 823 iov[1].iov_len = blob_len;
882 iov[1].iov_base = ntlmsspblob;
883 pSMB->req.SecurityBlobLength =
884 cpu_to_le16(blob_len);
885 /* Make sure that we tell the server that we 824 /* Make sure that we tell the server that we
886 are using the uid that it just gave us back 825 are using the uid that it just gave us back
887 on the response (challenge) */ 826 on the response (challenge) */
@@ -891,6 +830,7 @@ ssetup_ntlmssp_authenticate:
891 rc = -ENOSYS; 830 rc = -ENOSYS;
892 goto ssetup_exit; 831 goto ssetup_exit;
893 } 832 }
833 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
894 /* unicode strings must be word aligned */ 834 /* unicode strings must be word aligned */
895 if ((iov[0].iov_len + iov[1].iov_len) % 2) { 835 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
896 *bcc_ptr = 0; 836 *bcc_ptr = 0;
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index e0588cdf4cc..82f78c4d697 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -543,7 +543,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
544 SECMODE_SIGN_ENABLED))) { 544 SECMODE_SIGN_ENABLED))) {
545 rc = cifs_verify_signature(midQ->resp_buf, 545 rc = cifs_verify_signature(midQ->resp_buf,
546 ses->server, 546 &ses->server->mac_signing_key,
547 midQ->sequence_number+1); 547 midQ->sequence_number+1);
548 if (rc) { 548 if (rc) {
549 cERROR(1, "Unexpected SMB signature"); 549 cERROR(1, "Unexpected SMB signature");
@@ -731,7 +731,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
732 SECMODE_SIGN_ENABLED))) { 732 SECMODE_SIGN_ENABLED))) {
733 rc = cifs_verify_signature(out_buf, 733 rc = cifs_verify_signature(out_buf,
734 ses->server, 734 &ses->server->mac_signing_key,
735 midQ->sequence_number+1); 735 midQ->sequence_number+1);
736 if (rc) { 736 if (rc) {
737 cERROR(1, "Unexpected SMB signature"); 737 cERROR(1, "Unexpected SMB signature");
@@ -981,7 +981,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
982 SECMODE_SIGN_ENABLED))) { 982 SECMODE_SIGN_ENABLED))) {
983 rc = cifs_verify_signature(out_buf, 983 rc = cifs_verify_signature(out_buf,
984 ses->server, 984 &ses->server->mac_signing_key,
985 midQ->sequence_number+1); 985 midQ->sequence_number+1);
986 if (rc) { 986 if (rc) {
987 cERROR(1, "Unexpected SMB signature"); 987 cERROR(1, "Unexpected SMB signature");