aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsencrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifsencrypt.c')
-rw-r--r--fs/cifs/cifsencrypt.c193
1 files changed, 72 insertions, 121 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 709f2296bdb4..eef78c24e0cc 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -45,38 +45,39 @@ extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
45static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 45static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
46 struct TCP_Server_Info *server, char *signature) 46 struct TCP_Server_Info *server, char *signature)
47{ 47{
48 int rc; 48 int rc = 0;
49 struct {
50 struct shash_desc shash;
51 char ctx[crypto_shash_descsize(server->ntlmssp.md5)];
52 } sdesc;
49 53
50 if (cifs_pdu == NULL || server == NULL || signature == NULL) 54 if (cifs_pdu == NULL || server == NULL || signature == NULL)
51 return -EINVAL; 55 return -EINVAL;
52 56
53 if (!server->ntlmssp.sdescmd5) { 57 sdesc.shash.tfm = server->ntlmssp.md5;
54 cERROR(1, 58 sdesc.shash.flags = 0x0;
55 "cifs_calculate_signature: can't generate signature\n");
56 return -1;
57 }
58 59
59 rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash); 60 rc = crypto_shash_init(&sdesc.shash);
60 if (rc) { 61 if (rc) {
61 cERROR(1, "cifs_calculate_signature: oould not init md5\n"); 62 cERROR(1, "could not initialize master crypto API hmacmd5\n");
62 return rc; 63 return rc;
63 } 64 }
64 65
65 if (server->secType == RawNTLMSSP) 66 if (server->secType == RawNTLMSSP)
66 crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 67 crypto_shash_update(&sdesc.shash,
67 server->session_key.data.ntlmv2.key, 68 server->session_key.data.ntlmv2.key,
68 CIFS_NTLMV2_SESSKEY_SIZE); 69 CIFS_NTLMV2_SESSKEY_SIZE);
69 else 70 else
70 crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 71 crypto_shash_update(&sdesc.shash,
71 (char *)&server->session_key.data, 72 (char *)&server->session_key.data,
72 server->session_key.len); 73 server->session_key.len);
73 74
74 crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 75 crypto_shash_update(&sdesc.shash,
75 cifs_pdu->Protocol, cifs_pdu->smb_buf_length); 76 cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
76 77
77 rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature); 78 rc = crypto_shash_final(&sdesc.shash, signature);
78 79
79 return rc; 80 return 0;
80} 81}
81 82
82 83
@@ -114,28 +115,30 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
114 struct TCP_Server_Info *server, char *signature) 115 struct TCP_Server_Info *server, char *signature)
115{ 116{
116 int i; 117 int i;
117 int rc; 118 int rc = 0;
119 struct {
120 struct shash_desc shash;
121 char ctx[crypto_shash_descsize(server->ntlmssp.md5)];
122 } sdesc;
118 123
119 if (iov == NULL || server == NULL || signature == NULL) 124 if (iov == NULL || server == NULL || signature == NULL)
120 return -EINVAL; 125 return -EINVAL;
121 126
122 if (!server->ntlmssp.sdescmd5) { 127 sdesc.shash.tfm = server->ntlmssp.md5;
123 cERROR(1, "cifs_calc_signature2: can't generate signature\n"); 128 sdesc.shash.flags = 0x0;
124 return -1;
125 }
126 129
127 rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash); 130 rc = crypto_shash_init(&sdesc.shash);
128 if (rc) { 131 if (rc) {
129 cERROR(1, "cifs_calc_signature2: oould not init md5\n"); 132 cERROR(1, "could not initialize master crypto API hmacmd5\n");
130 return rc; 133 return rc;
131 } 134 }
132 135
133 if (server->secType == RawNTLMSSP) 136 if (server->secType == RawNTLMSSP)
134 crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 137 crypto_shash_update(&sdesc.shash,
135 server->session_key.data.ntlmv2.key, 138 server->session_key.data.ntlmv2.key,
136 CIFS_NTLMV2_SESSKEY_SIZE); 139 CIFS_NTLMV2_SESSKEY_SIZE);
137 else 140 else
138 crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 141 crypto_shash_update(&sdesc.shash,
139 (char *)&server->session_key.data, 142 (char *)&server->session_key.data,
140 server->session_key.len); 143 server->session_key.len);
141 144
@@ -143,7 +146,7 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
143 if (iov[i].iov_len == 0) 146 if (iov[i].iov_len == 0)
144 continue; 147 continue;
145 if (iov[i].iov_base == NULL) { 148 if (iov[i].iov_base == NULL) {
146 cERROR(1, "cifs_calc_signature2: null iovec entry"); 149 cERROR(1, "null iovec entry");
147 return -EIO; 150 return -EIO;
148 } 151 }
149 /* The first entry includes a length field (which does not get 152 /* The first entry includes a length field (which does not get
@@ -151,16 +154,16 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
151 if (i == 0) { 154 if (i == 0) {
152 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 155 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
153 break; /* nothing to sign or corrupt header */ 156 break; /* nothing to sign or corrupt header */
154 crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 157 crypto_shash_update(&sdesc.shash,
155 iov[i].iov_base + 4, iov[i].iov_len - 4); 158 iov[i].iov_base + 4, iov[i].iov_len - 4);
156 } else 159 } else
157 crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 160 crypto_shash_update(&sdesc.shash,
158 iov[i].iov_base, iov[i].iov_len); 161 iov[i].iov_base, iov[i].iov_len);
159 } 162 }
160 163
161 rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature); 164 rc = crypto_shash_final(&sdesc.shash, signature);
162 165
163 return rc; 166 return 0;
164} 167}
165 168
166int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 169int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
@@ -310,48 +313,43 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
310 wchar_t *user; 313 wchar_t *user;
311 wchar_t *domain; 314 wchar_t *domain;
312 wchar_t *server; 315 wchar_t *server;
313 316 struct {
314 if (!ses->server->ntlmssp.sdeschmacmd5) { 317 struct shash_desc shash;
315 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); 318 char ctx[crypto_shash_descsize(ses->server->ntlmssp.hmacmd5)];
316 return -1; 319 } sdesc;
317 }
318 320
319 /* calculate md4 hash of password */ 321 /* calculate md4 hash of password */
320 E_md4hash(ses->password, nt_hash); 322 E_md4hash(ses->password, nt_hash);
321 323
324 sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5;
325 sdesc.shash.flags = 0x0;
326
322 crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash, 327 crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash,
323 CIFS_NTHASH_SIZE); 328 CIFS_NTHASH_SIZE);
324 329
325 rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash); 330 rc = crypto_shash_init(&sdesc.shash);
326 if (rc) { 331 if (rc) {
327 cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n"); 332 cERROR(1, "could not initialize master crypto API hmacmd5\n");
328 return rc; 333 return rc;
329 } 334 }
330 335
331 /* convert ses->userName to unicode and uppercase */ 336 /* convert ses->userName to unicode and uppercase */
332 len = strlen(ses->userName); 337 len = strlen(ses->userName);
333 user = kmalloc(2 + (len * 2), GFP_KERNEL); 338 user = kmalloc(2 + (len * 2), GFP_KERNEL);
334 if (user == NULL) { 339 if (user == NULL)
335 cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
336 rc = -ENOMEM;
337 goto calc_exit_2; 340 goto calc_exit_2;
338 }
339 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); 341 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
340 UniStrupr(user); 342 UniStrupr(user);
341 343
342 crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, 344 crypto_shash_update(&sdesc.shash, (char *)user, 2 * len);
343 (char *)user, 2 * len);
344 345
345 /* convert ses->domainName to unicode and uppercase */ 346 /* convert ses->domainName to unicode and uppercase */
346 if (ses->domainName) { 347 if (ses->domainName) {
347 len = strlen(ses->domainName); 348 len = strlen(ses->domainName);
348 349
349 domain = kmalloc(2 + (len * 2), GFP_KERNEL); 350 domain = kmalloc(2 + (len * 2), GFP_KERNEL);
350 if (domain == NULL) { 351 if (domain == NULL)
351 cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure");
352 rc = -ENOMEM;
353 goto calc_exit_1; 352 goto calc_exit_1;
354 }
355 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, 353 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
356 nls_cp); 354 nls_cp);
357 /* the following line was removed since it didn't work well 355 /* the following line was removed since it didn't work well
@@ -359,19 +357,15 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
359 Maybe converting the domain name earlier makes sense */ 357 Maybe converting the domain name earlier makes sense */
360 /* UniStrupr(domain); */ 358 /* UniStrupr(domain); */
361 359
362 crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, 360 crypto_shash_update(&sdesc.shash, (char *)domain, 2 * len);
363 (char *)domain, 2 * len);
364 361
365 kfree(domain); 362 kfree(domain);
366 } else if (ses->serverName) { 363 } else if (ses->serverName) {
367 len = strlen(ses->serverName); 364 len = strlen(ses->serverName);
368 365
369 server = kmalloc(2 + (len * 2), GFP_KERNEL); 366 server = kmalloc(2 + (len * 2), GFP_KERNEL);
370 if (server == NULL) { 367 if (server == NULL)
371 cERROR(1, "calc_ntlmv2_hash: server mem alloc failure");
372 rc = -ENOMEM;
373 goto calc_exit_1; 368 goto calc_exit_1;
374 }
375 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, 369 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
376 nls_cp); 370 nls_cp);
377 /* the following line was removed since it didn't work well 371 /* the following line was removed since it didn't work well
@@ -379,20 +373,16 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
379 Maybe converting the domain name earlier makes sense */ 373 Maybe converting the domain name earlier makes sense */
380 /* UniStrupr(domain); */ 374 /* UniStrupr(domain); */
381 375
382 crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, 376 crypto_shash_update(&sdesc.shash, (char *)server, 2 * len);
383 (char *)server, 2 * len);
384 377
385 kfree(server); 378 kfree(server);
386 } 379 }
387
388 rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash,
389 ses->server->ntlmv2_hash);
390
391calc_exit_1: 380calc_exit_1:
392 kfree(user); 381 kfree(user);
393calc_exit_2: 382calc_exit_2:
394 /* BB FIXME what about bytes 24 through 40 of the signing key? 383 /* BB FIXME what about bytes 24 through 40 of the signing key?
395 compare with the NTLM example */ 384 compare with the NTLM example */
385 rc = crypto_shash_final(&sdesc.shash, ses->server->ntlmv2_hash);
396 386
397 return rc; 387 return rc;
398} 388}
@@ -452,33 +442,34 @@ CalcNTLMv2_response(const struct TCP_Server_Info *server,
452 char *v2_session_response) 442 char *v2_session_response)
453{ 443{
454 int rc; 444 int rc;
445 struct {
446 struct shash_desc shash;
447 char ctx[crypto_shash_descsize(server->ntlmssp.hmacmd5)];
448 } sdesc;
455 449
456 if (!server->ntlmssp.sdeschmacmd5) { 450 sdesc.shash.tfm = server->ntlmssp.hmacmd5;
457 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); 451 sdesc.shash.flags = 0x0;
458 return -1;
459 }
460 452
461 crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash, 453 crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash,
462 CIFS_HMAC_MD5_HASH_SIZE); 454 CIFS_HMAC_MD5_HASH_SIZE);
463 455
464 rc = crypto_shash_init(&server->ntlmssp.sdeschmacmd5->shash); 456 rc = crypto_shash_init(&sdesc.shash);
465 if (rc) { 457 if (rc) {
466 cERROR(1, "CalcNTLMv2_response: could not init hmacmd5"); 458 cERROR(1, "could not initialize master crypto API hmacmd5\n");
467 return rc; 459 return rc;
468 } 460 }
469 461
470 memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, 462 memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE,
471 server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE); 463 server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE);
472 crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash, 464 crypto_shash_update(&sdesc.shash,
473 v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, 465 v2_session_response + CIFS_SERVER_CHALLENGE_SIZE,
474 sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE); 466 sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE);
475 467
476 if (server->tilen) 468 if (server->tilen)
477 crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash, 469 crypto_shash_update(&sdesc.shash,
478 server->tiblob, server->tilen); 470 server->tiblob, server->tilen);
479 471
480 rc = crypto_shash_final(&server->ntlmssp.sdeschmacmd5->shash, 472 rc = crypto_shash_final(&sdesc.shash, v2_session_response);
481 v2_session_response);
482 473
483 return rc; 474 return rc;
484} 475}
@@ -489,6 +480,10 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
489{ 480{
490 int rc = 0; 481 int rc = 0;
491 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; 482 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;
492 487
493 buf->blob_signature = cpu_to_le32(0x00000101); 488 buf->blob_signature = cpu_to_le32(0x00000101);
494 buf->reserved = 0; 489 buf->reserved = 0;
@@ -516,24 +511,21 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
516 return rc; 511 return rc;
517 } 512 }
518 513
519 if (!ses->server->ntlmssp.sdeschmacmd5) {
520 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
521 return -1;
522 }
523
524 crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, 514 crypto_shash_setkey(ses->server->ntlmssp.hmacmd5,
525 ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 515 ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
526 516
527 rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash); 517 sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5;
518 sdesc.shash.flags = 0x0;
519
520 rc = crypto_shash_init(&sdesc.shash);
528 if (rc) { 521 if (rc) {
529 cERROR(1, "setup_ntlmv2_rsp: could not init hmacmd5\n"); 522 cERROR(1, "could not initialize master crypto API hmacmd5\n");
530 return rc; 523 return rc;
531 } 524 }
532 525
533 crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, 526 crypto_shash_update(&sdesc.shash, resp_buf, CIFS_HMAC_MD5_HASH_SIZE);
534 resp_buf, CIFS_HMAC_MD5_HASH_SIZE);
535 527
536 rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash, 528 rc = crypto_shash_final(&sdesc.shash,
537 ses->server->session_key.data.ntlmv2.key); 529 ses->server->session_key.data.ntlmv2.key);
538 530
539 memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf, 531 memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf,
@@ -586,65 +578,24 @@ cifs_crypto_shash_release(struct TCP_Server_Info *server)
586 578
587 if (server->ntlmssp.hmacmd5) 579 if (server->ntlmssp.hmacmd5)
588 crypto_free_shash(server->ntlmssp.hmacmd5); 580 crypto_free_shash(server->ntlmssp.hmacmd5);
589
590 kfree(server->ntlmssp.sdeschmacmd5);
591
592 kfree(server->ntlmssp.sdescmd5);
593} 581}
594 582
595int 583int
596cifs_crypto_shash_allocate(struct TCP_Server_Info *server) 584cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
597{ 585{
598 int rc;
599 unsigned int size;
600
601 server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); 586 server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
602 if (!server->ntlmssp.hmacmd5 || 587 if (!server->ntlmssp.hmacmd5 ||
603 IS_ERR(server->ntlmssp.hmacmd5)) { 588 IS_ERR(server->ntlmssp.hmacmd5)) {
604 cERROR(1, "could not allocate crypto hmacmd5\n"); 589 cERROR(1, "could not allocate master crypto API hmacmd5\n");
605 return 1; 590 return 1;
606 } 591 }
607 592
608 server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0); 593 server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0);
609 if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) { 594 if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) {
610 cERROR(1, "could not allocate crypto md5\n"); 595 crypto_free_shash(server->ntlmssp.hmacmd5);
611 rc = 1; 596 cERROR(1, "could not allocate master crypto API md5\n");
612 goto cifs_crypto_shash_allocate_ret1; 597 return 1;
613 }
614
615 size = sizeof(struct shash_desc) +
616 crypto_shash_descsize(server->ntlmssp.hmacmd5);
617 server->ntlmssp.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
618 if (!server->ntlmssp.sdeschmacmd5) {
619 cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n");
620 rc = -ENOMEM;
621 goto cifs_crypto_shash_allocate_ret2;
622 }
623 server->ntlmssp.sdeschmacmd5->shash.tfm = server->ntlmssp.hmacmd5;
624 server->ntlmssp.sdeschmacmd5->shash.flags = 0x0;
625
626
627 size = sizeof(struct shash_desc) +
628 crypto_shash_descsize(server->ntlmssp.md5);
629 server->ntlmssp.sdescmd5 = kmalloc(size, GFP_KERNEL);
630 if (!server->ntlmssp.sdescmd5) {
631 cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n");
632 rc = -ENOMEM;
633 goto cifs_crypto_shash_allocate_ret3;
634 } 598 }
635 server->ntlmssp.sdescmd5->shash.tfm = server->ntlmssp.md5;
636 server->ntlmssp.sdescmd5->shash.flags = 0x0;
637 599
638 return 0; 600 return 0;
639
640cifs_crypto_shash_allocate_ret3:
641 kfree(server->ntlmssp.sdeschmacmd5);
642
643cifs_crypto_shash_allocate_ret2:
644 crypto_free_shash(server->ntlmssp.md5);
645
646cifs_crypto_shash_allocate_ret1:
647 crypto_free_shash(server->ntlmssp.hmacmd5);
648
649 return rc;
650} 601}