Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  1/*
  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>
 33#include <linux/highmem.h>
 34#include "smb2pdu.h"
 35#include "cifsglob.h"
 36#include "cifsproto.h"
 37#include "smb2proto.h"
 38#include "cifs_debug.h"
 39#include "smb2status.h"
 40#include "smb2glob.h"
 41
 42static int
 43smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
 44{
 45	int rc;
 46	unsigned int size;
 47
 48	if (server->secmech.sdeschmacsha256 != NULL)
 49		return 0; /* already allocated */
 50
 51	server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
 52	if (IS_ERR(server->secmech.hmacsha256)) {
 53		cifs_dbg(VFS, "could not allocate crypto hmacsha256\n");
 54		rc = PTR_ERR(server->secmech.hmacsha256);
 55		server->secmech.hmacsha256 = NULL;
 56		return rc;
 57	}
 58
 59	size = sizeof(struct shash_desc) +
 60			crypto_shash_descsize(server->secmech.hmacsha256);
 61	server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
 62	if (!server->secmech.sdeschmacsha256) {
 63		crypto_free_shash(server->secmech.hmacsha256);
 64		server->secmech.hmacsha256 = NULL;
 65		return -ENOMEM;
 66	}
 67	server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
 68	server->secmech.sdeschmacsha256->shash.flags = 0x0;
 69
 70	return 0;
 71}
 72
 73static int
 74smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
 75{
 76	unsigned int size;
 77	int rc;
 78
 79	if (server->secmech.sdesccmacaes != NULL)
 80		return 0;  /* already allocated */
 81
 82	rc = smb2_crypto_shash_allocate(server);
 83	if (rc)
 84		return rc;
 85
 86	server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
 87	if (IS_ERR(server->secmech.cmacaes)) {
 88		cifs_dbg(VFS, "could not allocate crypto cmac-aes");
 89		kfree(server->secmech.sdeschmacsha256);
 90		server->secmech.sdeschmacsha256 = NULL;
 91		crypto_free_shash(server->secmech.hmacsha256);
 92		server->secmech.hmacsha256 = NULL;
 93		rc = PTR_ERR(server->secmech.cmacaes);
 94		server->secmech.cmacaes = NULL;
 95		return rc;
 96	}
 97
 98	size = sizeof(struct shash_desc) +
 99			crypto_shash_descsize(server->secmech.cmacaes);
100	server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
101	if (!server->secmech.sdesccmacaes) {
102		cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
103		kfree(server->secmech.sdeschmacsha256);
104		server->secmech.sdeschmacsha256 = NULL;
105		crypto_free_shash(server->secmech.hmacsha256);
106		crypto_free_shash(server->secmech.cmacaes);
107		server->secmech.hmacsha256 = NULL;
108		server->secmech.cmacaes = NULL;
109		return -ENOMEM;
110	}
111	server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
112	server->secmech.sdesccmacaes->shash.flags = 0x0;
113
114	return 0;
115}
116
117static struct cifs_ses *
118smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server)
119{
120	struct cifs_ses *ses;
121
122	spin_lock(&cifs_tcp_ses_lock);
123	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
124		if (ses->Suid != smb2hdr->SessionId)
125			continue;
126		spin_unlock(&cifs_tcp_ses_lock);
127		return ses;
128	}
129	spin_unlock(&cifs_tcp_ses_lock);
130
131	return NULL;
132}
133
134
135int
136smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
137{
138	int rc;
139	unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
140	unsigned char *sigptr = smb2_signature;
141	struct kvec *iov = rqst->rq_iov;
142	struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
143	struct cifs_ses *ses;
144
145	ses = smb2_find_smb_ses(smb2_pdu, server);
146	if (!ses) {
147		cifs_dbg(VFS, "%s: Could not find session\n", __func__);
148		return 0;
149	}
150
151	memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
152	memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
153
154	rc = smb2_crypto_shash_allocate(server);
155	if (rc) {
156		cifs_dbg(VFS, "%s: shah256 alloc failed\n", __func__);
157		return rc;
158	}
159
160	rc = crypto_shash_setkey(server->secmech.hmacsha256,
161		ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
162	if (rc) {
163		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
164		return rc;
165	}
166
167	rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
168	if (rc) {
169		cifs_dbg(VFS, "%s: Could not init sha256", __func__);
170		return rc;
171	}
172
173	rc = __cifs_calc_signature(rqst, server, sigptr,
174		&server->secmech.sdeschmacsha256->shash);
175
176	if (!rc)
177		memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE);
178
179	return rc;
180}
181
182static int generate_key(struct cifs_ses *ses, struct kvec label,
183			struct kvec context, __u8 *key, unsigned int key_size)
184{
185	unsigned char zero = 0x0;
186	__u8 i[4] = {0, 0, 0, 1};
187	__u8 L[4] = {0, 0, 0, 128};
188	int rc = 0;
189	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
190	unsigned char *hashptr = prfhash;
191
192	memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
193	memset(key, 0x0, key_size);
194
195	rc = smb3_crypto_shash_allocate(ses->server);
196	if (rc) {
197		cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
198		goto smb3signkey_ret;
199	}
200
201	rc = crypto_shash_setkey(ses->server->secmech.hmacsha256,
202		ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
203	if (rc) {
204		cifs_dbg(VFS, "%s: Could not set with session key\n", __func__);
205		goto smb3signkey_ret;
206	}
207
208	rc = crypto_shash_init(&ses->server->secmech.sdeschmacsha256->shash);
209	if (rc) {
210		cifs_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
211		goto smb3signkey_ret;
212	}
213
214	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
215				i, 4);
216	if (rc) {
217		cifs_dbg(VFS, "%s: Could not update with n\n", __func__);
218		goto smb3signkey_ret;
219	}
220
221	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
222				label.iov_base, label.iov_len);
223	if (rc) {
224		cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
225		goto smb3signkey_ret;
226	}
227
228	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
229				&zero, 1);
230	if (rc) {
231		cifs_dbg(VFS, "%s: Could not update with zero\n", __func__);
232		goto smb3signkey_ret;
233	}
234
235	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
236				context.iov_base, context.iov_len);
237	if (rc) {
238		cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
239		goto smb3signkey_ret;
240	}
241
242	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
243				L, 4);
244	if (rc) {
245		cifs_dbg(VFS, "%s: Could not update with L\n", __func__);
246		goto smb3signkey_ret;
247	}
248
249	rc = crypto_shash_final(&ses->server->secmech.sdeschmacsha256->shash,
250				hashptr);
251	if (rc) {
252		cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
253		goto smb3signkey_ret;
254	}
255
256	memcpy(key, hashptr, key_size);
257
258smb3signkey_ret:
259	return rc;
260}
261
262struct derivation {
263	struct kvec label;
264	struct kvec context;
265};
266
267struct derivation_triplet {
268	struct derivation signing;
269	struct derivation encryption;
270	struct derivation decryption;
271};
272
273static int
274generate_smb3signingkey(struct cifs_ses *ses,
275			const struct derivation_triplet *ptriplet)
276{
277	int rc;
278
279	rc = generate_key(ses, ptriplet->signing.label,
280			  ptriplet->signing.context, ses->smb3signingkey,
281			  SMB3_SIGN_KEY_SIZE);
282	if (rc)
283		return rc;
284
285	rc = generate_key(ses, ptriplet->encryption.label,
286			  ptriplet->encryption.context, ses->smb3encryptionkey,
287			  SMB3_SIGN_KEY_SIZE);
288	if (rc)
289		return rc;
290
291	return generate_key(ses, ptriplet->decryption.label,
292			    ptriplet->decryption.context,
293			    ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
294}
295
296int
297generate_smb30signingkey(struct cifs_ses *ses)
298
299{
300	struct derivation_triplet triplet;
301	struct derivation *d;
302
303	d = &triplet.signing;
304	d->label.iov_base = "SMB2AESCMAC";
305	d->label.iov_len = 12;
306	d->context.iov_base = "SmbSign";
307	d->context.iov_len = 8;
308
309	d = &triplet.encryption;
310	d->label.iov_base = "SMB2AESCCM";
311	d->label.iov_len = 11;
312	d->context.iov_base = "ServerIn ";
313	d->context.iov_len = 10;
314
315	d = &triplet.decryption;
316	d->label.iov_base = "SMB2AESCCM";
317	d->label.iov_len = 11;
318	d->context.iov_base = "ServerOut";
319	d->context.iov_len = 10;
320
321	return generate_smb3signingkey(ses, &triplet);
322}
323
324int
325generate_smb311signingkey(struct cifs_ses *ses)
326
327{
328	struct derivation_triplet triplet;
329	struct derivation *d;
330
331	d = &triplet.signing;
332	d->label.iov_base = "SMB2AESCMAC";
333	d->label.iov_len = 12;
334	d->context.iov_base = "SmbSign";
335	d->context.iov_len = 8;
336
337	d = &triplet.encryption;
338	d->label.iov_base = "SMB2AESCCM";
339	d->label.iov_len = 11;
340	d->context.iov_base = "ServerIn ";
341	d->context.iov_len = 10;
342
343	d = &triplet.decryption;
344	d->label.iov_base = "SMB2AESCCM";
345	d->label.iov_len = 11;
346	d->context.iov_base = "ServerOut";
347	d->context.iov_len = 10;
348
349	return generate_smb3signingkey(ses, &triplet);
350}
351
352int
353smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
354{
355	int rc = 0;
356	unsigned char smb3_signature[SMB2_CMACAES_SIZE];
357	unsigned char *sigptr = smb3_signature;
358	struct kvec *iov = rqst->rq_iov;
359	struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
360	struct cifs_ses *ses;
361
362	ses = smb2_find_smb_ses(smb2_pdu, server);
363	if (!ses) {
364		cifs_dbg(VFS, "%s: Could not find session\n", __func__);
365		return 0;
366	}
367
368	memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
369	memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
370
371	rc = crypto_shash_setkey(server->secmech.cmacaes,
372		ses->smb3signingkey, SMB2_CMACAES_SIZE);
373
374	if (rc) {
375		cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
376		return rc;
377	}
378
379	/*
380	 * we already allocate sdesccmacaes when we init smb3 signing key,
381	 * so unlike smb2 case we do not have to check here if secmech are
382	 * initialized
383	 */
384	rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash);
385	if (rc) {
386		cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
387		return rc;
388	}
389	
390	rc = __cifs_calc_signature(rqst, server, sigptr,
391				   &server->secmech.sdesccmacaes->shash);
392
393	if (!rc)
394		memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE);
395
396	return rc;
397}
398
399/* must be called with server->srv_mutex held */
400static int
401smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
402{
403	int rc = 0;
404	struct smb2_hdr *smb2_pdu = rqst->rq_iov[0].iov_base;
405
406	if (!(smb2_pdu->Flags & SMB2_FLAGS_SIGNED) ||
407	    server->tcpStatus == CifsNeedNegotiate)
408		return rc;
409
410	if (!server->session_estab) {
411		strncpy(smb2_pdu->Signature, "BSRSPYL", 8);
412		return rc;
413	}
414
415	rc = server->ops->calc_signature(rqst, server);
416
417	return rc;
418}
419
420int
421smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
422{
423	unsigned int rc;
424	char server_response_sig[16];
425	struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
426
427	if ((smb2_pdu->Command == SMB2_NEGOTIATE) ||
428	    (smb2_pdu->Command == SMB2_SESSION_SETUP) ||
429	    (smb2_pdu->Command == SMB2_OPLOCK_BREAK) ||
430	    (!server->session_estab))
431		return 0;
432
433	/*
434	 * BB what if signatures are supposed to be on for session but
435	 * server does not send one? BB
436	 */
437
438	/* Do not need to verify session setups with signature "BSRSPYL " */
439	if (memcmp(smb2_pdu->Signature, "BSRSPYL ", 8) == 0)
440		cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
441			 smb2_pdu->Command);
442
443	/*
444	 * Save off the origiginal signature so we can modify the smb and check
445	 * our calculated signature against what the server sent.
446	 */
447	memcpy(server_response_sig, smb2_pdu->Signature, SMB2_SIGNATURE_SIZE);
448
449	memset(smb2_pdu->Signature, 0, SMB2_SIGNATURE_SIZE);
450
451	mutex_lock(&server->srv_mutex);
452	rc = server->ops->calc_signature(rqst, server);
453	mutex_unlock(&server->srv_mutex);
454
455	if (rc)
456		return rc;
457
458	if (memcmp(server_response_sig, smb2_pdu->Signature,
459		   SMB2_SIGNATURE_SIZE))
460		return -EACCES;
461	else
462		return 0;
463}
464
465/*
466 * Set message id for the request. Should be called after wait_for_free_request
467 * and when srv_mutex is held.
468 */
469static inline void
470smb2_seq_num_into_buf(struct TCP_Server_Info *server, struct smb2_hdr *hdr)
471{
472	unsigned int i, num = le16_to_cpu(hdr->CreditCharge);
473
474	hdr->MessageId = get_next_mid64(server);
475	/* skip message numbers according to CreditCharge field */
476	for (i = 1; i < num; i++)
477		get_next_mid(server);
478}
479
480static struct mid_q_entry *
481smb2_mid_entry_alloc(const struct smb2_hdr *smb_buffer,
482		     struct TCP_Server_Info *server)
483{
484	struct mid_q_entry *temp;
485
486	if (server == NULL) {
487		cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
488		return NULL;
489	}
490
491	temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
492	if (temp == NULL)
493		return temp;
494	else {
495		memset(temp, 0, sizeof(struct mid_q_entry));
496		temp->mid = le64_to_cpu(smb_buffer->MessageId);
497		temp->pid = current->pid;
498		temp->command = smb_buffer->Command;	/* Always LE */
499		temp->when_alloc = jiffies;
500		temp->server = server;
501
502		/*
503		 * The default is for the mid to be synchronous, so the
504		 * default callback just wakes up the current task.
505		 */
506		temp->callback = cifs_wake_up_task;
507		temp->callback_data = current;
508	}
509
510	atomic_inc(&midCount);
511	temp->mid_state = MID_REQUEST_ALLOCATED;
512	return temp;
513}
514
515static int
516smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_hdr *buf,
517		   struct mid_q_entry **mid)
518{
519	if (ses->server->tcpStatus == CifsExiting)
520		return -ENOENT;
521
522	if (ses->server->tcpStatus == CifsNeedReconnect) {
523		cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
524		return -EAGAIN;
525	}
526
527	if (ses->status == CifsNew) {
528		if ((buf->Command != SMB2_SESSION_SETUP) &&
529		    (buf->Command != SMB2_NEGOTIATE))
530			return -EAGAIN;
531		/* else ok - we are setting up session */
532	}
533
534	if (ses->status == CifsExiting) {
535		if (buf->Command != SMB2_LOGOFF)
536			return -EAGAIN;
537		/* else ok - we are shutting down the session */
538	}
539
540	*mid = smb2_mid_entry_alloc(buf, ses->server);
541	if (*mid == NULL)
542		return -ENOMEM;
543	spin_lock(&GlobalMid_Lock);
544	list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
545	spin_unlock(&GlobalMid_Lock);
546	return 0;
547}
548
549int
550smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
551		   bool log_error)
552{
553	unsigned int len = get_rfc1002_length(mid->resp_buf);
554	struct kvec iov;
555	struct smb_rqst rqst = { .rq_iov = &iov,
556				 .rq_nvec = 1 };
557
558	iov.iov_base = (char *)mid->resp_buf;
559	iov.iov_len = get_rfc1002_length(mid->resp_buf) + 4;
560
561	dump_smb(mid->resp_buf, min_t(u32, 80, len));
562	/* convert the length into a more usable form */
563	if (len > 24 && server->sign) {
564		int rc;
565
566		rc = smb2_verify_signature(&rqst, server);
567		if (rc)
568			cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
569				 rc);
570	}
571
572	return map_smb2_to_linux_error(mid->resp_buf, log_error);
573}
574
575struct mid_q_entry *
576smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
577{
578	int rc;
579	struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
580	struct mid_q_entry *mid;
581
582	smb2_seq_num_into_buf(ses->server, hdr);
583
584	rc = smb2_get_mid_entry(ses, hdr, &mid);
585	if (rc)
586		return ERR_PTR(rc);
587	rc = smb2_sign_rqst(rqst, ses->server);
588	if (rc) {
589		cifs_delete_mid(mid);
590		return ERR_PTR(rc);
591	}
592	return mid;
593}
594
595struct mid_q_entry *
596smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
597{
598	int rc;
599	struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
600	struct mid_q_entry *mid;
601
602	smb2_seq_num_into_buf(server, hdr);
603
604	mid = smb2_mid_entry_alloc(hdr, server);
605	if (mid == NULL)
606		return ERR_PTR(-ENOMEM);
607
608	rc = smb2_sign_rqst(rqst, server);
609	if (rc) {
610		DeleteMidQEntry(mid);
611		return ERR_PTR(rc);
612	}
613
614	return mid;
615}