aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsencrypt.c195
-rw-r--r--fs/cifs/cifsproto.h1
-rw-r--r--fs/cifs/connect.c6
-rw-r--r--fs/cifs/smb2transport.c90
4 files changed, 174 insertions, 118 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 3d8bf941d126..45e57cc38200 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,36 @@
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 return PTR_ERR(server->secmech.md5);
47 }
48
49 size = sizeof(struct shash_desc) +
50 crypto_shash_descsize(server->secmech.md5);
51 server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
52 if (!server->secmech.sdescmd5) {
53 rc = -ENOMEM;
54 crypto_free_shash(server->secmech.md5);
55 server->secmech.md5 = NULL;
56 return rc;
57 }
58 server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
59 server->secmech.sdescmd5->shash.flags = 0x0;
60
61 return 0;
62}
63
34/* 64/*
35 * Calculate and return the CIFS signature based on the mac key and SMB PDU. 65 * 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 66 * The 16 byte signature must be allocated by the caller. Note we only use the
@@ -50,8 +80,11 @@ static int cifs_calc_signature(struct smb_rqst *rqst,
50 return -EINVAL; 80 return -EINVAL;
51 81
52 if (!server->secmech.sdescmd5) { 82 if (!server->secmech.sdescmd5) {
53 cifs_dbg(VFS, "%s: Can't generate signature\n", __func__); 83 rc = cifs_crypto_shash_md5_allocate(server);
54 return -1; 84 if (rc) {
85 cifs_dbg(VFS, "%s: Can't alloc md5 crypto\n", __func__);
86 return -1;
87 }
55 } 88 }
56 89
57 rc = crypto_shash_init(&server->secmech.sdescmd5->shash); 90 rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
@@ -556,6 +589,33 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
556 return rc; 589 return rc;
557} 590}
558 591
592static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server)
593{
594 unsigned int size;
595
596 /* check if already allocated */
597 if (server->secmech.sdeschmacmd5)
598 return 0;
599
600 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
601 if (IS_ERR(server->secmech.hmacmd5)) {
602 cifs_dbg(VFS, "could not allocate crypto hmacmd5\n");
603 return PTR_ERR(server->secmech.hmacmd5);
604 }
605
606 size = sizeof(struct shash_desc) +
607 crypto_shash_descsize(server->secmech.hmacmd5);
608 server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
609 if (!server->secmech.sdeschmacmd5) {
610 crypto_free_shash(server->secmech.hmacmd5);
611 server->secmech.hmacmd5 = NULL;
612 return -ENOMEM;
613 }
614 server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
615 server->secmech.sdeschmacmd5->shash.flags = 0x0;
616
617 return 0;
618}
559 619
560int 620int
561setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) 621setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
@@ -606,6 +666,12 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
606 666
607 memcpy(ses->auth_key.response + baselen, tiblob, tilen); 667 memcpy(ses->auth_key.response + baselen, tiblob, tilen);
608 668
669 rc = crypto_hmacmd5_alloc(ses->server);
670 if (rc) {
671 cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc);
672 goto setup_ntlmv2_rsp_ret;
673 }
674
609 /* calculate ntlmv2_hash */ 675 /* calculate ntlmv2_hash */
610 rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp); 676 rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
611 if (rc) { 677 if (rc) {
@@ -705,123 +771,32 @@ calc_seckey(struct cifs_ses *ses)
705void 771void
706cifs_crypto_shash_release(struct TCP_Server_Info *server) 772cifs_crypto_shash_release(struct TCP_Server_Info *server)
707{ 773{
708 if (server->secmech.cmacaes) 774 if (server->secmech.cmacaes) {
709 crypto_free_shash(server->secmech.cmacaes); 775 crypto_free_shash(server->secmech.cmacaes);
776 server->secmech.cmacaes = NULL;
777 }
710 778
711 if (server->secmech.hmacsha256) 779 if (server->secmech.hmacsha256) {
712 crypto_free_shash(server->secmech.hmacsha256); 780 crypto_free_shash(server->secmech.hmacsha256);
781 server->secmech.hmacsha256 = NULL;
782 }
713 783
714 if (server->secmech.md5) 784 if (server->secmech.md5) {
715 crypto_free_shash(server->secmech.md5); 785 crypto_free_shash(server->secmech.md5);
786 server->secmech.md5 = NULL;
787 }
716 788
717 if (server->secmech.hmacmd5) 789 if (server->secmech.hmacmd5) {
718 crypto_free_shash(server->secmech.hmacmd5); 790 crypto_free_shash(server->secmech.hmacmd5);
791 server->secmech.hmacmd5 = NULL;
792 }
719 793
720 kfree(server->secmech.sdesccmacaes); 794 kfree(server->secmech.sdesccmacaes);
721 795 server->secmech.sdesccmacaes = NULL;
722 kfree(server->secmech.sdeschmacsha256); 796 kfree(server->secmech.sdeschmacsha256);
723 797 server->secmech.sdeschmacsha256 = NULL;
724 kfree(server->secmech.sdeschmacmd5); 798 kfree(server->secmech.sdeschmacmd5);
725 799 server->secmech.sdeschmacmd5 = NULL;
726 kfree(server->secmech.sdescmd5); 800 kfree(server->secmech.sdescmd5);
727} 801 server->secmech.sdescmd5 = NULL;
728
729int
730cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
731{
732 int rc;
733 unsigned int size;
734
735 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
736 if (IS_ERR(server->secmech.hmacmd5)) {
737 cifs_dbg(VFS, "could not allocate crypto hmacmd5\n");
738 return PTR_ERR(server->secmech.hmacmd5);
739 }
740
741 server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
742 if (IS_ERR(server->secmech.md5)) {
743 cifs_dbg(VFS, "could not allocate crypto md5\n");
744 rc = PTR_ERR(server->secmech.md5);
745 goto crypto_allocate_md5_fail;
746 }
747
748 server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
749 if (IS_ERR(server->secmech.hmacsha256)) {
750 cifs_dbg(VFS, "could not allocate crypto hmacsha256\n");
751 rc = PTR_ERR(server->secmech.hmacsha256);
752 goto crypto_allocate_hmacsha256_fail;
753 }
754
755 server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
756 if (IS_ERR(server->secmech.cmacaes)) {
757 cifs_dbg(VFS, "could not allocate crypto cmac-aes");
758 rc = PTR_ERR(server->secmech.cmacaes);
759 goto crypto_allocate_cmacaes_fail;
760 }
761
762 size = sizeof(struct shash_desc) +
763 crypto_shash_descsize(server->secmech.hmacmd5);
764 server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
765 if (!server->secmech.sdeschmacmd5) {
766 rc = -ENOMEM;
767 goto crypto_allocate_hmacmd5_sdesc_fail;
768 }
769 server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
770 server->secmech.sdeschmacmd5->shash.flags = 0x0;
771
772 size = sizeof(struct shash_desc) +
773 crypto_shash_descsize(server->secmech.md5);
774 server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
775 if (!server->secmech.sdescmd5) {
776 rc = -ENOMEM;
777 goto crypto_allocate_md5_sdesc_fail;
778 }
779 server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
780 server->secmech.sdescmd5->shash.flags = 0x0;
781
782 size = sizeof(struct shash_desc) +
783 crypto_shash_descsize(server->secmech.hmacsha256);
784 server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
785 if (!server->secmech.sdeschmacsha256) {
786 rc = -ENOMEM;
787 goto crypto_allocate_hmacsha256_sdesc_fail;
788 }
789 server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
790 server->secmech.sdeschmacsha256->shash.flags = 0x0;
791
792 size = sizeof(struct shash_desc) +
793 crypto_shash_descsize(server->secmech.cmacaes);
794 server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
795 if (!server->secmech.sdesccmacaes) {
796 cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
797 rc = -ENOMEM;
798 goto crypto_allocate_cmacaes_sdesc_fail;
799 }
800 server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
801 server->secmech.sdesccmacaes->shash.flags = 0x0;
802
803 return 0;
804
805crypto_allocate_cmacaes_sdesc_fail:
806 kfree(server->secmech.sdeschmacsha256);
807
808crypto_allocate_hmacsha256_sdesc_fail:
809 kfree(server->secmech.sdescmd5);
810
811crypto_allocate_md5_sdesc_fail:
812 kfree(server->secmech.sdeschmacmd5);
813
814crypto_allocate_hmacmd5_sdesc_fail:
815 crypto_free_shash(server->secmech.cmacaes);
816
817crypto_allocate_cmacaes_fail:
818 crypto_free_shash(server->secmech.hmacsha256);
819
820crypto_allocate_hmacsha256_fail:
821 crypto_free_shash(server->secmech.md5);
822
823crypto_allocate_md5_fail:
824 crypto_free_shash(server->secmech.hmacmd5);
825
826 return rc;
827} 802}
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index c8ff018fae68..f7e584d047e2 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -433,7 +433,6 @@ extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *,
433 const struct nls_table *); 433 const struct nls_table *);
434extern int setup_ntlm_response(struct cifs_ses *, const struct nls_table *); 434extern int setup_ntlm_response(struct cifs_ses *, const struct nls_table *);
435extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); 435extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
436extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
437extern void cifs_crypto_shash_release(struct TCP_Server_Info *); 436extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
438extern int calc_seckey(struct cifs_ses *); 437extern int calc_seckey(struct cifs_ses *);
439extern void generate_smb3signingkey(struct TCP_Server_Info *); 438extern void generate_smb3signingkey(struct TCP_Server_Info *);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index afcb8a1a33b7..fa68813396b5 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2108,12 +2108,6 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
2108 goto out_err; 2108 goto out_err;
2109 } 2109 }
2110 2110
2111 rc = cifs_crypto_shash_allocate(tcp_ses);
2112 if (rc) {
2113 cifs_dbg(VFS, "could not setup hash structures rc %d\n", rc);
2114 goto out_err;
2115 }
2116
2117 tcp_ses->ops = volume_info->ops; 2111 tcp_ses->ops = volume_info->ops;
2118 tcp_ses->vals = volume_info->vals; 2112 tcp_ses->vals = volume_info->vals;
2119 cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns)); 2113 cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
index 09b4fbaadeb6..301b191270b9 100644
--- a/fs/cifs/smb2transport.c
+++ b/fs/cifs/smb2transport.c
@@ -39,6 +39,77 @@
39#include "smb2status.h" 39#include "smb2status.h"
40#include "smb2glob.h" 40#include "smb2glob.h"
41 41
42static int
43smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
44{
45 unsigned int size;
46
47 if (server->secmech.sdeschmacsha256 != NULL)
48 return 0; /* already allocated */
49
50 server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
51 if (IS_ERR(server->secmech.hmacsha256)) {
52 cifs_dbg(VFS, "could not allocate crypto hmacsha256\n");
53 return PTR_ERR(server->secmech.hmacsha256);
54 }
55
56 size = sizeof(struct shash_desc) +
57 crypto_shash_descsize(server->secmech.hmacsha256);
58 server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
59 if (!server->secmech.sdeschmacsha256) {
60 crypto_free_shash(server->secmech.hmacsha256);
61 server->secmech.hmacsha256 = NULL;
62 return -ENOMEM;
63 }
64 server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
65 server->secmech.sdeschmacsha256->shash.flags = 0x0;
66
67 return 0;
68}
69
70static int
71smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
72{
73 unsigned int size;
74 int rc;
75
76 if (server->secmech.sdesccmacaes != NULL)
77 return 0; /* already allocated */
78
79 rc = smb2_crypto_shash_allocate(server);
80 if (rc)
81 return rc;
82
83 server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
84 if (IS_ERR(server->secmech.cmacaes)) {
85 cifs_dbg(VFS, "could not allocate crypto cmac-aes");
86 kfree(server->secmech.sdeschmacsha256);
87 server->secmech.sdeschmacsha256 = NULL;
88 crypto_free_shash(server->secmech.hmacsha256);
89 server->secmech.hmacsha256 = NULL;
90 return PTR_ERR(server->secmech.cmacaes);
91 }
92
93 size = sizeof(struct shash_desc) +
94 crypto_shash_descsize(server->secmech.cmacaes);
95 server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
96 if (!server->secmech.sdesccmacaes) {
97 cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
98 kfree(server->secmech.sdeschmacsha256);
99 server->secmech.sdeschmacsha256 = NULL;
100 crypto_free_shash(server->secmech.hmacsha256);
101 crypto_free_shash(server->secmech.cmacaes);
102 server->secmech.hmacsha256 = NULL;
103 server->secmech.cmacaes = NULL;
104 return -ENOMEM;
105 }
106 server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
107 server->secmech.sdesccmacaes->shash.flags = 0x0;
108
109 return 0;
110}
111
112
42int 113int
43smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) 114smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
44{ 115{
@@ -52,6 +123,12 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
52 memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE); 123 memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
53 memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE); 124 memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
54 125
126 rc = smb2_crypto_shash_allocate(server);
127 if (rc) {
128 cifs_dbg(VFS, "%s: shah256 alloc failed\n", __func__);
129 return rc;
130 }
131
55 rc = crypto_shash_setkey(server->secmech.hmacsha256, 132 rc = crypto_shash_setkey(server->secmech.hmacsha256,
56 server->session_key.response, SMB2_NTLMV2_SESSKEY_SIZE); 133 server->session_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
57 if (rc) { 134 if (rc) {
@@ -61,7 +138,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
61 138
62 rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash); 139 rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
63 if (rc) { 140 if (rc) {
64 cifs_dbg(VFS, "%s: Could not init md5\n", __func__); 141 cifs_dbg(VFS, "%s: Could not init sha256", __func__);
65 return rc; 142 return rc;
66 } 143 }
67 144
@@ -129,6 +206,12 @@ generate_smb3signingkey(struct TCP_Server_Info *server)
129 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE); 206 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
130 memset(server->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE); 207 memset(server->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE);
131 208
209 rc = smb3_crypto_shash_allocate(server);
210 if (rc) {
211 cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
212 goto smb3signkey_ret;
213 }
214
132 rc = crypto_shash_setkey(server->secmech.hmacsha256, 215 rc = crypto_shash_setkey(server->secmech.hmacsha256,
133 server->session_key.response, SMB2_NTLMV2_SESSKEY_SIZE); 216 server->session_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
134 if (rc) { 217 if (rc) {
@@ -210,6 +293,11 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
210 return rc; 293 return rc;
211 } 294 }
212 295
296 /*
297 * we already allocate sdesccmacaes when we init smb3 signing key,
298 * so unlike smb2 case we do not have to check here if secmech are
299 * initialized
300 */
213 rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash); 301 rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash);
214 if (rc) { 302 if (rc) {
215 cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__); 303 cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);