diff options
Diffstat (limited to 'fs/cifs/smb2transport.c')
-rw-r--r-- | fs/cifs/smb2transport.c | 90 |
1 files changed, 89 insertions, 1 deletions
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 | ||
42 | static int | ||
43 | smb2_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 | |||
70 | static int | ||
71 | smb3_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 | |||
42 | int | 113 | int |
43 | smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) | 114 | smb2_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__); |