Commit c8e56f1f4fb9f82f63e4ce6d73a14501d0432c76

Authored by Steve French
1 parent 745e507a9c

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>

Showing 11 changed files with 172 additions and 452 deletions Side-by-side Diff

... ... @@ -2,8 +2,6 @@
2 2 tristate "CIFS support (advanced network filesystem, SMBFS successor)"
3 3 depends on INET
4 4 select NLS
5   - select CRYPTO_MD5
6   - select CRYPTO_ARC4
7 5 help
8 6 This is the client VFS module for the Common Internet File System
9 7 (CIFS) protocol which is the successor to the Server Message Block
... ... @@ -597,13 +597,13 @@
597 597 if (compare_oid(oid, oidlen, MSKRB5_OID,
598 598 MSKRB5_OID_LEN))
599 599 server->sec_mskerberos = true;
600   - if (compare_oid(oid, oidlen, KRB5U2U_OID,
  600 + else if (compare_oid(oid, oidlen, KRB5U2U_OID,
601 601 KRB5U2U_OID_LEN))
602 602 server->sec_kerberosu2u = true;
603   - if (compare_oid(oid, oidlen, KRB5_OID,
  603 + else if (compare_oid(oid, oidlen, KRB5_OID,
604 604 KRB5_OID_LEN))
605 605 server->sec_kerberos = true;
606   - if (compare_oid(oid, oidlen, NTLMSSP_OID,
  606 + else if (compare_oid(oid, oidlen, NTLMSSP_OID,
607 607 NTLMSSP_OID_LEN))
608 608 server->sec_ntlmssp = true;
609 609  
fs/cifs/cifsencrypt.c
... ... @@ -27,7 +27,6 @@
27 27 #include "md5.h"
28 28 #include "cifs_unicode.h"
29 29 #include "cifsproto.h"
30   -#include "ntlmssp.h"
31 30 #include <linux/ctype.h>
32 31 #include <linux/random.h>
33 32  
34 33  
35 34  
36 35  
37 36  
38 37  
... ... @@ -43,44 +42,21 @@
43 42 unsigned char *p24);
44 43  
45 44 static 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;
49   - struct {
50   - struct shash_desc shash;
51   - char ctx[crypto_shash_descsize(server->ntlmssp.md5)];
52   - } sdesc;
  47 + struct MD5Context context;
53 48  
54   - if (cifs_pdu == NULL || server == NULL || signature == NULL)
  49 + if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL))
55 50 return -EINVAL;
56 51  
57   - sdesc.shash.tfm = server->ntlmssp.md5;
58   - sdesc.shash.flags = 0x0;
  52 + cifs_MD5_init(&context);
  53 + cifs_MD5_update(&context, (char *)&key->data, key->len);
  54 + cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
59 55  
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   -
  56 + cifs_MD5_final(signature, &context);
80 57 return 0;
81 58 }
82 59  
83   -
84 60 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
85 61 __u32 *pexpected_response_sequence_number)
86 62 {
... ... @@ -102,7 +78,8 @@
102 78 server->sequence_number++;
103 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 83 if (rc)
107 84 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
108 85 else
109 86  
110 87  
111 88  
112 89  
... ... @@ -112,36 +89,16 @@
112 89 }
113 90  
114 91 static 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 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 98 return -EINVAL;
126 99  
127   - sdesc.shash.tfm = server->ntlmssp.md5;
128   - sdesc.shash.flags = 0x0;
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   -
  100 + cifs_MD5_init(&context);
  101 + cifs_MD5_update(&context, (char *)&key->data, key->len);
145 102 for (i = 0; i < n_vec; i++) {
146 103 if (iov[i].iov_len == 0)
147 104 continue;
148 105  
149 106  
150 107  
... ... @@ -154,18 +111,18 @@
154 111 if (i == 0) {
155 112 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
156 113 break; /* nothing to sign or corrupt header */
157   - crypto_shash_update(&sdesc.shash,
158   - iov[i].iov_base + 4, iov[i].iov_len - 4);
  114 + cifs_MD5_update(&context, iov[0].iov_base+4,
  115 + iov[0].iov_len-4);
159 116 } else
160   - crypto_shash_update(&sdesc.shash,
161   - iov[i].iov_base, iov[i].iov_len);
  117 + cifs_MD5_update(&context, 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 122 return 0;
167 123 }
168 124  
  125 +
169 126 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
170 127 __u32 *pexpected_response_sequence_number)
171 128 {
... ... @@ -188,7 +145,8 @@
188 145 server->sequence_number++;
189 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 150 if (rc)
193 151 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
194 152 else
195 153  
196 154  
... ... @@ -198,14 +156,14 @@
198 156 }
199 157  
200 158 int cifs_verify_signature(struct smb_hdr *cifs_pdu,
201   - struct TCP_Server_Info *server,
  159 + const struct mac_key *mac_key,
202 160 __u32 expected_sequence_number)
203 161 {
204   - int rc;
  162 + unsigned int rc;
205 163 char server_response_sig[8];
206 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 167 return -EINVAL;
210 168  
211 169 if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
... ... @@ -234,7 +192,7 @@
234 192 cpu_to_le32(expected_sequence_number);
235 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 196 what_we_think_sig_should_be);
239 197  
240 198 if (rc)
... ... @@ -251,7 +209,7 @@
251 209 }
252 210  
253 211 /* We fill in key by putting in 40 byte array which was allocated by caller */
254   -int cifs_calculate_session_key(struct session_key *key, const char *rn,
  212 +int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
255 213 const char *password)
256 214 {
257 215 char temp_key[16];
... ... @@ -265,6 +223,63 @@
265 223 return 0;
266 224 }
267 225  
  226 +int 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 283 #ifdef CONFIG_CIFS_WEAK_PW_HASH
269 284 void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
270 285 char *lnm_session_key)
271 286  
272 287  
273 288  
274 289  
... ... @@ -309,30 +324,22 @@
309 324 {
310 325 int rc = 0;
311 326 int len;
312   - char nt_hash[CIFS_NTHASH_SIZE];
  327 + char nt_hash[16];
  328 + struct HMACMD5Context *pctxt;
313 329 wchar_t *user;
314 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  
  332 + pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL);
  333 +
  334 + if (pctxt == NULL)
  335 + return -ENOMEM;
  336 +
321 337 /* calculate md4 hash of password */
322 338 E_md4hash(ses->password, nt_hash);
323 339  
324   - sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5;
325   - sdesc.shash.flags = 0x0;
  340 + /* convert Domainname to unicode and uppercase */
  341 + hmac_md5_init_limK_to_64(nt_hash, 16, pctxt);
326 342  
327   - crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash,
328   - CIFS_NTHASH_SIZE);
329   -
330   - rc = crypto_shash_init(&sdesc.shash);
331   - if (rc) {
332   - cERROR(1, "could not initialize master crypto API hmacmd5\n");
333   - return rc;
334   - }
335   -
336 343 /* convert ses->userName to unicode and uppercase */
337 344 len = strlen(ses->userName);
338 345 user = kmalloc(2 + (len * 2), GFP_KERNEL);
339 346  
... ... @@ -340,9 +347,8 @@
340 347 goto calc_exit_2;
341 348 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
342 349 UniStrupr(user);
  350 + hmac_md5_update((char *)user, 2*len, pctxt);
343 351  
344   - crypto_shash_update(&sdesc.shash, (char *)user, 2 * len);
345   -
346 352 /* convert ses->domainName to unicode and uppercase */
347 353 if (ses->domainName) {
348 354 len = strlen(ses->domainName);
349 355  
350 356  
351 357  
352 358  
353 359  
354 360  
355 361  
356 362  
357 363  
358 364  
359 365  
360 366  
361 367  
362 368  
363 369  
364 370  
... ... @@ -357,244 +363,66 @@
357 363 Maybe converting the domain name earlier makes sense */
358 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 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 }
380 370 calc_exit_1:
381 371 kfree(user);
382 372 calc_exit_2:
383 373 /* BB FIXME what about bytes 24 through 40 of the signing key?
384 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 376  
  377 + kfree(pctxt);
387 378 return rc;
388 379 }
389 380  
390   -static int
391   -find_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   -
437   - return rc;
438   -}
439   -
440   -static int
441   -CalcNTLMv2_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   -
477   -int
478   -setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
  381 +void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
479 382 const struct nls_table *nls_cp)
480 383 {
481   - int rc = 0;
  384 + int rc;
482 385 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf;
483   - struct {
484   - struct shash_desc shash;
485   - char ctx[crypto_shash_descsize(ses->server->ntlmssp.hmacmd5)];
486   - } sdesc;
  386 + struct HMACMD5Context context;
487 387  
488 388 buf->blob_signature = cpu_to_le32(0x00000101);
489 389 buf->reserved = 0;
490 390 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
491 391 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
492 392 buf->reserved2 = 0;
  393 + buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE);
  394 + buf->names[0].length = 0;
  395 + buf->names[1].type = 0;
  396 + buf->names[1].length = 0;
493 397  
494   - if (!ses->domainName) {
495   - rc = find_domain_name(ses);
496   - if (rc) {
497   - cERROR(1, "could not get domain/server name rc %d", rc);
498   - return rc;
499   - }
500   - }
501   -
502 398 /* calculate buf->ntlmv2_hash */
503 399 rc = calc_ntlmv2_hash(ses, nls_cp);
504   - if (rc) {
  400 + if (rc)
505 401 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);
511   - return rc;
512   - }
  402 + CalcNTLMv2_response(ses, resp_buf);
513 403  
514   - crypto_shash_setkey(ses->server->ntlmssp.hmacmd5,
515   - ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
  404 + /* now calculate the MAC key for NTLMv2 */
  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);
516 408  
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   -
528   - rc = crypto_shash_final(&sdesc.shash,
529   - ses->server->session_key.data.ntlmv2.key);
530   -
531   - memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf,
532   - sizeof(struct ntlmv2_resp));
533   - ses->server->session_key.len = 16 + sizeof(struct ntlmv2_resp);
534   -
535   - return rc;
  409 + memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf,
  410 + sizeof(struct ntlmv2_resp));
  411 + ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp);
536 412 }
537 413  
538   -int
539   -calc_seckey(struct TCP_Server_Info *server)
  414 +void CalcNTLMv2_response(const struct cifsSesInfo *ses,
  415 + char *v2_session_response)
540 416 {
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;
  417 + struct HMACMD5Context context;
  418 + /* rest of v2 struct already generated */
  419 + memcpy(v2_session_response + 8, ses->server->cryptKey, 8);
  420 + hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
546 421  
547   - get_random_bytes(sec_key, CIFS_NTLMV2_SESSKEY_SIZE);
  422 + hmac_md5_update(v2_session_response+8,
  423 + sizeof(struct ntlmv2_resp) - 8, &context);
548 424  
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   -
571   -void
572   -cifs_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   -
581   -int
582   -cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
583   -{
584   - server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
585   - if (!server->ntlmssp.hmacmd5 ||
586   - IS_ERR(server->ntlmssp.hmacmd5)) {
587   - cERROR(1, "could not allocate master crypto API hmacmd5\n");
588   - return 1;
589   - }
590   -
591   - server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0);
592   - if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) {
593   - crypto_free_shash(server->ntlmssp.hmacmd5);
594   - cERROR(1, "could not allocate master crypto API md5\n");
595   - return 1;
596   - }
597   -
598   - return 0;
  425 + hmac_md5_final(v2_session_response, &context);
  426 +/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */
599 427 }
... ... @@ -25,9 +25,6 @@
25 25 #include <linux/workqueue.h>
26 26 #include "cifs_fs_sb.h"
27 27 #include "cifsacl.h"
28   -#include <crypto/internal/hash.h>
29   -#include <linux/scatterlist.h>
30   -
31 28 /*
32 29 * The sizes of various internal tables and strings
33 30 */
... ... @@ -100,7 +97,7 @@
100 97 /* Netbios frames protocol not supported at this time */
101 98 };
102 99  
103   -struct session_key {
  100 +struct mac_key {
104 101 unsigned int len;
105 102 union {
106 103 char ntlm[CIFS_SESS_KEY_SIZE + 16];
... ... @@ -123,14 +120,6 @@
123 120 struct cifs_ace *aces;
124 121 };
125 122  
126   -struct 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 125 * Except the CIFS PDUs themselves all the
137 126  
... ... @@ -193,14 +182,11 @@
193 182 /* 16th byte of RFC1001 workstation name is always null */
194 183 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
195 184 __u32 sequence_number; /* needed for CIFS PDU signature */
196   - struct session_key session_key;
  185 + struct mac_key mac_signing_key;
197 186 char ntlmv2_hash[16];
198 187 unsigned long lstrp; /* when we got last response from this server */
199 188 u16 dialect; /* dialect index that server chose */
200 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 190 bool sec_kerberos; /* supports plain Kerberos */
205 191 bool sec_mskerberos; /* supports legacy MS Kerberos */
206 192 bool sec_kerberosu2u; /* supports U2U Kerberos */
... ... @@ -134,12 +134,6 @@
134 134 * Size of the session key (crypto key encrypted with the password
135 135 */
136 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 139 * Maximum user name length
... ... @@ -669,6 +663,7 @@
669 663 __le64 time;
670 664 __u64 client_chal; /* random */
671 665 __u32 reserved2;
  666 + struct ntlmssp2_name names[2];
672 667 /* array of name entries could follow ending in minimum 4 byte struct */
673 668 } __attribute__((packed));
674 669  
... ... @@ -361,15 +361,15 @@
361 361 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
362 362 __u32 *);
363 363 extern int cifs_verify_signature(struct smb_hdr *,
364   - struct TCP_Server_Info *server,
  364 + const struct mac_key *mac_key,
365 365 __u32 expected_sequence_number);
366   -extern int cifs_calculate_session_key(struct session_key *key, const char *rn,
  366 +extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
367 367 const char *pass);
368   -extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
  368 +extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *,
  369 + const struct nls_table *);
  370 +extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *);
  371 +extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
369 372 const struct nls_table *);
370   -extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
371   -extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
372   -extern int calc_seckey(struct TCP_Server_Info *);
373 373 #ifdef CONFIG_CIFS_WEAK_PW_HASH
374 374 extern void calc_lanman_hash(const char *password, const char *cryptkey,
375 375 bool encrypt, char *lnm_session_key);
... ... @@ -604,14 +604,11 @@
604 604 else
605 605 rc = -EINVAL;
606 606  
607   - if (server->secType == Kerberos) {
608   - if (!server->sec_kerberos &&
609   - !server->sec_mskerberos)
610   - rc = -EOPNOTSUPP;
611   - } else if (server->secType == RawNTLMSSP) {
612   - if (!server->sec_ntlmssp)
613   - rc = -EOPNOTSUPP;
614   - } else
  607 + if (server->sec_kerberos || server->sec_mskerberos)
  608 + server->secType = Kerberos;
  609 + else if (server->sec_ntlmssp)
  610 + server->secType = RawNTLMSSP;
  611 + else
615 612 rc = -EOPNOTSUPP;
616 613 }
617 614 } else
... ... @@ -1708,7 +1708,6 @@
1708 1708 CIFSSMBLogoff(xid, ses);
1709 1709 _FreeXid(xid);
1710 1710 }
1711   - cifs_crypto_shash_release(server);
1712 1711 sesInfoFree(ses);
1713 1712 cifs_put_tcp_session(server);
1714 1713 }
1715 1714  
1716 1715  
... ... @@ -1788,23 +1787,13 @@
1788 1787 ses->linux_uid = volume_info->linux_uid;
1789 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 1790 mutex_lock(&ses->session_mutex);
1800 1791 rc = cifs_negotiate_protocol(xid, ses);
1801 1792 if (!rc)
1802 1793 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
1803 1794 mutex_unlock(&ses->session_mutex);
1804   - if (rc) {
1805   - cifs_crypto_shash_release(ses->server);
  1795 + if (rc)
1806 1796 goto get_ses_fail;
1807   - }
1808 1797  
1809 1798 /* success, put it on the list */
1810 1799 write_lock(&cifs_tcp_ses_lock);
... ... @@ -61,19 +61,6 @@
61 61 #define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000
62 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 64 /* Although typedefs are not commonly used for structure definitions */
78 65 /* in the Linux kernel, in this particular case they are useful */
79 66 /* to more closely match the standards document for NTLMSSP from */
... ... @@ -383,9 +383,6 @@
383 383 static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
384 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 386 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
390 387  
391 388 if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
... ... @@ -408,18 +405,6 @@
408 405 /* BB spec says that if AvId field of MsvAvTimestamp is populated then
409 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 408 return 0;
424 409 }
425 410  
426 411  
... ... @@ -466,12 +451,10 @@
466 451 struct cifsSesInfo *ses,
467 452 const struct nls_table *nls_cp, bool first)
468 453 {
469   - int rc;
470   - unsigned int size;
471 454 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
472 455 __u32 flags;
473 456 unsigned char *tmp;
474   - struct ntlmv2_resp ntlmv2_response = {};
  457 + char ntlm_session_key[CIFS_SESS_KEY_SIZE];
475 458  
476 459 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
477 460 sec_blob->MessageType = NtLmAuthenticate;
478 461  
479 462  
480 463  
... ... @@ -494,26 +477,20 @@
494 477 sec_blob->LmChallengeResponse.Length = 0;
495 478 sec_blob->LmChallengeResponse.MaximumLength = 0;
496 479  
497   - sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
498   - rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp);
499   - if (rc) {
500   - cERROR(1, "error rc: %d during ntlmssp ntlmv2 setup", rc);
501   - goto setup_ntlmv2_ret;
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;
  480 + /* calculate session key, BB what about adding similar ntlmv2 path? */
  481 + SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key);
  482 + if (first)
  483 + cifs_calculate_mac_key(&ses->server->mac_signing_key,
  484 + ntlm_session_key, ses->password);
511 485  
512   - sec_blob->NtChallengeResponse.Length = cpu_to_le16(size +
513   - ses->server->tilen);
  486 + memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE);
  487 + sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
  488 + sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE);
514 489 sec_blob->NtChallengeResponse.MaximumLength =
515   - cpu_to_le16(size + ses->server->tilen);
  490 + cpu_to_le16(CIFS_SESS_KEY_SIZE);
516 491  
  492 + tmp += CIFS_SESS_KEY_SIZE;
  493 +
517 494 if (ses->domainName == NULL) {
518 495 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
519 496 sec_blob->DomainName.Length = 0;
... ... @@ -524,6 +501,7 @@
524 501 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
525 502 MAX_USERNAME_SIZE, nls_cp);
526 503 len *= 2; /* unicode is 2 bytes each */
  504 + len += 2; /* trailing null */
527 505 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
528 506 sec_blob->DomainName.Length = cpu_to_le16(len);
529 507 sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
... ... @@ -540,6 +518,7 @@
540 518 len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
541 519 MAX_USERNAME_SIZE, nls_cp);
542 520 len *= 2; /* unicode is 2 bytes each */
  521 + len += 2; /* trailing null */
543 522 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
544 523 sec_blob->UserName.Length = cpu_to_le16(len);
545 524 sec_blob->UserName.MaximumLength = cpu_to_le16(len);
... ... @@ -551,26 +530,9 @@
551 530 sec_blob->WorkstationName.MaximumLength = 0;
552 531 tmp += 2;
553 532  
554   - if ((ses->server->ntlmssp.server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
555   - !calc_seckey(ses->server)) {
556   - memcpy(tmp, ses->server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE);
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   -
570   -setup_ntlmv2_ret:
571   - if (ses->server->tilen > 0)
572   - kfree(ses->server->tiblob);
573   -
  533 + sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
  534 + sec_blob->SessionKey.Length = 0;
  535 + sec_blob->SessionKey.MaximumLength = 0;
574 536 return tmp - pbuffer;
575 537 }
576 538  
577 539  
578 540  
... ... @@ -584,14 +546,15 @@
584 546 return;
585 547 }
586 548  
587   -static int setup_ntlmssp_auth_req(char *ntlmsspblob,
  549 +static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
588 550 struct cifsSesInfo *ses,
589 551 const struct nls_table *nls, bool first_time)
590 552 {
591 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 556 first_time);
  557 + pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen);
595 558  
596 559 return bloblen;
597 560 }
... ... @@ -617,7 +580,6 @@
617 580 struct key *spnego_key = NULL;
618 581 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
619 582 bool first_time;
620   - char *ntlmsspblob;
621 583  
622 584 if (ses == NULL)
623 585 return -EINVAL;
... ... @@ -728,7 +690,7 @@
728 690  
729 691 if (first_time) /* should this be moved into common code
730 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 694 ntlm_session_key, ses->password);
733 695 /* copy session key */
734 696  
735 697  
... ... @@ -767,21 +729,12 @@
767 729 cpu_to_le16(sizeof(struct ntlmv2_resp));
768 730  
769 731 /* calculate session key */
770   - rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
771   - if (rc) {
772   - kfree(v2_sess_key);
773   - goto ssetup_exit;
774   - }
  732 + setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
775 733 /* FIXME: calculate MAC key */
776 734 memcpy(bcc_ptr, (char *)v2_sess_key,
777 735 sizeof(struct ntlmv2_resp));
778 736 bcc_ptr += sizeof(struct ntlmv2_resp);
779 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 738 if (ses->capabilities & CAP_UNICODE) {
786 739 if (iov[0].iov_len % 2) {
787 740 *bcc_ptr = 0;
788 741  
... ... @@ -812,15 +765,15 @@
812 765 }
813 766 /* bail out if key is too long */
814 767 if (msg->sesskey_len >
815   - sizeof(ses->server->session_key.data.krb5)) {
  768 + sizeof(ses->server->mac_signing_key.data.krb5)) {
816 769 cERROR(1, "Kerberos signing key too long (%u bytes)",
817 770 msg->sesskey_len);
818 771 rc = -EOVERFLOW;
819 772 goto ssetup_exit;
820 773 }
821 774 if (first_time) {
822   - ses->server->session_key.len = msg->sesskey_len;
823   - memcpy(ses->server->session_key.data.krb5,
  775 + ses->server->mac_signing_key.len = msg->sesskey_len;
  776 + memcpy(ses->server->mac_signing_key.data.krb5,
824 777 msg->data, msg->sesskey_len);
825 778 }
826 779 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
827 780  
828 781  
... ... @@ -862,26 +815,12 @@
862 815 if (phase == NtLmNegotiate) {
863 816 setup_ntlmssp_neg_req(pSMB, ses);
864 817 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
865   - iov[1].iov_base = &pSMB->req.SecurityBlob[0];
866 818 } else if (phase == NtLmAuthenticate) {
867 819 int blob_len;
868   - ntlmsspblob = kmalloc(5 *
869   - sizeof(struct _AUTHENTICATE_MESSAGE),
870   - GFP_KERNEL);
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);
  820 + blob_len = setup_ntlmssp_auth_req(pSMB, ses,
  821 + nls_cp,
  822 + first_time);
881 823 iov[1].iov_len = blob_len;
882   - iov[1].iov_base = ntlmsspblob;
883   - pSMB->req.SecurityBlobLength =
884   - cpu_to_le16(blob_len);
885 824 /* Make sure that we tell the server that we
886 825 are using the uid that it just gave us back
887 826 on the response (challenge) */
... ... @@ -891,6 +830,7 @@
891 830 rc = -ENOSYS;
892 831 goto ssetup_exit;
893 832 }
  833 + iov[1].iov_base = &pSMB->req.SecurityBlob[0];
894 834 /* unicode strings must be word aligned */
895 835 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
896 836 *bcc_ptr = 0;
... ... @@ -543,7 +543,7 @@
543 543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
544 544 SECMODE_SIGN_ENABLED))) {
545 545 rc = cifs_verify_signature(midQ->resp_buf,
546   - ses->server,
  546 + &ses->server->mac_signing_key,
547 547 midQ->sequence_number+1);
548 548 if (rc) {
549 549 cERROR(1, "Unexpected SMB signature");
... ... @@ -731,7 +731,7 @@
731 731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
732 732 SECMODE_SIGN_ENABLED))) {
733 733 rc = cifs_verify_signature(out_buf,
734   - ses->server,
  734 + &ses->server->mac_signing_key,
735 735 midQ->sequence_number+1);
736 736 if (rc) {
737 737 cERROR(1, "Unexpected SMB signature");
... ... @@ -981,7 +981,7 @@
981 981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
982 982 SECMODE_SIGN_ENABLED))) {
983 983 rc = cifs_verify_signature(out_buf,
984   - ses->server,
  984 + &ses->server->mac_signing_key,
985 985 midQ->sequence_number+1);
986 986 if (rc) {
987 987 cERROR(1, "Unexpected SMB signature");