blob: 20cc79e5c15d5152a98f95b13c8a7103c54b603f [file] [log] [blame]
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +04001/*
2 * fs/cifs/smb2transport.c
3 *
4 * Copyright (C) International Business Machines Corp., 2002, 2011
5 * Etersoft, 2012
6 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Jeremy Allison (jra@samba.org) 2006
8 * Pavel Shilovsky (pshilovsky@samba.org) 2012
9 *
10 * This library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published
12 * by the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
18 * the GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/fs.h>
26#include <linux/list.h>
27#include <linux/wait.h>
28#include <linux/net.h>
29#include <linux/delay.h>
30#include <linux/uaccess.h>
31#include <asm/processor.h>
32#include <linux/mempool.h>
Jeff Laytonfb308a62012-09-18 16:20:35 -070033#include <linux/highmem.h>
Pavel Shilovsky026e93d2016-11-03 16:47:37 -070034#include <crypto/aead.h>
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +040035#include "smb2pdu.h"
36#include "cifsglob.h"
37#include "cifsproto.h"
38#include "smb2proto.h"
39#include "cifs_debug.h"
40#include "smb2status.h"
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -070041#include "smb2glob.h"
42
Steve French95dc8dd2013-07-04 10:35:21 -050043static int
44smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
45{
Aurelien Aptel82fb82b2018-02-16 19:19:27 +010046 return cifs_alloc_hash("hmac(sha256)",
47 &server->secmech.hmacsha256,
48 &server->secmech.sdeschmacsha256);
Steve French95dc8dd2013-07-04 10:35:21 -050049}
50
51static int
52smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
53{
Aurelien Aptel82fb82b2018-02-16 19:19:27 +010054 struct cifs_secmech *p = &server->secmech;
Steve French95dc8dd2013-07-04 10:35:21 -050055 int rc;
56
Aurelien Aptel82fb82b2018-02-16 19:19:27 +010057 rc = cifs_alloc_hash("hmac(sha256)",
58 &p->hmacsha256,
59 &p->sdeschmacsha256);
Steve French95dc8dd2013-07-04 10:35:21 -050060 if (rc)
Aurelien Aptel82fb82b2018-02-16 19:19:27 +010061 goto err;
Steve French95dc8dd2013-07-04 10:35:21 -050062
Aurelien Aptel82fb82b2018-02-16 19:19:27 +010063 rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
64 if (rc)
65 goto err;
Steve French95dc8dd2013-07-04 10:35:21 -050066
67 return 0;
Aurelien Aptel82fb82b2018-02-16 19:19:27 +010068err:
69 cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
70 return rc;
Steve French95dc8dd2013-07-04 10:35:21 -050071}
72
Aurelien Aptel5fcd7f32018-02-16 19:19:28 +010073int
74smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
75{
76 struct cifs_secmech *p = &server->secmech;
77 int rc = 0;
78
79 rc = cifs_alloc_hash("hmac(sha256)",
80 &p->hmacsha256,
81 &p->sdeschmacsha256);
82 if (rc)
83 return rc;
84
85 rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
86 if (rc)
87 goto err;
88
89 rc = cifs_alloc_hash("sha512", &p->sha512, &p->sdescsha512);
90 if (rc)
91 goto err;
92
93 return 0;
94
95err:
96 cifs_free_hash(&p->cmacaes, &p->sdesccmacaes);
97 cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
98 return rc;
99}
Aurelien Aptel5fcd7f32018-02-16 19:19:28 +0100100
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200101
102static
103int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
104{
105 struct cifs_chan *chan;
106 struct cifs_ses *ses = NULL;
Aurelien Aptelcc95b672020-02-06 13:49:26 +0100107 struct TCP_Server_Info *it = NULL;
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200108 int i;
109 int rc = 0;
110
111 spin_lock(&cifs_tcp_ses_lock);
112
Aurelien Aptelcc95b672020-02-06 13:49:26 +0100113 list_for_each_entry(it, &cifs_tcp_ses_list, tcp_ses_list) {
114 list_for_each_entry(ses, &it->smb_ses_list, smb_ses_list) {
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200115 if (ses->Suid == ses_id)
116 goto found;
117 }
118 }
119 cifs_server_dbg(VFS, "%s: Could not find session 0x%llx\n",
120 __func__, ses_id);
121 rc = -ENOENT;
122 goto out;
123
124found:
125 if (ses->binding) {
126 /*
127 * If we are in the process of binding a new channel
128 * to an existing session, use the master connection
129 * session key
130 */
131 memcpy(key, ses->smb3signingkey, SMB3_SIGN_KEY_SIZE);
132 goto out;
133 }
134
135 /*
136 * Otherwise, use the channel key.
137 */
138
139 for (i = 0; i < ses->chan_count; i++) {
140 chan = ses->chans + i;
141 if (chan->server == server) {
142 memcpy(key, chan->signkey, SMB3_SIGN_KEY_SIZE);
143 goto out;
144 }
145 }
146
147 cifs_dbg(VFS,
148 "%s: Could not find channel signing key for session 0x%llx\n",
149 __func__, ses_id);
150 rc = -ENOENT;
151
152out:
153 spin_unlock(&cifs_tcp_ses_lock);
154 return rc;
155}
156
Sachin Prabhu38bd4902017-03-03 15:41:38 -0800157static struct cifs_ses *
158smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
159{
160 struct cifs_ses *ses;
161
162 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
163 if (ses->Suid != ses_id)
164 continue;
165 return ses;
166 }
167
168 return NULL;
169}
170
Pavel Shilovsky026e93d2016-11-03 16:47:37 -0700171struct cifs_ses *
172smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500173{
174 struct cifs_ses *ses;
175
176 spin_lock(&cifs_tcp_ses_lock);
Sachin Prabhu38bd4902017-03-03 15:41:38 -0800177 ses = smb2_find_smb_ses_unlocked(server, ses_id);
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500178 spin_unlock(&cifs_tcp_ses_lock);
179
Sachin Prabhu38bd4902017-03-03 15:41:38 -0800180 return ses;
181}
182
183static struct cifs_tcon *
184smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32 tid)
185{
186 struct cifs_tcon *tcon;
187
188 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
189 if (tcon->tid != tid)
190 continue;
191 ++tcon->tc_count;
192 return tcon;
193 }
194
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500195 return NULL;
196}
197
Sachin Prabhu38bd4902017-03-03 15:41:38 -0800198/*
199 * Obtain tcon corresponding to the tid in the given
200 * cifs_ses
201 */
202
203struct cifs_tcon *
204smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid)
205{
206 struct cifs_ses *ses;
207 struct cifs_tcon *tcon;
208
209 spin_lock(&cifs_tcp_ses_lock);
210 ses = smb2_find_smb_ses_unlocked(server, ses_id);
211 if (!ses) {
212 spin_unlock(&cifs_tcp_ses_lock);
213 return NULL;
214 }
215 tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
216 spin_unlock(&cifs_tcp_ses_lock);
217
218 return tcon;
219}
220
Steve French38107d42012-12-08 22:08:06 -0600221int
Jeff Layton0b688cf2012-09-18 16:20:34 -0700222smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700223{
Al Viro16c568e2015-11-12 22:46:49 -0500224 int rc;
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700225 unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
226 unsigned char *sigptr = smb2_signature;
Jeff Layton0b688cf2012-09-18 16:20:34 -0700227 struct kvec *iov = rqst->rq_iov;
Ronnie Sahlbergc713c872018-06-12 08:00:58 +1000228 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500229 struct cifs_ses *ses;
Aurelien Aptela5c62f42018-08-02 16:39:52 +0200230 struct shash_desc *shash;
Paulo Alcantara8de8c462018-06-23 14:52:24 -0300231 struct smb_rqst drqst;
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500232
Pavel Shilovsky026e93d2016-11-03 16:47:37 -0700233 ses = smb2_find_smb_ses(server, shdr->SessionId);
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500234 if (!ses) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000235 cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500236 return 0;
237 }
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700238
239 memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700240 memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700241
Steve French95dc8dd2013-07-04 10:35:21 -0500242 rc = smb2_crypto_shash_allocate(server);
243 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000244 cifs_server_dbg(VFS, "%s: sha256 alloc failed\n", __func__);
Steve French95dc8dd2013-07-04 10:35:21 -0500245 return rc;
246 }
247
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700248 rc = crypto_shash_setkey(server->secmech.hmacsha256,
Paulo Alcantara8de8c462018-06-23 14:52:24 -0300249 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700250 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000251 cifs_server_dbg(VFS, "%s: Could not update with response\n", __func__);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700252 return rc;
253 }
254
Aurelien Aptela5c62f42018-08-02 16:39:52 +0200255 shash = &server->secmech.sdeschmacsha256->shash;
Paulo Alcantara8de8c462018-06-23 14:52:24 -0300256 rc = crypto_shash_init(shash);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700257 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000258 cifs_server_dbg(VFS, "%s: Could not init sha256", __func__);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700259 return rc;
260 }
261
Paulo Alcantara8de8c462018-06-23 14:52:24 -0300262 /*
263 * For SMB2+, __cifs_calc_signature() expects to sign only the actual
264 * data, that is, iov[0] should not contain a rfc1002 length.
265 *
266 * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
267 * __cifs_calc_signature().
268 */
269 drqst = *rqst;
270 if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
271 rc = crypto_shash_update(shash, iov[0].iov_base,
272 iov[0].iov_len);
273 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000274 cifs_server_dbg(VFS, "%s: Could not update with payload\n",
Paulo Alcantara8de8c462018-06-23 14:52:24 -0300275 __func__);
276 return rc;
277 }
278 drqst.rq_iov++;
279 drqst.rq_nvec--;
280 }
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700281
Paulo Alcantara8de8c462018-06-23 14:52:24 -0300282 rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
Al Viro16c568e2015-11-12 22:46:49 -0500283 if (!rc)
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700284 memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700285
286 return rc;
287}
288
Steve French373512e2015-12-18 13:05:30 -0600289static int generate_key(struct cifs_ses *ses, struct kvec label,
290 struct kvec context, __u8 *key, unsigned int key_size)
Steve French429b46f2013-06-26 23:45:05 -0500291{
292 unsigned char zero = 0x0;
293 __u8 i[4] = {0, 0, 0, 1};
294 __u8 L[4] = {0, 0, 0, 128};
295 int rc = 0;
296 unsigned char prfhash[SMB2_HMACSHA256_SIZE];
297 unsigned char *hashptr = prfhash;
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000298 struct TCP_Server_Info *server = ses->server;
Steve French429b46f2013-06-26 23:45:05 -0500299
300 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
Steve French373512e2015-12-18 13:05:30 -0600301 memset(key, 0x0, key_size);
Steve French429b46f2013-06-26 23:45:05 -0500302
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000303 rc = smb3_crypto_shash_allocate(server);
Steve French95dc8dd2013-07-04 10:35:21 -0500304 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000305 cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__);
Steve French95dc8dd2013-07-04 10:35:21 -0500306 goto smb3signkey_ret;
307 }
308
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000309 rc = crypto_shash_setkey(server->secmech.hmacsha256,
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500310 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
Steve French429b46f2013-06-26 23:45:05 -0500311 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000312 cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__);
Steve French429b46f2013-06-26 23:45:05 -0500313 goto smb3signkey_ret;
314 }
315
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000316 rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
Steve French429b46f2013-06-26 23:45:05 -0500317 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000318 cifs_server_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
Steve French429b46f2013-06-26 23:45:05 -0500319 goto smb3signkey_ret;
320 }
321
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000322 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
Steve French429b46f2013-06-26 23:45:05 -0500323 i, 4);
324 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000325 cifs_server_dbg(VFS, "%s: Could not update with n\n", __func__);
Steve French429b46f2013-06-26 23:45:05 -0500326 goto smb3signkey_ret;
327 }
328
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000329 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
Steve French373512e2015-12-18 13:05:30 -0600330 label.iov_base, label.iov_len);
Steve French429b46f2013-06-26 23:45:05 -0500331 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000332 cifs_server_dbg(VFS, "%s: Could not update with label\n", __func__);
Steve French429b46f2013-06-26 23:45:05 -0500333 goto smb3signkey_ret;
334 }
335
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000336 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
Steve French429b46f2013-06-26 23:45:05 -0500337 &zero, 1);
338 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000339 cifs_server_dbg(VFS, "%s: Could not update with zero\n", __func__);
Steve French429b46f2013-06-26 23:45:05 -0500340 goto smb3signkey_ret;
341 }
342
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000343 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
Steve French373512e2015-12-18 13:05:30 -0600344 context.iov_base, context.iov_len);
Steve French429b46f2013-06-26 23:45:05 -0500345 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000346 cifs_server_dbg(VFS, "%s: Could not update with context\n", __func__);
Steve French429b46f2013-06-26 23:45:05 -0500347 goto smb3signkey_ret;
348 }
349
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000350 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
Steve French429b46f2013-06-26 23:45:05 -0500351 L, 4);
352 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000353 cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__);
Steve French429b46f2013-06-26 23:45:05 -0500354 goto smb3signkey_ret;
355 }
356
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000357 rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash,
Steve French429b46f2013-06-26 23:45:05 -0500358 hashptr);
359 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000360 cifs_server_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
Steve French429b46f2013-06-26 23:45:05 -0500361 goto smb3signkey_ret;
362 }
363
Steve French373512e2015-12-18 13:05:30 -0600364 memcpy(key, hashptr, key_size);
Steve French429b46f2013-06-26 23:45:05 -0500365
366smb3signkey_ret:
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500367 return rc;
Steve French429b46f2013-06-26 23:45:05 -0500368}
369
Steve French373512e2015-12-18 13:05:30 -0600370struct derivation {
371 struct kvec label;
372 struct kvec context;
373};
374
375struct derivation_triplet {
376 struct derivation signing;
377 struct derivation encryption;
378 struct derivation decryption;
379};
380
381static int
382generate_smb3signingkey(struct cifs_ses *ses,
383 const struct derivation_triplet *ptriplet)
384{
385 int rc;
386
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200387 /*
388 * All channels use the same encryption/decryption keys but
389 * they have their own signing key.
390 *
391 * When we generate the keys, check if it is for a new channel
392 * (binding) in which case we only need to generate a signing
393 * key and store it in the channel as to not overwrite the
394 * master connection signing key stored in the session
395 */
Steve French373512e2015-12-18 13:05:30 -0600396
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200397 if (ses->binding) {
398 rc = generate_key(ses, ptriplet->signing.label,
399 ptriplet->signing.context,
400 cifs_ses_binding_channel(ses)->signkey,
401 SMB3_SIGN_KEY_SIZE);
402 if (rc)
403 return rc;
404 } else {
405 rc = generate_key(ses, ptriplet->signing.label,
406 ptriplet->signing.context,
407 ses->smb3signingkey,
408 SMB3_SIGN_KEY_SIZE);
409 if (rc)
410 return rc;
Paulo Alcantara (SUSE)ff6b6f32019-11-22 12:30:57 -0300411
412 memcpy(ses->chans[0].signkey, ses->smb3signingkey,
413 SMB3_SIGN_KEY_SIZE);
414
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200415 rc = generate_key(ses, ptriplet->encryption.label,
416 ptriplet->encryption.context,
417 ses->smb3encryptionkey,
418 SMB3_SIGN_KEY_SIZE);
419 rc = generate_key(ses, ptriplet->decryption.label,
420 ptriplet->decryption.context,
421 ses->smb3decryptionkey,
422 SMB3_SIGN_KEY_SIZE);
423 if (rc)
424 return rc;
425 }
Aurélien Apteld38de3c62017-05-24 16:13:25 +0200426
427 if (rc)
428 return rc;
429
430#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
431 cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__);
432 /*
433 * The session id is opaque in terms of endianness, so we can't
434 * print it as a long long. we dump it as we got it on the wire
435 */
436 cifs_dbg(VFS, "Session Id %*ph\n", (int)sizeof(ses->Suid),
437 &ses->Suid);
438 cifs_dbg(VFS, "Session Key %*ph\n",
439 SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
440 cifs_dbg(VFS, "Signing Key %*ph\n",
441 SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
442 cifs_dbg(VFS, "ServerIn Key %*ph\n",
443 SMB3_SIGN_KEY_SIZE, ses->smb3encryptionkey);
444 cifs_dbg(VFS, "ServerOut Key %*ph\n",
445 SMB3_SIGN_KEY_SIZE, ses->smb3decryptionkey);
446#endif
447 return rc;
Steve French373512e2015-12-18 13:05:30 -0600448}
449
450int
451generate_smb30signingkey(struct cifs_ses *ses)
452
453{
454 struct derivation_triplet triplet;
455 struct derivation *d;
456
457 d = &triplet.signing;
458 d->label.iov_base = "SMB2AESCMAC";
459 d->label.iov_len = 12;
460 d->context.iov_base = "SmbSign";
461 d->context.iov_len = 8;
462
463 d = &triplet.encryption;
464 d->label.iov_base = "SMB2AESCCM";
465 d->label.iov_len = 11;
466 d->context.iov_base = "ServerIn ";
467 d->context.iov_len = 10;
468
469 d = &triplet.decryption;
470 d->label.iov_base = "SMB2AESCCM";
471 d->label.iov_len = 11;
472 d->context.iov_base = "ServerOut";
473 d->context.iov_len = 10;
474
475 return generate_smb3signingkey(ses, &triplet);
476}
477
478int
479generate_smb311signingkey(struct cifs_ses *ses)
480
481{
482 struct derivation_triplet triplet;
483 struct derivation *d;
484
485 d = &triplet.signing;
Steve French06e22902017-09-25 20:11:58 -0500486 d->label.iov_base = "SMBSigningKey";
487 d->label.iov_len = 14;
488 d->context.iov_base = ses->preauth_sha_hash;
489 d->context.iov_len = 64;
Steve French373512e2015-12-18 13:05:30 -0600490
491 d = &triplet.encryption;
Steve French06e22902017-09-25 20:11:58 -0500492 d->label.iov_base = "SMBC2SCipherKey";
493 d->label.iov_len = 16;
494 d->context.iov_base = ses->preauth_sha_hash;
495 d->context.iov_len = 64;
Steve French373512e2015-12-18 13:05:30 -0600496
497 d = &triplet.decryption;
Steve French06e22902017-09-25 20:11:58 -0500498 d->label.iov_base = "SMBS2CCipherKey";
499 d->label.iov_len = 16;
500 d->context.iov_base = ses->preauth_sha_hash;
501 d->context.iov_len = 64;
Steve French373512e2015-12-18 13:05:30 -0600502
503 return generate_smb3signingkey(ses, &triplet);
504}
505
Steve French429b46f2013-06-26 23:45:05 -0500506int
Steve French38107d42012-12-08 22:08:06 -0600507smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
508{
Paulo Alcantara27c32b42018-06-23 14:52:23 -0300509 int rc;
Steve French429b46f2013-06-26 23:45:05 -0500510 unsigned char smb3_signature[SMB2_CMACAES_SIZE];
511 unsigned char *sigptr = smb3_signature;
512 struct kvec *iov = rqst->rq_iov;
Ronnie Sahlbergc713c872018-06-12 08:00:58 +1000513 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
Paulo Alcantara27c32b42018-06-23 14:52:23 -0300514 struct shash_desc *shash = &server->secmech.sdesccmacaes->shash;
515 struct smb_rqst drqst;
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200516 u8 key[SMB3_SIGN_KEY_SIZE];
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500517
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200518 rc = smb2_get_sign_key(shdr->SessionId, server, key);
519 if (rc)
Shirish Pargaonkar32811d22013-08-29 08:35:11 -0500520 return 0;
Steve French429b46f2013-06-26 23:45:05 -0500521
522 memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700523 memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
Steve French429b46f2013-06-26 23:45:05 -0500524
525 rc = crypto_shash_setkey(server->secmech.cmacaes,
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200526 key, SMB2_CMACAES_SIZE);
Steve French429b46f2013-06-26 23:45:05 -0500527 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000528 cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
Steve French429b46f2013-06-26 23:45:05 -0500529 return rc;
530 }
531
Steve French95dc8dd2013-07-04 10:35:21 -0500532 /*
533 * we already allocate sdesccmacaes when we init smb3 signing key,
534 * so unlike smb2 case we do not have to check here if secmech are
535 * initialized
536 */
Paulo Alcantara27c32b42018-06-23 14:52:23 -0300537 rc = crypto_shash_init(shash);
Steve French429b46f2013-06-26 23:45:05 -0500538 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000539 cifs_server_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
Steve French429b46f2013-06-26 23:45:05 -0500540 return rc;
541 }
Aurelien Aptel82fb82b2018-02-16 19:19:27 +0100542
Paulo Alcantara27c32b42018-06-23 14:52:23 -0300543 /*
544 * For SMB2+, __cifs_calc_signature() expects to sign only the actual
545 * data, that is, iov[0] should not contain a rfc1002 length.
546 *
547 * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
548 * __cifs_calc_signature().
549 */
550 drqst = *rqst;
551 if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
552 rc = crypto_shash_update(shash, iov[0].iov_base,
553 iov[0].iov_len);
554 if (rc) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000555 cifs_server_dbg(VFS, "%s: Could not update with payload\n",
Paulo Alcantara27c32b42018-06-23 14:52:23 -0300556 __func__);
557 return rc;
558 }
559 drqst.rq_iov++;
560 drqst.rq_nvec--;
561 }
Steve French429b46f2013-06-26 23:45:05 -0500562
Paulo Alcantara27c32b42018-06-23 14:52:23 -0300563 rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
Al Viro16c568e2015-11-12 22:46:49 -0500564 if (!rc)
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700565 memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
Steve French429b46f2013-06-26 23:45:05 -0500566
567 return rc;
Steve French38107d42012-12-08 22:08:06 -0600568}
569
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700570/* must be called with server->srv_mutex held */
571static int
Jeff Layton0b688cf2012-09-18 16:20:34 -0700572smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700573{
574 int rc = 0;
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200575 struct smb2_sync_hdr *shdr;
576 struct smb2_sess_setup_req *ssr;
577 bool is_binding;
578 bool is_signed;
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700579
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200580 shdr = (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
581 ssr = (struct smb2_sess_setup_req *)shdr;
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700582
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200583 is_binding = shdr->Command == SMB2_SESSION_SETUP &&
584 (ssr->Flags & SMB2_SESSION_REQ_FLAG_BINDING);
585 is_signed = shdr->Flags & SMB2_FLAGS_SIGNED;
586
587 if (!is_signed)
588 return 0;
589 if (server->tcpStatus == CifsNeedNegotiate)
590 return 0;
591 if (!is_binding && !server->session_estab) {
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700592 strncpy(shdr->Signature, "BSRSPYL", 8);
Aurelien Apteld70e9fa2019-09-20 06:31:10 +0200593 return 0;
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700594 }
595
Steve French38107d42012-12-08 22:08:06 -0600596 rc = server->ops->calc_signature(rqst, server);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700597
598 return rc;
599}
600
601int
Jeff Layton0b688cf2012-09-18 16:20:34 -0700602smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700603{
604 unsigned int rc;
Steve Frenchedad7342020-03-27 12:47:41 -0500605 char server_response_sig[SMB2_SIGNATURE_SIZE];
Pavel Shilovsky738f9de2016-11-23 15:14:57 -0800606 struct smb2_sync_hdr *shdr =
Ronnie Sahlberg977b6172018-06-01 10:53:02 +1000607 (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700608
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700609 if ((shdr->Command == SMB2_NEGOTIATE) ||
610 (shdr->Command == SMB2_SESSION_SETUP) ||
611 (shdr->Command == SMB2_OPLOCK_BREAK) ||
Steve French4f5c10f2019-09-03 21:18:49 -0500612 server->ignore_signature ||
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700613 (!server->session_estab))
614 return 0;
615
616 /*
617 * BB what if signatures are supposed to be on for session but
618 * server does not send one? BB
619 */
620
621 /* Do not need to verify session setups with signature "BSRSPYL " */
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700622 if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
Joe Perchesf96637b2013-05-04 22:12:25 -0500623 cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700624 shdr->Command);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700625
626 /*
627 * Save off the origiginal signature so we can modify the smb and check
628 * our calculated signature against what the server sent.
629 */
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700630 memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700631
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700632 memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700633
634 mutex_lock(&server->srv_mutex);
Steve French38107d42012-12-08 22:08:06 -0600635 rc = server->ops->calc_signature(rqst, server);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700636 mutex_unlock(&server->srv_mutex);
637
638 if (rc)
639 return rc;
640
Steve Frenchf460c502020-03-29 16:44:43 -0500641 if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE)) {
642 dump_stack();
643 cifs_dbg(VFS, "sign fail cmd 0x%x message id 0x%llx\n", shdr->Command, shdr->MessageId);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700644 return -EACCES;
Steve Frenchf460c502020-03-29 16:44:43 -0500645 } else
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700646 return 0;
647}
648
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400649/*
650 * Set message id for the request. Should be called after wait_for_free_request
651 * and when srv_mutex is held.
652 */
653static inline void
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700654smb2_seq_num_into_buf(struct TCP_Server_Info *server,
655 struct smb2_sync_hdr *shdr)
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400656{
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700657 unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
Pavel Shilovskycb7e9ea2014-06-05 19:03:27 +0400658
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700659 shdr->MessageId = get_next_mid64(server);
Pavel Shilovskycb7e9ea2014-06-05 19:03:27 +0400660 /* skip message numbers according to CreditCharge field */
661 for (i = 1; i < num; i++)
662 get_next_mid(server);
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400663}
664
665static struct mid_q_entry *
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700666smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400667 struct TCP_Server_Info *server)
668{
669 struct mid_q_entry *temp;
Pavel Shilovskyc781af72019-03-04 14:02:50 -0800670 unsigned int credits = le16_to_cpu(shdr->CreditCharge);
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400671
672 if (server == NULL) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500673 cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400674 return NULL;
675 }
676
677 temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
NeilBrowna6f74e82017-04-10 12:08:53 +1000678 memset(temp, 0, sizeof(struct mid_q_entry));
Lars Persson696e4202018-06-25 14:05:25 +0200679 kref_init(&temp->refcount);
NeilBrowna6f74e82017-04-10 12:08:53 +1000680 temp->mid = le64_to_cpu(shdr->MessageId);
Pavel Shilovskyc781af72019-03-04 14:02:50 -0800681 temp->credits = credits > 0 ? credits : 1;
NeilBrowna6f74e82017-04-10 12:08:53 +1000682 temp->pid = current->pid;
683 temp->command = shdr->Command; /* Always LE */
684 temp->when_alloc = jiffies;
685 temp->server = server;
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400686
NeilBrowna6f74e82017-04-10 12:08:53 +1000687 /*
688 * The default is for the mid to be synchronous, so the
689 * default callback just wakes up the current task.
690 */
Vincent Whitchurchf1f27ad2020-01-23 17:09:06 +0100691 get_task_struct(current);
692 temp->creator = current;
NeilBrowna6f74e82017-04-10 12:08:53 +1000693 temp->callback = cifs_wake_up_task;
694 temp->callback_data = current;
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400695
696 atomic_inc(&midCount);
697 temp->mid_state = MID_REQUEST_ALLOCATED;
Steve French53a3e0d2019-02-26 21:26:20 -0600698 trace_smb3_cmd_enter(shdr->TreeId, shdr->SessionId,
699 le16_to_cpu(shdr->Command), temp->mid);
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400700 return temp;
701}
702
703static int
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200704smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
705 struct smb2_sync_hdr *shdr, struct mid_q_entry **mid)
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400706{
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200707 if (server->tcpStatus == CifsExiting)
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400708 return -ENOENT;
709
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200710 if (server->tcpStatus == CifsNeedReconnect) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500711 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400712 return -EAGAIN;
713 }
714
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200715 if (server->tcpStatus == CifsNeedNegotiate &&
Pavel Shilovsky2084ed52019-03-05 15:51:55 -0800716 shdr->Command != SMB2_NEGOTIATE)
717 return -EAGAIN;
718
Shirish Pargaonkar7f485582013-10-12 10:06:03 -0500719 if (ses->status == CifsNew) {
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700720 if ((shdr->Command != SMB2_SESSION_SETUP) &&
721 (shdr->Command != SMB2_NEGOTIATE))
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400722 return -EAGAIN;
723 /* else ok - we are setting up session */
724 }
Shirish Pargaonkar7f485582013-10-12 10:06:03 -0500725
726 if (ses->status == CifsExiting) {
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700727 if (shdr->Command != SMB2_LOGOFF)
Shirish Pargaonkar7f485582013-10-12 10:06:03 -0500728 return -EAGAIN;
729 /* else ok - we are shutting down the session */
730 }
731
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200732 *mid = smb2_mid_entry_alloc(shdr, server);
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400733 if (*mid == NULL)
734 return -ENOMEM;
735 spin_lock(&GlobalMid_Lock);
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200736 list_add_tail(&(*mid)->qhead, &server->pending_mid_q);
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400737 spin_unlock(&GlobalMid_Lock);
Steve French53a3e0d2019-02-26 21:26:20 -0600738
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400739 return 0;
740}
741
742int
743smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
744 bool log_error)
745{
Ronnie Sahlberge19b2bc2018-04-09 18:06:28 +1000746 unsigned int len = mid->resp_buf_size;
Ronnie Sahlberg977b6172018-06-01 10:53:02 +1000747 struct kvec iov[1];
Pavel Shilovsky738f9de2016-11-23 15:14:57 -0800748 struct smb_rqst rqst = { .rq_iov = iov,
Ronnie Sahlberg977b6172018-06-01 10:53:02 +1000749 .rq_nvec = 1 };
Jeff Layton0b688cf2012-09-18 16:20:34 -0700750
Pavel Shilovsky738f9de2016-11-23 15:14:57 -0800751 iov[0].iov_base = (char *)mid->resp_buf;
Ronnie Sahlberg977b6172018-06-01 10:53:02 +1000752 iov[0].iov_len = len;
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400753
754 dump_smb(mid->resp_buf, min_t(u32, 80, len));
755 /* convert the length into a more usable form */
Pavel Shilovsky4326ed22016-11-17 15:24:46 -0800756 if (len > 24 && server->sign && !mid->decrypted) {
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700757 int rc;
758
Jeff Layton0b688cf2012-09-18 16:20:34 -0700759 rc = smb2_verify_signature(&rqst, server);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700760 if (rc)
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000761 cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n",
Joe Perchesf96637b2013-05-04 22:12:25 -0500762 rc);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700763 }
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400764
765 return map_smb2_to_linux_error(mid->resp_buf, log_error);
766}
767
Jeff Laytonfec344e2012-09-18 16:20:35 -0700768struct mid_q_entry *
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200769smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
770 struct smb_rqst *rqst)
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400771{
772 int rc;
Pavel Shilovsky738f9de2016-11-23 15:14:57 -0800773 struct smb2_sync_hdr *shdr =
Ronnie Sahlbergc713c872018-06-12 08:00:58 +1000774 (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400775 struct mid_q_entry *mid;
776
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200777 smb2_seq_num_into_buf(server, shdr);
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400778
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200779 rc = smb2_get_mid_entry(ses, server, shdr, &mid);
Pavel Shilovskyc781af72019-03-04 14:02:50 -0800780 if (rc) {
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200781 revert_current_mid_from_hdr(server, shdr);
Jeff Laytonfec344e2012-09-18 16:20:35 -0700782 return ERR_PTR(rc);
Pavel Shilovskyc781af72019-03-04 14:02:50 -0800783 }
784
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200785 rc = smb2_sign_rqst(rqst, server);
Jeff Laytonfec344e2012-09-18 16:20:35 -0700786 if (rc) {
Aurelien Aptelf780bd32019-09-20 06:08:34 +0200787 revert_current_mid_from_hdr(server, shdr);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700788 cifs_delete_mid(mid);
Jeff Laytonfec344e2012-09-18 16:20:35 -0700789 return ERR_PTR(rc);
790 }
Pavel Shilovskyc781af72019-03-04 14:02:50 -0800791
Jeff Laytonfec344e2012-09-18 16:20:35 -0700792 return mid;
Pavel Shilovsky2dc7e1c2011-12-26 22:53:34 +0400793}
794
Jeff Laytonfec344e2012-09-18 16:20:35 -0700795struct mid_q_entry *
796smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
Pavel Shilovskyc95b8ee2012-07-11 14:45:28 +0400797{
Jeff Laytonfec344e2012-09-18 16:20:35 -0700798 int rc;
Pavel Shilovsky738f9de2016-11-23 15:14:57 -0800799 struct smb2_sync_hdr *shdr =
Ronnie Sahlbergc713c872018-06-12 08:00:58 +1000800 (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
Pavel Shilovskyc95b8ee2012-07-11 14:45:28 +0400801 struct mid_q_entry *mid;
802
Pavel Shilovsky2084ed52019-03-05 15:51:55 -0800803 if (server->tcpStatus == CifsNeedNegotiate &&
804 shdr->Command != SMB2_NEGOTIATE)
805 return ERR_PTR(-EAGAIN);
806
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700807 smb2_seq_num_into_buf(server, shdr);
Pavel Shilovskyc95b8ee2012-07-11 14:45:28 +0400808
Pavel Shilovsky31473fc2016-10-24 15:33:04 -0700809 mid = smb2_mid_entry_alloc(shdr, server);
Pavel Shilovskyc781af72019-03-04 14:02:50 -0800810 if (mid == NULL) {
811 revert_current_mid_from_hdr(server, shdr);
Jeff Laytonfec344e2012-09-18 16:20:35 -0700812 return ERR_PTR(-ENOMEM);
Pavel Shilovskyc781af72019-03-04 14:02:50 -0800813 }
Pavel Shilovskyc95b8ee2012-07-11 14:45:28 +0400814
Jeff Laytonfec344e2012-09-18 16:20:35 -0700815 rc = smb2_sign_rqst(rqst, server);
Pavel Shilovskyc95b8ee2012-07-11 14:45:28 +0400816 if (rc) {
Pavel Shilovskyc781af72019-03-04 14:02:50 -0800817 revert_current_mid_from_hdr(server, shdr);
Pavel Shilovskyc95b8ee2012-07-11 14:45:28 +0400818 DeleteMidQEntry(mid);
Jeff Laytonfec344e2012-09-18 16:20:35 -0700819 return ERR_PTR(rc);
Pavel Shilovsky3c1bf7e2012-09-18 16:20:30 -0700820 }
821
Jeff Laytonfec344e2012-09-18 16:20:35 -0700822 return mid;
Pavel Shilovskyc95b8ee2012-07-11 14:45:28 +0400823}
Pavel Shilovsky026e93d2016-11-03 16:47:37 -0700824
825int
826smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
827{
828 struct crypto_aead *tfm;
829
830 if (!server->secmech.ccmaesencrypt) {
Steve French2b2f7542019-06-07 15:16:10 -0500831 if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
832 tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
833 else
834 tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
Pavel Shilovsky026e93d2016-11-03 16:47:37 -0700835 if (IS_ERR(tfm)) {
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000836 cifs_server_dbg(VFS, "%s: Failed to alloc encrypt aead\n",
Pavel Shilovsky026e93d2016-11-03 16:47:37 -0700837 __func__);
838 return PTR_ERR(tfm);
839 }
840 server->secmech.ccmaesencrypt = tfm;
841 }
842
843 if (!server->secmech.ccmaesdecrypt) {
Steve French2b2f7542019-06-07 15:16:10 -0500844 if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
845 tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
846 else
847 tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
Pavel Shilovsky026e93d2016-11-03 16:47:37 -0700848 if (IS_ERR(tfm)) {
849 crypto_free_aead(server->secmech.ccmaesencrypt);
850 server->secmech.ccmaesencrypt = NULL;
Ronnie Sahlbergafe6f652019-08-28 17:15:35 +1000851 cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n",
Pavel Shilovsky026e93d2016-11-03 16:47:37 -0700852 __func__);
853 return PTR_ERR(tfm);
854 }
855 server->secmech.ccmaesdecrypt = tfm;
856 }
857
858 return 0;
859}