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.c189
1 files changed, 98 insertions, 91 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 71436d1fca13..fc6f4f3a1a9d 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsencrypt.c 2 * fs/cifs/cifsencrypt.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2005,2006 4 * Copyright (C) International Business Machines Corp., 2005,2013
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -31,6 +31,37 @@
31#include <linux/random.h> 31#include <linux/random.h>
32#include <linux/highmem.h> 32#include <linux/highmem.h>
33 33
34static int
35cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server)
36{
37 int rc;
38 unsigned int size;
39
40 if (server->secmech.sdescmd5 != NULL)
41 return 0; /* already allocated */
42
43 server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
44 if (IS_ERR(server->secmech.md5)) {
45 cifs_dbg(VFS, "could not allocate crypto md5\n");
46 rc = PTR_ERR(server->secmech.md5);
47 server->secmech.md5 = NULL;
48 return rc;
49 }
50
51 size = sizeof(struct shash_desc) +
52 crypto_shash_descsize(server->secmech.md5);
53 server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
54 if (!server->secmech.sdescmd5) {
55 crypto_free_shash(server->secmech.md5);
56 server->secmech.md5 = NULL;
57 return -ENOMEM;
58 }
59 server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
60 server->secmech.sdescmd5->shash.flags = 0x0;
61
62 return 0;
63}
64
34/* 65/*
35 * Calculate and return the CIFS signature based on the mac key and SMB PDU. 66 * Calculate and return the CIFS signature based on the mac key and SMB PDU.
36 * The 16 byte signature must be allocated by the caller. Note we only use the 67 * The 16 byte signature must be allocated by the caller. Note we only use the
@@ -50,8 +81,11 @@ static int cifs_calc_signature(struct smb_rqst *rqst,
50 return -EINVAL; 81 return -EINVAL;
51 82
52 if (!server->secmech.sdescmd5) { 83 if (!server->secmech.sdescmd5) {
53 cifs_dbg(VFS, "%s: Can't generate signature\n", __func__); 84 rc = cifs_crypto_shash_md5_allocate(server);
54 return -1; 85 if (rc) {
86 cifs_dbg(VFS, "%s: Can't alloc md5 crypto\n", __func__);
87 return -1;
88 }
55 } 89 }
56 90
57 rc = crypto_shash_init(&server->secmech.sdescmd5->shash); 91 rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
@@ -276,7 +310,6 @@ int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
276 strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE); 310 strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
277 311
278 if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) { 312 if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
279 memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE);
280 memcpy(lnm_session_key, password_with_pad, 313 memcpy(lnm_session_key, password_with_pad,
281 CIFS_ENCPWD_SIZE); 314 CIFS_ENCPWD_SIZE);
282 return 0; 315 return 0;
@@ -389,7 +422,7 @@ find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
389 if (blobptr + attrsize > blobend) 422 if (blobptr + attrsize > blobend)
390 break; 423 break;
391 if (type == NTLMSSP_AV_NB_DOMAIN_NAME) { 424 if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
392 if (!attrsize) 425 if (!attrsize || attrsize >= CIFS_MAX_DOMAINNAME_LEN)
393 break; 426 break;
394 if (!ses->domainName) { 427 if (!ses->domainName) {
395 ses->domainName = 428 ses->domainName =
@@ -414,7 +447,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
414 int rc = 0; 447 int rc = 0;
415 int len; 448 int len;
416 char nt_hash[CIFS_NTHASH_SIZE]; 449 char nt_hash[CIFS_NTHASH_SIZE];
417 wchar_t *user; 450 __le16 *user;
418 wchar_t *domain; 451 wchar_t *domain;
419 wchar_t *server; 452 wchar_t *server;
420 453
@@ -439,7 +472,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
439 return rc; 472 return rc;
440 } 473 }
441 474
442 /* convert ses->user_name to unicode and uppercase */ 475 /* convert ses->user_name to unicode */
443 len = ses->user_name ? strlen(ses->user_name) : 0; 476 len = ses->user_name ? strlen(ses->user_name) : 0;
444 user = kmalloc(2 + (len * 2), GFP_KERNEL); 477 user = kmalloc(2 + (len * 2), GFP_KERNEL);
445 if (user == NULL) { 478 if (user == NULL) {
@@ -448,7 +481,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
448 } 481 }
449 482
450 if (len) { 483 if (len) {
451 len = cifs_strtoUTF16((__le16 *)user, ses->user_name, len, nls_cp); 484 len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp);
452 UniStrupr(user); 485 UniStrupr(user);
453 } else { 486 } else {
454 memset(user, '\0', 2); 487 memset(user, '\0', 2);
@@ -536,7 +569,7 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
536 return rc; 569 return rc;
537 } 570 }
538 571
539 if (ses->server->secType == RawNTLMSSP) 572 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED)
540 memcpy(ses->auth_key.response + offset, 573 memcpy(ses->auth_key.response + offset,
541 ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 574 ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
542 else 575 else
@@ -557,6 +590,36 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
557 return rc; 590 return rc;
558} 591}
559 592
593static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server)
594{
595 int rc;
596 unsigned int size;
597
598 /* check if already allocated */
599 if (server->secmech.sdeschmacmd5)
600 return 0;
601
602 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
603 if (IS_ERR(server->secmech.hmacmd5)) {
604 cifs_dbg(VFS, "could not allocate crypto hmacmd5\n");
605 rc = PTR_ERR(server->secmech.hmacmd5);
606 server->secmech.hmacmd5 = NULL;
607 return rc;
608 }
609
610 size = sizeof(struct shash_desc) +
611 crypto_shash_descsize(server->secmech.hmacmd5);
612 server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
613 if (!server->secmech.sdeschmacmd5) {
614 crypto_free_shash(server->secmech.hmacmd5);
615 server->secmech.hmacmd5 = NULL;
616 return -ENOMEM;
617 }
618 server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
619 server->secmech.sdeschmacmd5->shash.flags = 0x0;
620
621 return 0;
622}
560 623
561int 624int
562setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) 625setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
@@ -568,7 +631,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
568 char ntlmv2_hash[16]; 631 char ntlmv2_hash[16];
569 unsigned char *tiblob = NULL; /* target info blob */ 632 unsigned char *tiblob = NULL; /* target info blob */
570 633
571 if (ses->server->secType == RawNTLMSSP) { 634 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
572 if (!ses->domainName) { 635 if (!ses->domainName) {
573 rc = find_domain_name(ses, nls_cp); 636 rc = find_domain_name(ses, nls_cp);
574 if (rc) { 637 if (rc) {
@@ -607,6 +670,12 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
607 670
608 memcpy(ses->auth_key.response + baselen, tiblob, tilen); 671 memcpy(ses->auth_key.response + baselen, tiblob, tilen);
609 672
673 rc = crypto_hmacmd5_alloc(ses->server);
674 if (rc) {
675 cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc);
676 goto setup_ntlmv2_rsp_ret;
677 }
678
610 /* calculate ntlmv2_hash */ 679 /* calculate ntlmv2_hash */
611 rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp); 680 rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
612 if (rc) { 681 if (rc) {
@@ -706,94 +775,32 @@ calc_seckey(struct cifs_ses *ses)
706void 775void
707cifs_crypto_shash_release(struct TCP_Server_Info *server) 776cifs_crypto_shash_release(struct TCP_Server_Info *server)
708{ 777{
709 if (server->secmech.hmacsha256) 778 if (server->secmech.cmacaes) {
710 crypto_free_shash(server->secmech.hmacsha256); 779 crypto_free_shash(server->secmech.cmacaes);
711 780 server->secmech.cmacaes = NULL;
712 if (server->secmech.md5)
713 crypto_free_shash(server->secmech.md5);
714
715 if (server->secmech.hmacmd5)
716 crypto_free_shash(server->secmech.hmacmd5);
717
718 kfree(server->secmech.sdeschmacsha256);
719
720 kfree(server->secmech.sdeschmacmd5);
721
722 kfree(server->secmech.sdescmd5);
723}
724
725int
726cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
727{
728 int rc;
729 unsigned int size;
730
731 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
732 if (IS_ERR(server->secmech.hmacmd5)) {
733 cifs_dbg(VFS, "could not allocate crypto hmacmd5\n");
734 return PTR_ERR(server->secmech.hmacmd5);
735 }
736
737 server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
738 if (IS_ERR(server->secmech.md5)) {
739 cifs_dbg(VFS, "could not allocate crypto md5\n");
740 rc = PTR_ERR(server->secmech.md5);
741 goto crypto_allocate_md5_fail;
742 } 781 }
743 782
744 server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0); 783 if (server->secmech.hmacsha256) {
745 if (IS_ERR(server->secmech.hmacsha256)) { 784 crypto_free_shash(server->secmech.hmacsha256);
746 cifs_dbg(VFS, "could not allocate crypto hmacsha256\n"); 785 server->secmech.hmacsha256 = NULL;
747 rc = PTR_ERR(server->secmech.hmacsha256);
748 goto crypto_allocate_hmacsha256_fail;
749 }
750
751 size = sizeof(struct shash_desc) +
752 crypto_shash_descsize(server->secmech.hmacmd5);
753 server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
754 if (!server->secmech.sdeschmacmd5) {
755 rc = -ENOMEM;
756 goto crypto_allocate_hmacmd5_sdesc_fail;
757 } 786 }
758 server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
759 server->secmech.sdeschmacmd5->shash.flags = 0x0;
760 787
761 size = sizeof(struct shash_desc) + 788 if (server->secmech.md5) {
762 crypto_shash_descsize(server->secmech.md5); 789 crypto_free_shash(server->secmech.md5);
763 server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL); 790 server->secmech.md5 = NULL;
764 if (!server->secmech.sdescmd5) {
765 rc = -ENOMEM;
766 goto crypto_allocate_md5_sdesc_fail;
767 } 791 }
768 server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
769 server->secmech.sdescmd5->shash.flags = 0x0;
770 792
771 size = sizeof(struct shash_desc) + 793 if (server->secmech.hmacmd5) {
772 crypto_shash_descsize(server->secmech.hmacsha256); 794 crypto_free_shash(server->secmech.hmacmd5);
773 server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL); 795 server->secmech.hmacmd5 = NULL;
774 if (!server->secmech.sdeschmacsha256) {
775 rc = -ENOMEM;
776 goto crypto_allocate_hmacsha256_sdesc_fail;
777 } 796 }
778 server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
779 server->secmech.sdeschmacsha256->shash.flags = 0x0;
780
781 return 0;
782
783crypto_allocate_hmacsha256_sdesc_fail:
784 kfree(server->secmech.sdescmd5);
785 797
786crypto_allocate_md5_sdesc_fail: 798 kfree(server->secmech.sdesccmacaes);
799 server->secmech.sdesccmacaes = NULL;
800 kfree(server->secmech.sdeschmacsha256);
801 server->secmech.sdeschmacsha256 = NULL;
787 kfree(server->secmech.sdeschmacmd5); 802 kfree(server->secmech.sdeschmacmd5);
788 803 server->secmech.sdeschmacmd5 = NULL;
789crypto_allocate_hmacmd5_sdesc_fail: 804 kfree(server->secmech.sdescmd5);
790 crypto_free_shash(server->secmech.hmacsha256); 805 server->secmech.sdescmd5 = NULL;
791
792crypto_allocate_hmacsha256_fail:
793 crypto_free_shash(server->secmech.md5);
794
795crypto_allocate_md5_fail:
796 crypto_free_shash(server->secmech.hmacmd5);
797
798 return rc;
799} 806}