1
2
3
4
5
6
7
8
9
10
11
12#include <linux/fs.h>
13#include <linux/list.h>
14#include <linux/wait.h>
15#include <linux/net.h>
16#include <linux/delay.h>
17#include <linux/uaccess.h>
18#include <asm/processor.h>
19#include <linux/mempool.h>
20#include <linux/highmem.h>
21#include <crypto/aead.h>
22#include "smb2pdu.h"
23#include "cifsglob.h"
24#include "cifsproto.h"
25#include "smb2proto.h"
26#include "cifs_debug.h"
27#include "smb2status.h"
28#include "smb2glob.h"
29
30static int
31smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
32{
33 struct cifs_secmech *p = &server->secmech;
34 int rc;
35
36 rc = cifs_alloc_hash("hmac(sha256)",
37 &p->hmacsha256,
38 &p->sdeschmacsha256);
39 if (rc)
40 goto err;
41
42 rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
43 if (rc)
44 goto err;
45
46 return 0;
47err:
48 cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
49 return rc;
50}
51
52int
53smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
54{
55 struct cifs_secmech *p = &server->secmech;
56 int rc = 0;
57
58 rc = cifs_alloc_hash("hmac(sha256)",
59 &p->hmacsha256,
60 &p->sdeschmacsha256);
61 if (rc)
62 return rc;
63
64 rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
65 if (rc)
66 goto err;
67
68 rc = cifs_alloc_hash("sha512", &p->sha512, &p->sdescsha512);
69 if (rc)
70 goto err;
71
72 return 0;
73
74err:
75 cifs_free_hash(&p->cmacaes, &p->sdesccmacaes);
76 cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
77 return rc;
78}
79
80
81static
82int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
83{
84 struct cifs_chan *chan;
85 struct cifs_ses *ses = NULL;
86 struct TCP_Server_Info *it = NULL;
87 int i;
88 int rc = 0;
89
90 spin_lock(&cifs_tcp_ses_lock);
91
92 list_for_each_entry(it, &cifs_tcp_ses_list, tcp_ses_list) {
93 list_for_each_entry(ses, &it->smb_ses_list, smb_ses_list) {
94 if (ses->Suid == ses_id)
95 goto found;
96 }
97 }
98 cifs_server_dbg(VFS, "%s: Could not find session 0x%llx\n",
99 __func__, ses_id);
100 rc = -ENOENT;
101 goto out;
102
103found:
104 if (ses->binding) {
105
106
107
108
109
110 memcpy(key, ses->smb3signingkey, SMB3_SIGN_KEY_SIZE);
111 goto out;
112 }
113
114
115
116
117
118 for (i = 0; i < ses->chan_count; i++) {
119 chan = ses->chans + i;
120 if (chan->server == server) {
121 memcpy(key, chan->signkey, SMB3_SIGN_KEY_SIZE);
122 goto out;
123 }
124 }
125
126 cifs_dbg(VFS,
127 "%s: Could not find channel signing key for session 0x%llx\n",
128 __func__, ses_id);
129 rc = -ENOENT;
130
131out:
132 spin_unlock(&cifs_tcp_ses_lock);
133 return rc;
134}
135
136static struct cifs_ses *
137smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
138{
139 struct cifs_ses *ses;
140
141 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
142 if (ses->Suid != ses_id)
143 continue;
144 ++ses->ses_count;
145 return ses;
146 }
147
148 return NULL;
149}
150
151struct cifs_ses *
152smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
153{
154 struct cifs_ses *ses;
155
156 spin_lock(&cifs_tcp_ses_lock);
157 ses = smb2_find_smb_ses_unlocked(server, ses_id);
158 spin_unlock(&cifs_tcp_ses_lock);
159
160 return ses;
161}
162
163static struct cifs_tcon *
164smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32 tid)
165{
166 struct cifs_tcon *tcon;
167
168 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
169 if (tcon->tid != tid)
170 continue;
171 ++tcon->tc_count;
172 return tcon;
173 }
174
175 return NULL;
176}
177
178
179
180
181
182
183struct cifs_tcon *
184smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid)
185{
186 struct cifs_ses *ses;
187 struct cifs_tcon *tcon;
188
189 spin_lock(&cifs_tcp_ses_lock);
190 ses = smb2_find_smb_ses_unlocked(server, ses_id);
191 if (!ses) {
192 spin_unlock(&cifs_tcp_ses_lock);
193 return NULL;
194 }
195 tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
196 if (!tcon) {
197 cifs_put_smb_ses(ses);
198 spin_unlock(&cifs_tcp_ses_lock);
199 return NULL;
200 }
201 spin_unlock(&cifs_tcp_ses_lock);
202
203 cifs_put_smb_ses(ses);
204
205 return tcon;
206}
207
208int
209smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
210 bool allocate_crypto)
211{
212 int rc;
213 unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
214 unsigned char *sigptr = smb2_signature;
215 struct kvec *iov = rqst->rq_iov;
216 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
217 struct cifs_ses *ses;
218 struct shash_desc *shash;
219 struct crypto_shash *hash;
220 struct sdesc *sdesc = NULL;
221 struct smb_rqst drqst;
222
223 ses = smb2_find_smb_ses(server, shdr->SessionId);
224 if (!ses) {
225 cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
226 return 0;
227 }
228
229 memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
230 memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
231
232 if (allocate_crypto) {
233 rc = cifs_alloc_hash("hmac(sha256)", &hash, &sdesc);
234 if (rc) {
235 cifs_server_dbg(VFS,
236 "%s: sha256 alloc failed\n", __func__);
237 goto out;
238 }
239 shash = &sdesc->shash;
240 } else {
241 hash = server->secmech.hmacsha256;
242 shash = &server->secmech.sdeschmacsha256->shash;
243 }
244
245 rc = crypto_shash_setkey(hash, ses->auth_key.response,
246 SMB2_NTLMV2_SESSKEY_SIZE);
247 if (rc) {
248 cifs_server_dbg(VFS,
249 "%s: Could not update with response\n",
250 __func__);
251 goto out;
252 }
253
254 rc = crypto_shash_init(shash);
255 if (rc) {
256 cifs_server_dbg(VFS, "%s: Could not init sha256", __func__);
257 goto out;
258 }
259
260
261
262
263
264
265
266
267 drqst = *rqst;
268 if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
269 rc = crypto_shash_update(shash, iov[0].iov_base,
270 iov[0].iov_len);
271 if (rc) {
272 cifs_server_dbg(VFS,
273 "%s: Could not update with payload\n",
274 __func__);
275 goto out;
276 }
277 drqst.rq_iov++;
278 drqst.rq_nvec--;
279 }
280
281 rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
282 if (!rc)
283 memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
284
285out:
286 if (allocate_crypto)
287 cifs_free_hash(&hash, &sdesc);
288 if (ses)
289 cifs_put_smb_ses(ses);
290 return rc;
291}
292
293static int generate_key(struct cifs_ses *ses, struct kvec label,
294 struct kvec context, __u8 *key, unsigned int key_size)
295{
296 unsigned char zero = 0x0;
297 __u8 i[4] = {0, 0, 0, 1};
298 __u8 L128[4] = {0, 0, 0, 128};
299 __u8 L256[4] = {0, 0, 1, 0};
300 int rc = 0;
301 unsigned char prfhash[SMB2_HMACSHA256_SIZE];
302 unsigned char *hashptr = prfhash;
303 struct TCP_Server_Info *server = ses->server;
304
305 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
306 memset(key, 0x0, key_size);
307
308 rc = smb3_crypto_shash_allocate(server);
309 if (rc) {
310 cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__);
311 goto smb3signkey_ret;
312 }
313
314 rc = crypto_shash_setkey(server->secmech.hmacsha256,
315 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
316 if (rc) {
317 cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__);
318 goto smb3signkey_ret;
319 }
320
321 rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
322 if (rc) {
323 cifs_server_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
324 goto smb3signkey_ret;
325 }
326
327 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
328 i, 4);
329 if (rc) {
330 cifs_server_dbg(VFS, "%s: Could not update with n\n", __func__);
331 goto smb3signkey_ret;
332 }
333
334 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
335 label.iov_base, label.iov_len);
336 if (rc) {
337 cifs_server_dbg(VFS, "%s: Could not update with label\n", __func__);
338 goto smb3signkey_ret;
339 }
340
341 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
342 &zero, 1);
343 if (rc) {
344 cifs_server_dbg(VFS, "%s: Could not update with zero\n", __func__);
345 goto smb3signkey_ret;
346 }
347
348 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
349 context.iov_base, context.iov_len);
350 if (rc) {
351 cifs_server_dbg(VFS, "%s: Could not update with context\n", __func__);
352 goto smb3signkey_ret;
353 }
354
355 if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
356 (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
357 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
358 L256, 4);
359 } else {
360 rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
361 L128, 4);
362 }
363 if (rc) {
364 cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__);
365 goto smb3signkey_ret;
366 }
367
368 rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash,
369 hashptr);
370 if (rc) {
371 cifs_server_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
372 goto smb3signkey_ret;
373 }
374
375 memcpy(key, hashptr, key_size);
376
377smb3signkey_ret:
378 return rc;
379}
380
381struct derivation {
382 struct kvec label;
383 struct kvec context;
384};
385
386struct derivation_triplet {
387 struct derivation signing;
388 struct derivation encryption;
389 struct derivation decryption;
390};
391
392static int
393generate_smb3signingkey(struct cifs_ses *ses,
394 const struct derivation_triplet *ptriplet)
395{
396 int rc;
397#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
398 struct TCP_Server_Info *server = ses->server;
399#endif
400
401
402
403
404
405
406
407
408
409
410
411 if (ses->binding) {
412 rc = generate_key(ses, ptriplet->signing.label,
413 ptriplet->signing.context,
414 cifs_ses_binding_channel(ses)->signkey,
415 SMB3_SIGN_KEY_SIZE);
416 if (rc)
417 return rc;
418 } else {
419 rc = generate_key(ses, ptriplet->signing.label,
420 ptriplet->signing.context,
421 ses->smb3signingkey,
422 SMB3_SIGN_KEY_SIZE);
423 if (rc)
424 return rc;
425
426 memcpy(ses->chans[0].signkey, ses->smb3signingkey,
427 SMB3_SIGN_KEY_SIZE);
428
429 rc = generate_key(ses, ptriplet->encryption.label,
430 ptriplet->encryption.context,
431 ses->smb3encryptionkey,
432 SMB3_ENC_DEC_KEY_SIZE);
433 rc = generate_key(ses, ptriplet->decryption.label,
434 ptriplet->decryption.context,
435 ses->smb3decryptionkey,
436 SMB3_ENC_DEC_KEY_SIZE);
437 if (rc)
438 return rc;
439 }
440
441 if (rc)
442 return rc;
443
444#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
445 cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__);
446
447
448
449
450 cifs_dbg(VFS, "Session Id %*ph\n", (int)sizeof(ses->Suid),
451 &ses->Suid);
452 cifs_dbg(VFS, "Cipher type %d\n", server->cipher_type);
453 cifs_dbg(VFS, "Session Key %*ph\n",
454 SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
455 cifs_dbg(VFS, "Signing Key %*ph\n",
456 SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
457 if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
458 (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
459 cifs_dbg(VFS, "ServerIn Key %*ph\n",
460 SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3encryptionkey);
461 cifs_dbg(VFS, "ServerOut Key %*ph\n",
462 SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3decryptionkey);
463 } else {
464 cifs_dbg(VFS, "ServerIn Key %*ph\n",
465 SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3encryptionkey);
466 cifs_dbg(VFS, "ServerOut Key %*ph\n",
467 SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3decryptionkey);
468 }
469#endif
470 return rc;
471}
472
473int
474generate_smb30signingkey(struct cifs_ses *ses)
475
476{
477 struct derivation_triplet triplet;
478 struct derivation *d;
479
480 d = &triplet.signing;
481 d->label.iov_base = "SMB2AESCMAC";
482 d->label.iov_len = 12;
483 d->context.iov_base = "SmbSign";
484 d->context.iov_len = 8;
485
486 d = &triplet.encryption;
487 d->label.iov_base = "SMB2AESCCM";
488 d->label.iov_len = 11;
489 d->context.iov_base = "ServerIn ";
490 d->context.iov_len = 10;
491
492 d = &triplet.decryption;
493 d->label.iov_base = "SMB2AESCCM";
494 d->label.iov_len = 11;
495 d->context.iov_base = "ServerOut";
496 d->context.iov_len = 10;
497
498 return generate_smb3signingkey(ses, &triplet);
499}
500
501int
502generate_smb311signingkey(struct cifs_ses *ses)
503
504{
505 struct derivation_triplet triplet;
506 struct derivation *d;
507
508 d = &triplet.signing;
509 d->label.iov_base = "SMBSigningKey";
510 d->label.iov_len = 14;
511 d->context.iov_base = ses->preauth_sha_hash;
512 d->context.iov_len = 64;
513
514 d = &triplet.encryption;
515 d->label.iov_base = "SMBC2SCipherKey";
516 d->label.iov_len = 16;
517 d->context.iov_base = ses->preauth_sha_hash;
518 d->context.iov_len = 64;
519
520 d = &triplet.decryption;
521 d->label.iov_base = "SMBS2CCipherKey";
522 d->label.iov_len = 16;
523 d->context.iov_base = ses->preauth_sha_hash;
524 d->context.iov_len = 64;
525
526 return generate_smb3signingkey(ses, &triplet);
527}
528
529int
530smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
531 bool allocate_crypto)
532{
533 int rc;
534 unsigned char smb3_signature[SMB2_CMACAES_SIZE];
535 unsigned char *sigptr = smb3_signature;
536 struct kvec *iov = rqst->rq_iov;
537 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
538 struct shash_desc *shash;
539 struct crypto_shash *hash;
540 struct sdesc *sdesc = NULL;
541 struct smb_rqst drqst;
542 u8 key[SMB3_SIGN_KEY_SIZE];
543
544 rc = smb2_get_sign_key(shdr->SessionId, server, key);
545 if (rc)
546 return 0;
547
548 if (allocate_crypto) {
549 rc = cifs_alloc_hash("cmac(aes)", &hash, &sdesc);
550 if (rc)
551 return rc;
552
553 shash = &sdesc->shash;
554 } else {
555 hash = server->secmech.cmacaes;
556 shash = &server->secmech.sdesccmacaes->shash;
557 }
558
559 memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
560 memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
561
562 rc = crypto_shash_setkey(hash, key, SMB2_CMACAES_SIZE);
563 if (rc) {
564 cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
565 goto out;
566 }
567
568
569
570
571
572
573 rc = crypto_shash_init(shash);
574 if (rc) {
575 cifs_server_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
576 goto out;
577 }
578
579
580
581
582
583
584
585
586 drqst = *rqst;
587 if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
588 rc = crypto_shash_update(shash, iov[0].iov_base,
589 iov[0].iov_len);
590 if (rc) {
591 cifs_server_dbg(VFS, "%s: Could not update with payload\n",
592 __func__);
593 goto out;
594 }
595 drqst.rq_iov++;
596 drqst.rq_nvec--;
597 }
598
599 rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
600 if (!rc)
601 memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
602
603out:
604 if (allocate_crypto)
605 cifs_free_hash(&hash, &sdesc);
606 return rc;
607}
608
609
610static int
611smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
612{
613 int rc = 0;
614 struct smb2_sync_hdr *shdr;
615 struct smb2_sess_setup_req *ssr;
616 bool is_binding;
617 bool is_signed;
618
619 shdr = (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
620 ssr = (struct smb2_sess_setup_req *)shdr;
621
622 is_binding = shdr->Command == SMB2_SESSION_SETUP &&
623 (ssr->Flags & SMB2_SESSION_REQ_FLAG_BINDING);
624 is_signed = shdr->Flags & SMB2_FLAGS_SIGNED;
625
626 if (!is_signed)
627 return 0;
628 if (server->tcpStatus == CifsNeedNegotiate)
629 return 0;
630 if (!is_binding && !server->session_estab) {
631 strncpy(shdr->Signature, "BSRSPYL", 8);
632 return 0;
633 }
634
635 rc = server->ops->calc_signature(rqst, server, false);
636
637 return rc;
638}
639
640int
641smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
642{
643 unsigned int rc;
644 char server_response_sig[SMB2_SIGNATURE_SIZE];
645 struct smb2_sync_hdr *shdr =
646 (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
647
648 if ((shdr->Command == SMB2_NEGOTIATE) ||
649 (shdr->Command == SMB2_SESSION_SETUP) ||
650 (shdr->Command == SMB2_OPLOCK_BREAK) ||
651 server->ignore_signature ||
652 (!server->session_estab))
653 return 0;
654
655
656
657
658
659
660
661 if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
662 cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
663 shdr->Command);
664
665
666
667
668
669 memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
670
671 memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
672
673 rc = server->ops->calc_signature(rqst, server, true);
674
675 if (rc)
676 return rc;
677
678 if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE)) {
679 cifs_dbg(VFS, "sign fail cmd 0x%x message id 0x%llx\n",
680 shdr->Command, shdr->MessageId);
681 return -EACCES;
682 } else
683 return 0;
684}
685
686
687
688
689
690static inline void
691smb2_seq_num_into_buf(struct TCP_Server_Info *server,
692 struct smb2_sync_hdr *shdr)
693{
694 unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
695
696 shdr->MessageId = get_next_mid64(server);
697
698 for (i = 1; i < num; i++)
699 get_next_mid(server);
700}
701
702static struct mid_q_entry *
703smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
704 struct TCP_Server_Info *server)
705{
706 struct mid_q_entry *temp;
707 unsigned int credits = le16_to_cpu(shdr->CreditCharge);
708
709 if (server == NULL) {
710 cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
711 return NULL;
712 }
713
714 temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
715 memset(temp, 0, sizeof(struct mid_q_entry));
716 kref_init(&temp->refcount);
717 temp->mid = le64_to_cpu(shdr->MessageId);
718 temp->credits = credits > 0 ? credits : 1;
719 temp->pid = current->pid;
720 temp->command = shdr->Command;
721 temp->when_alloc = jiffies;
722 temp->server = server;
723
724
725
726
727
728 get_task_struct(current);
729 temp->creator = current;
730 temp->callback = cifs_wake_up_task;
731 temp->callback_data = current;
732
733 atomic_inc(&midCount);
734 temp->mid_state = MID_REQUEST_ALLOCATED;
735 trace_smb3_cmd_enter(shdr->TreeId, shdr->SessionId,
736 le16_to_cpu(shdr->Command), temp->mid);
737 return temp;
738}
739
740static int
741smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
742 struct smb2_sync_hdr *shdr, struct mid_q_entry **mid)
743{
744 if (server->tcpStatus == CifsExiting)
745 return -ENOENT;
746
747 if (server->tcpStatus == CifsNeedReconnect) {
748 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
749 return -EAGAIN;
750 }
751
752 if (server->tcpStatus == CifsNeedNegotiate &&
753 shdr->Command != SMB2_NEGOTIATE)
754 return -EAGAIN;
755
756 if (ses->status == CifsNew) {
757 if ((shdr->Command != SMB2_SESSION_SETUP) &&
758 (shdr->Command != SMB2_NEGOTIATE))
759 return -EAGAIN;
760
761 }
762
763 if (ses->status == CifsExiting) {
764 if (shdr->Command != SMB2_LOGOFF)
765 return -EAGAIN;
766
767 }
768
769 *mid = smb2_mid_entry_alloc(shdr, server);
770 if (*mid == NULL)
771 return -ENOMEM;
772 spin_lock(&GlobalMid_Lock);
773 list_add_tail(&(*mid)->qhead, &server->pending_mid_q);
774 spin_unlock(&GlobalMid_Lock);
775
776 return 0;
777}
778
779int
780smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
781 bool log_error)
782{
783 unsigned int len = mid->resp_buf_size;
784 struct kvec iov[1];
785 struct smb_rqst rqst = { .rq_iov = iov,
786 .rq_nvec = 1 };
787
788 iov[0].iov_base = (char *)mid->resp_buf;
789 iov[0].iov_len = len;
790
791 dump_smb(mid->resp_buf, min_t(u32, 80, len));
792
793 if (len > 24 && server->sign && !mid->decrypted) {
794 int rc;
795
796 rc = smb2_verify_signature(&rqst, server);
797 if (rc)
798 cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n",
799 rc);
800 }
801
802 return map_smb2_to_linux_error(mid->resp_buf, log_error);
803}
804
805struct mid_q_entry *
806smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
807 struct smb_rqst *rqst)
808{
809 int rc;
810 struct smb2_sync_hdr *shdr =
811 (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
812 struct mid_q_entry *mid;
813
814 smb2_seq_num_into_buf(server, shdr);
815
816 rc = smb2_get_mid_entry(ses, server, shdr, &mid);
817 if (rc) {
818 revert_current_mid_from_hdr(server, shdr);
819 return ERR_PTR(rc);
820 }
821
822 rc = smb2_sign_rqst(rqst, server);
823 if (rc) {
824 revert_current_mid_from_hdr(server, shdr);
825 cifs_delete_mid(mid);
826 return ERR_PTR(rc);
827 }
828
829 return mid;
830}
831
832struct mid_q_entry *
833smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
834{
835 int rc;
836 struct smb2_sync_hdr *shdr =
837 (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
838 struct mid_q_entry *mid;
839
840 if (server->tcpStatus == CifsNeedNegotiate &&
841 shdr->Command != SMB2_NEGOTIATE)
842 return ERR_PTR(-EAGAIN);
843
844 smb2_seq_num_into_buf(server, shdr);
845
846 mid = smb2_mid_entry_alloc(shdr, server);
847 if (mid == NULL) {
848 revert_current_mid_from_hdr(server, shdr);
849 return ERR_PTR(-ENOMEM);
850 }
851
852 rc = smb2_sign_rqst(rqst, server);
853 if (rc) {
854 revert_current_mid_from_hdr(server, shdr);
855 DeleteMidQEntry(mid);
856 return ERR_PTR(rc);
857 }
858
859 return mid;
860}
861
862int
863smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
864{
865 struct crypto_aead *tfm;
866
867 if (!server->secmech.ccmaesencrypt) {
868 if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
869 (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
870 tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
871 else
872 tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
873 if (IS_ERR(tfm)) {
874 cifs_server_dbg(VFS, "%s: Failed alloc encrypt aead\n",
875 __func__);
876 return PTR_ERR(tfm);
877 }
878 server->secmech.ccmaesencrypt = tfm;
879 }
880
881 if (!server->secmech.ccmaesdecrypt) {
882 if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
883 (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
884 tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
885 else
886 tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
887 if (IS_ERR(tfm)) {
888 crypto_free_aead(server->secmech.ccmaesencrypt);
889 server->secmech.ccmaesencrypt = NULL;
890 cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n",
891 __func__);
892 return PTR_ERR(tfm);
893 }
894 server->secmech.ccmaesdecrypt = tfm;
895 }
896
897 return 0;
898}
899