cifsencrypt.c 24.2 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3
/*
 *   fs/cifs/cifsencrypt.c
 *
4 5 6
 *   Encryption and hashing operations relating to NTLM, NTLMv2.  See MS-NLMP
 *   for more detailed information
 *
7
 *   Copyright (C) International Business Machines  Corp., 2005,2013
L
Linus Torvalds 已提交
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <linux/fs.h>
26
#include <linux/slab.h>
L
Linus Torvalds 已提交
27
#include "cifspdu.h"
S
Steve French 已提交
28
#include "cifsglob.h"
L
Linus Torvalds 已提交
29 30 31
#include "cifs_debug.h"
#include "cifs_unicode.h"
#include "cifsproto.h"
32
#include "ntlmssp.h"
33
#include <linux/ctype.h>
S
Steve French 已提交
34
#include <linux/random.h>
35
#include <linux/highmem.h>
H
Herbert Xu 已提交
36
#include <crypto/skcipher.h>
L
Linus Torvalds 已提交
37

38 39 40 41 42 43 44 45 46 47 48 49
static int
cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server)
{
	int rc;
	unsigned int size;

	if (server->secmech.sdescmd5 != NULL)
		return 0; /* already allocated */

	server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
	if (IS_ERR(server->secmech.md5)) {
		cifs_dbg(VFS, "could not allocate crypto md5\n");
50 51 52
		rc = PTR_ERR(server->secmech.md5);
		server->secmech.md5 = NULL;
		return rc;
53 54 55 56 57 58 59 60
	}

	size = sizeof(struct shash_desc) +
			crypto_shash_descsize(server->secmech.md5);
	server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
	if (!server->secmech.sdescmd5) {
		crypto_free_shash(server->secmech.md5);
		server->secmech.md5 = NULL;
61
		return -ENOMEM;
62 63 64 65 66 67 68
	}
	server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
	server->secmech.sdescmd5->shash.flags = 0x0;

	return 0;
}

69 70 71
int __cifs_calc_signature(struct smb_rqst *rqst,
			struct TCP_Server_Info *server, char *signature,
			struct shash_desc *shash)
72
{
73
	int i;
74
	int rc;
75 76
	struct kvec *iov = rqst->rq_iov;
	int n_vec = rqst->rq_nvec;
77

78
	for (i = 0; i < n_vec; i++) {
79 80
		if (iov[i].iov_len == 0)
			continue;
S
Steve French 已提交
81
		if (iov[i].iov_base == NULL) {
82
			cifs_dbg(VFS, "null iovec entry\n");
83
			return -EIO;
84
		}
S
Steve French 已提交
85
		/* The first entry includes a length field (which does not get
86
		   signed that occupies the first 4 bytes before the header */
S
Steve French 已提交
87
		if (i == 0) {
88
			if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
89
				break; /* nothing to sign or corrupt header */
90
			rc = crypto_shash_update(shash,
91
				iov[i].iov_base + 4, iov[i].iov_len - 4);
92
		} else {
93
			rc = crypto_shash_update(shash,
94
				iov[i].iov_base, iov[i].iov_len);
95 96
		}
		if (rc) {
97 98
			cifs_dbg(VFS, "%s: Could not update with payload\n",
				 __func__);
99 100
			return rc;
		}
101
	}
102

103 104
	/* now hash over the rq_pages array */
	for (i = 0; i < rqst->rq_npages; i++) {
105 106 107 108 109 110 111
		void *kaddr = kmap(rqst->rq_pages[i]);
		size_t len = rqst->rq_pagesz;

		if (i == rqst->rq_npages - 1)
			len = rqst->rq_tailsz;

		crypto_shash_update(shash, kaddr, len);
112 113 114 115

		kunmap(rqst->rq_pages[i]);
	}

116
	rc = crypto_shash_final(shash, signature);
117
	if (rc)
118
		cifs_dbg(VFS, "%s: Could not generate hash\n", __func__);
119

120
	return rc;
121 122
}

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
/*
 * Calculate and return the CIFS signature based on the mac key and SMB PDU.
 * The 16 byte signature must be allocated by the caller. Note we only use the
 * 1st eight bytes and that the smb header signature field on input contains
 * the sequence number before this function is called. Also, this function
 * should be called with the server->srv_mutex held.
 */
static int cifs_calc_signature(struct smb_rqst *rqst,
			struct TCP_Server_Info *server, char *signature)
{
	int rc;

	if (!rqst->rq_iov || !signature || !server)
		return -EINVAL;

	if (!server->secmech.sdescmd5) {
		rc = cifs_crypto_shash_md5_allocate(server);
		if (rc) {
			cifs_dbg(VFS, "%s: Can't alloc md5 crypto\n", __func__);
			return -1;
		}
	}

	rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
	if (rc) {
		cifs_dbg(VFS, "%s: Could not init md5\n", __func__);
		return rc;
	}

	rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
		server->session_key.response, server->session_key.len);
	if (rc) {
		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
		return rc;
	}

	return __cifs_calc_signature(rqst, server, signature,
				     &server->secmech.sdescmd5->shash);
}

163
/* must be called with server->srv_mutex held */
164
int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
165
		   __u32 *pexpected_response_sequence_number)
166 167 168
{
	int rc = 0;
	char smb_signature[20];
169
	struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
170

S
Steve French 已提交
171
	if ((cifs_pdu == NULL) || (server == NULL))
172 173
		return -EINVAL;

174 175
	if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
	    server->tcpStatus == CifsNeedNegotiate)
176 177
		return rc;

178
	if (!server->session_estab) {
179
		memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
180 181 182
		return rc;
	}

S
Steve French 已提交
183
	cifs_pdu->Signature.Sequence.SequenceNumber =
184
				cpu_to_le32(server->sequence_number);
S
Steve French 已提交
185
	cifs_pdu->Signature.Sequence.Reserved = 0;
186

187 188
	*pexpected_response_sequence_number = ++server->sequence_number;
	++server->sequence_number;
189

190
	rc = cifs_calc_signature(rqst, server, smb_signature);
S
Steve French 已提交
191 192 193 194
	if (rc)
		memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
	else
		memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
195

S
Steve French 已提交
196
	return rc;
197 198
}

199 200 201 202 203 204 205 206 207
int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
		   __u32 *pexpected_response_sequence)
{
	struct smb_rqst rqst = { .rq_iov = iov,
				 .rq_nvec = n_vec };

	return cifs_sign_rqst(&rqst, server, pexpected_response_sequence);
}

208 209 210 211 212 213 214 215 216
/* must be called with server->srv_mutex held */
int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
		  __u32 *pexpected_response_sequence_number)
{
	struct kvec iov;

	iov.iov_base = cifs_pdu;
	iov.iov_len = be32_to_cpu(cifs_pdu->smb_buf_length) + 4;

217
	return cifs_sign_smbv(&iov, 1, server,
218 219 220
			      pexpected_response_sequence_number);
}

221
int cifs_verify_signature(struct smb_rqst *rqst,
222
			  struct TCP_Server_Info *server,
S
Steve French 已提交
223
			  __u32 expected_sequence_number)
L
Linus Torvalds 已提交
224
{
225
	unsigned int rc;
L
Linus Torvalds 已提交
226 227
	char server_response_sig[8];
	char what_we_think_sig_should_be[20];
228
	struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
L
Linus Torvalds 已提交
229

230
	if (cifs_pdu == NULL || server == NULL)
L
Linus Torvalds 已提交
231 232
		return -EINVAL;

233
	if (!server->session_estab)
L
Linus Torvalds 已提交
234 235 236
		return 0;

	if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
237
		struct smb_com_lock_req *pSMB =
S
Steve French 已提交
238 239
			(struct smb_com_lock_req *)cifs_pdu;
	    if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
L
Linus Torvalds 已提交
240 241 242
			return 0;
	}

243 244 245
	/* BB what if signatures are supposed to be on for session but
	   server does not send one? BB */

L
Linus Torvalds 已提交
246
	/* Do not need to verify session setups with signature "BSRSPYL "  */
247
	if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
248 249
		cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
			 cifs_pdu->Command);
L
Linus Torvalds 已提交
250 251 252

	/* save off the origiginal signature so we can modify the smb and check
		its signature against what the server sent */
253
	memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
L
Linus Torvalds 已提交
254

255 256
	cifs_pdu->Signature.Sequence.SequenceNumber =
					cpu_to_le32(expected_sequence_number);
L
Linus Torvalds 已提交
257 258
	cifs_pdu->Signature.Sequence.Reserved = 0;

259
	mutex_lock(&server->srv_mutex);
260
	rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
261
	mutex_unlock(&server->srv_mutex);
L
Linus Torvalds 已提交
262

263
	if (rc)
L
Linus Torvalds 已提交
264 265
		return rc;

266 267
/*	cifs_dump_mem("what we think it should be: ",
		      what_we_think_sig_should_be, 16); */
L
Linus Torvalds 已提交
268

269
	if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
L
Linus Torvalds 已提交
270 271 272 273 274 275
		return -EACCES;
	else
		return 0;

}

276
/* first calculate 24 bytes ntlm response and then 16 byte session key */
277
int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
L
Linus Torvalds 已提交
278
{
279
	int rc = 0;
280 281 282 283
	unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
	char temp_key[CIFS_SESS_KEY_SIZE];

	if (!ses)
L
Linus Torvalds 已提交
284 285
		return -EINVAL;

286
	ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
287
	if (!ses->auth_key.response)
288
		return -ENOMEM;
289

290 291
	ses->auth_key.len = temp_len;

292
	rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
293
			ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
294
	if (rc) {
295 296
		cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
			 __func__, rc);
297 298 299
		return rc;
	}

300
	rc = E_md4hash(ses->password, temp_key, nls_cp);
301
	if (rc) {
302 303
		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
			 __func__, rc);
304 305
		return rc;
	}
306

307 308
	rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
	if (rc)
309 310
		cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
			 __func__, rc);
311

312
	return rc;
L
Linus Torvalds 已提交
313 314
}

315
#ifdef CONFIG_CIFS_WEAK_PW_HASH
316
int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
317
			char *lnm_session_key)
318 319
{
	int i;
320
	int rc;
321 322 323
	char password_with_pad[CIFS_ENCPWD_SIZE];

	memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
324 325 326
	if (password)
		strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);

327
	if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
328 329
		memcpy(lnm_session_key, password_with_pad,
			CIFS_ENCPWD_SIZE);
330
		return 0;
331
	}
332

333 334 335 336 337 338 339 340 341 342 343
	/* calculate old style session key */
	/* calling toupper is less broken than repeatedly
	calling nls_toupper would be since that will never
	work for UTF8, but neither handles multibyte code pages
	but the only alternative would be converting to UCS-16 (Unicode)
	(using a routine something like UniStrupr) then
	uppercasing and then converting back from Unicode - which
	would only worth doing it if we knew it were utf8. Basically
	utf8 and other multibyte codepages each need their own strupper
	function since a byte at a time will ont work. */

344
	for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
345 346
		password_with_pad[i] = toupper(password_with_pad[i]);

347
	rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
348

349
	return rc;
350 351 352
}
#endif /* CIFS_WEAK_PW_HASH */

353 354 355 356
/* Build a proper attribute value/target info pairs blob.
 * Fill in netbios and dns domain name and workstation name
 * and client time (total five av pairs and + one end of fields indicator.
 * Allocate domain name which gets freed when session struct is deallocated.
357 358
 */
static int
359
build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
360
{
361
	unsigned int dlen;
362
	unsigned int size = 2 * sizeof(struct ntlmssp2_name);
363 364
	char *defdmname = "WORKGROUP";
	unsigned char *blobptr;
365 366
	struct ntlmssp2_name *attrptr;

367 368 369 370 371 372 373 374
	if (!ses->domainName) {
		ses->domainName = kstrdup(defdmname, GFP_KERNEL);
		if (!ses->domainName)
			return -ENOMEM;
	}

	dlen = strlen(ses->domainName);

375 376 377 378 379
	/*
	 * The length of this blob is two times the size of a
	 * structure (av pair) which holds name/size
	 * ( for NTLMSSP_AV_NB_DOMAIN_NAME followed by NTLMSSP_AV_EOL ) +
	 * unicode length of a netbios domain name
380
	 */
381
	ses->auth_key.len = size + 2 * dlen;
382 383 384
	ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
	if (!ses->auth_key.response) {
		ses->auth_key.len = 0;
385 386
		return -ENOMEM;
	}
387

388
	blobptr = ses->auth_key.response;
389 390
	attrptr = (struct ntlmssp2_name *) blobptr;

391 392 393 394
	/*
	 * As defined in MS-NTLM 3.3.2, just this av pair field
	 * is sufficient as part of the temp
	 */
395 396 397
	attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
	attrptr->length = cpu_to_le16(2 * dlen);
	blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
398
	cifs_strtoUTF16((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
399

400 401 402 403 404 405 406 407 408 409 410 411 412 413
	return 0;
}

/* Server has provided av pairs/target info in the type 2 challenge
 * packet and we have plucked it and stored within smb session.
 * We parse that blob here to find netbios domain name to be used
 * as part of ntlmv2 authentication (in Target String), if not already
 * specified on the command line.
 * If this function returns without any error but without fetching
 * domain name, authentication may fail against some server but
 * may not fail against other (those who are not very particular
 * about target string i.e. for some, just user name might suffice.
 */
static int
414
find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
415 416 417 418 419 420 421 422
{
	unsigned int attrsize;
	unsigned int type;
	unsigned int onesize = sizeof(struct ntlmssp2_name);
	unsigned char *blobptr;
	unsigned char *blobend;
	struct ntlmssp2_name *attrptr;

423
	if (!ses->auth_key.len || !ses->auth_key.response)
424 425
		return 0;

426 427
	blobptr = ses->auth_key.response;
	blobend = blobptr + ses->auth_key.len;
428 429 430 431 432 433 434 435 436 437 438 439

	while (blobptr + onesize < blobend) {
		attrptr = (struct ntlmssp2_name *) blobptr;
		type = le16_to_cpu(attrptr->type);
		if (type == NTLMSSP_AV_EOL)
			break;
		blobptr += 2; /* advance attr type */
		attrsize = le16_to_cpu(attrptr->length);
		blobptr += 2; /* advance attr size */
		if (blobptr + attrsize > blobend)
			break;
		if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
440
			if (!attrsize || attrsize >= CIFS_MAX_DOMAINNAME_LEN)
441 442 443 444 445 446
				break;
			if (!ses->domainName) {
				ses->domainName =
					kmalloc(attrsize + 1, GFP_KERNEL);
				if (!ses->domainName)
						return -ENOMEM;
447
				cifs_from_utf16(ses->domainName,
448
					(__le16 *)blobptr, attrsize, attrsize,
449
					nls_cp, NO_MAP_UNI_RSVD);
450 451 452 453 454 455 456 457 458
				break;
			}
		}
		blobptr += attrsize; /* advance attr  value */
	}

	return 0;
}

459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
/* Server has provided av pairs/target info in the type 2 challenge
 * packet and we have plucked it and stored within smb session.
 * We parse that blob here to find the server given timestamp
 * as part of ntlmv2 authentication (or local current time as
 * default in case of failure)
 */
static __le64
find_timestamp(struct cifs_ses *ses)
{
	unsigned int attrsize;
	unsigned int type;
	unsigned int onesize = sizeof(struct ntlmssp2_name);
	unsigned char *blobptr;
	unsigned char *blobend;
	struct ntlmssp2_name *attrptr;

	if (!ses->auth_key.len || !ses->auth_key.response)
		return 0;

	blobptr = ses->auth_key.response;
	blobend = blobptr + ses->auth_key.len;

	while (blobptr + onesize < blobend) {
		attrptr = (struct ntlmssp2_name *) blobptr;
		type = le16_to_cpu(attrptr->type);
		if (type == NTLMSSP_AV_EOL)
			break;
		blobptr += 2; /* advance attr type */
		attrsize = le16_to_cpu(attrptr->length);
		blobptr += 2; /* advance attr size */
		if (blobptr + attrsize > blobend)
			break;
		if (type == NTLMSSP_AV_TIMESTAMP) {
			if (attrsize == sizeof(u64))
				return *((__le64 *)blobptr);
		}
		blobptr += attrsize; /* advance attr value */
	}

	return cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
}

501
static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
502
			    const struct nls_table *nls_cp)
S
Steve French 已提交
503 504 505
{
	int rc = 0;
	int len;
506
	char nt_hash[CIFS_NTHASH_SIZE];
507
	__le16 *user;
508
	wchar_t *domain;
509
	wchar_t *server;
S
Steve French 已提交
510

511
	if (!ses->server->secmech.sdeschmacmd5) {
512
		cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
513 514
		return -1;
	}
515

516
	/* calculate md4 hash of password */
517
	E_md4hash(ses->password, nt_hash, nls_cp);
518

519
	rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
520
				CIFS_NTHASH_SIZE);
521
	if (rc) {
522
		cifs_dbg(VFS, "%s: Could not set NT Hash as a key\n", __func__);
523 524
		return rc;
	}
525 526 527

	rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
	if (rc) {
528
		cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__);
529 530
		return rc;
	}
S
Steve French 已提交
531

532
	/* convert ses->user_name to unicode */
J
Jeff Layton 已提交
533
	len = ses->user_name ? strlen(ses->user_name) : 0;
S
Steve French 已提交
534
	user = kmalloc(2 + (len * 2), GFP_KERNEL);
535 536
	if (user == NULL) {
		rc = -ENOMEM;
537
		return rc;
538
	}
J
Jeff Layton 已提交
539 540

	if (len) {
541
		len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp);
J
Jeff Layton 已提交
542 543 544 545
		UniStrupr(user);
	} else {
		memset(user, '\0', 2);
	}
546

547
	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
548
				(char *)user, 2 * len);
549 550
	kfree(user);
	if (rc) {
551
		cifs_dbg(VFS, "%s: Could not update with user\n", __func__);
552 553
		return rc;
	}
S
Steve French 已提交
554 555

	/* convert ses->domainName to unicode and uppercase */
556
	if (ses->domainName) {
S
Steve French 已提交
557
		len = strlen(ses->domainName);
S
Steve French 已提交
558

559
		domain = kmalloc(2 + (len * 2), GFP_KERNEL);
560 561
		if (domain == NULL) {
			rc = -ENOMEM;
562
			return rc;
563
		}
564 565
		len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len,
				      nls_cp);
566
		rc =
567 568
		crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
					(char *)domain, 2 * len);
S
Steve French 已提交
569
		kfree(domain);
570
		if (rc) {
571 572
			cifs_dbg(VFS, "%s: Could not update with domain\n",
				 __func__);
573 574
			return rc;
		}
575 576
	} else {
		/* We use ses->serverName if no domain name available */
577 578 579 580 581
		len = strlen(ses->serverName);

		server = kmalloc(2 + (len * 2), GFP_KERNEL);
		if (server == NULL) {
			rc = -ENOMEM;
582
			return rc;
583
		}
584
		len = cifs_strtoUTF16((__le16 *)server, ses->serverName, len,
585
					nls_cp);
586
		rc =
587 588 589
		crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
					(char *)server, 2 * len);
		kfree(server);
590
		if (rc) {
591 592
			cifs_dbg(VFS, "%s: Could not update with server\n",
				 __func__);
593 594
			return rc;
		}
S
Steve French 已提交
595
	}
596 597

	rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
598
					ntlmv2_hash);
599
	if (rc)
600
		cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
601 602 603 604 605

	return rc;
}

static int
606
CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
607 608
{
	int rc;
609 610 611 612 613 614 615
	struct ntlmv2_resp *ntlmv2 = (struct ntlmv2_resp *)
	    (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
	unsigned int hash_len;

	/* The MD5 hash starts at challenge_key.key */
	hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE +
		offsetof(struct ntlmv2_resp, challenge.key[0]));
616 617

	if (!ses->server->secmech.sdeschmacmd5) {
618
		cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
619 620 621
		return -1;
	}

622
	rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
623
				 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
624
	if (rc) {
625 626
		cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
			 __func__);
627 628
		return rc;
	}
629 630 631

	rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
	if (rc) {
632
		cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__);
633 634 635
		return rc;
	}

636
	if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED)
637 638
		memcpy(ntlmv2->challenge.key,
		       ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
639
	else
640 641
		memcpy(ntlmv2->challenge.key,
		       ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
642
	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
643
				 ntlmv2->challenge.key, hash_len);
644
	if (rc) {
645
		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
646 647
		return rc;
	}
648

649
	/* Note that the MD5 digest over writes anon.challenge_key.key */
650
	rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
651
				ntlmv2->ntlmv2_hash);
652
	if (rc)
653
		cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
654 655 656 657

	return rc;
}

658 659
static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server)
{
660
	int rc;
661 662 663 664 665 666 667 668 669
	unsigned int size;

	/* check if already allocated */
	if (server->secmech.sdeschmacmd5)
		return 0;

	server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
	if (IS_ERR(server->secmech.hmacmd5)) {
		cifs_dbg(VFS, "could not allocate crypto hmacmd5\n");
670 671 672
		rc = PTR_ERR(server->secmech.hmacmd5);
		server->secmech.hmacmd5 = NULL;
		return rc;
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
	}

	size = sizeof(struct shash_desc) +
			crypto_shash_descsize(server->secmech.hmacmd5);
	server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
	if (!server->secmech.sdeschmacmd5) {
		crypto_free_shash(server->secmech.hmacmd5);
		server->secmech.hmacmd5 = NULL;
		return -ENOMEM;
	}
	server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
	server->secmech.sdeschmacmd5->shash.flags = 0x0;

	return 0;
}
688

689
int
690
setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
691
{
692
	int rc;
693
	int baselen;
694
	unsigned int tilen;
695
	struct ntlmv2_resp *ntlmv2;
696 697
	char ntlmv2_hash[16];
	unsigned char *tiblob = NULL; /* target info blob */
698
	__le64 rsp_timestamp;
S
Steve French 已提交
699

700
	if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
701
		if (!ses->domainName) {
702
			rc = find_domain_name(ses, nls_cp);
703
			if (rc) {
704 705
				cifs_dbg(VFS, "error %d finding domain name\n",
					 rc);
706 707 708 709
				goto setup_ntlmv2_rsp_ret;
			}
		}
	} else {
710
		rc = build_avpair_blob(ses, nls_cp);
711
		if (rc) {
712
			cifs_dbg(VFS, "error %d building av pair blob\n", rc);
713
			goto setup_ntlmv2_rsp_ret;
714 715
		}
	}
S
Steve French 已提交
716

717 718 719 720 721 722
	/* Must be within 5 minutes of the server (or in range +/-2h
	 * in case of Mac OS X), so simply carry over server timestamp
	 * (as Windows 7 does)
	 */
	rsp_timestamp = find_timestamp(ses);

723
	baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
724 725 726 727
	tilen = ses->auth_key.len;
	tiblob = ses->auth_key.response;

	ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
728
	if (!ses->auth_key.response) {
729
		rc = -ENOMEM;
730
		ses->auth_key.len = 0;
731 732
		goto setup_ntlmv2_rsp_ret;
	}
733
	ses->auth_key.len += baselen;
734

735
	ntlmv2 = (struct ntlmv2_resp *)
736
			(ses->auth_key.response + CIFS_SESS_KEY_SIZE);
737 738
	ntlmv2->blob_signature = cpu_to_le32(0x00000101);
	ntlmv2->reserved = 0;
739 740
	ntlmv2->time = rsp_timestamp;

741 742
	get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal));
	ntlmv2->reserved2 = 0;
743

744
	memcpy(ses->auth_key.response + baselen, tiblob, tilen);
745

746 747
	mutex_lock(&ses->server->srv_mutex);

748 749 750
	rc = crypto_hmacmd5_alloc(ses->server);
	if (rc) {
		cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc);
751
		goto unlock;
752 753
	}

754
	/* calculate ntlmv2_hash */
755
	rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
756
	if (rc) {
757
		cifs_dbg(VFS, "could not get v2 hash rc %d\n", rc);
758
		goto unlock;
759
	}
760 761

	/* calculate first part of the client response (CR1) */
762
	rc = CalcNTLMv2_response(ses, ntlmv2_hash);
763
	if (rc) {
764
		cifs_dbg(VFS, "Could not calculate CR1 rc: %d\n", rc);
765
		goto unlock;
766
	}
767

768
	/* now calculate the session key for NTLMv2 */
769
	rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
770
		ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
771
	if (rc) {
772 773
		cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
			 __func__);
774
		goto unlock;
775
	}
776 777 778

	rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
	if (rc) {
779
		cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
780
		goto unlock;
781 782
	}

783
	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
784
		ntlmv2->ntlmv2_hash,
785
		CIFS_HMAC_MD5_HASH_SIZE);
786
	if (rc) {
787
		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
788
		goto unlock;
789
	}
790 791 792

	rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
		ses->auth_key.response);
793
	if (rc)
794
		cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
795

796 797
unlock:
	mutex_unlock(&ses->server->srv_mutex);
798
setup_ntlmv2_rsp_ret:
799
	kfree(tiblob);
800 801

	return rc;
S
Steve French 已提交
802 803
}

804
int
805
calc_seckey(struct cifs_ses *ses)
806 807
{
	int rc;
H
Herbert Xu 已提交
808
	struct crypto_skcipher *tfm_arc4;
809
	struct scatterlist sgin, sgout;
H
Herbert Xu 已提交
810
	struct skcipher_request *req;
S
Sachin Prabhu 已提交
811 812 813 814 815
	unsigned char *sec_key;

	sec_key = kmalloc(CIFS_SESS_KEY_SIZE, GFP_KERNEL);
	if (sec_key == NULL)
		return -ENOMEM;
816 817 818

	get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);

H
Herbert Xu 已提交
819
	tfm_arc4 = crypto_alloc_skcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
820 821
	if (IS_ERR(tfm_arc4)) {
		rc = PTR_ERR(tfm_arc4);
822
		cifs_dbg(VFS, "could not allocate crypto API arc4\n");
S
Sachin Prabhu 已提交
823
		goto out;
824 825
	}

H
Herbert Xu 已提交
826
	rc = crypto_skcipher_setkey(tfm_arc4, ses->auth_key.response,
827
					CIFS_SESS_KEY_SIZE);
828
	if (rc) {
829 830
		cifs_dbg(VFS, "%s: Could not set response as a key\n",
			 __func__);
H
Herbert Xu 已提交
831 832 833 834 835 836 837 838
		goto out_free_cipher;
	}

	req = skcipher_request_alloc(tfm_arc4, GFP_KERNEL);
	if (!req) {
		rc = -ENOMEM;
		cifs_dbg(VFS, "could not allocate crypto API arc4 request\n");
		goto out_free_cipher;
839
	}
840 841

	sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE);
842
	sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
843

H
Herbert Xu 已提交
844 845 846 847 848
	skcipher_request_set_callback(req, 0, NULL, NULL);
	skcipher_request_set_crypt(req, &sgin, &sgout, CIFS_CPHTXT_SIZE, NULL);

	rc = crypto_skcipher_encrypt(req);
	skcipher_request_free(req);
849
	if (rc) {
850
		cifs_dbg(VFS, "could not encrypt session key rc: %d\n", rc);
H
Herbert Xu 已提交
851
		goto out_free_cipher;
852 853 854 855 856 857 858
	}

	/* make secondary_key/nonce as session key */
	memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE);
	/* and make len as that of session key only */
	ses->auth_key.len = CIFS_SESS_KEY_SIZE;

H
Herbert Xu 已提交
859 860
out_free_cipher:
	crypto_free_skcipher(tfm_arc4);
S
Sachin Prabhu 已提交
861 862
out:
	kfree(sec_key);
863
	return rc;
864 865 866 867 868
}

void
cifs_crypto_shash_release(struct TCP_Server_Info *server)
{
869
	if (server->secmech.cmacaes) {
S
Steve French 已提交
870
		crypto_free_shash(server->secmech.cmacaes);
871 872
		server->secmech.cmacaes = NULL;
	}
S
Steve French 已提交
873

874
	if (server->secmech.hmacsha256) {
P
Pavel Shilovsky 已提交
875
		crypto_free_shash(server->secmech.hmacsha256);
876 877
		server->secmech.hmacsha256 = NULL;
	}
P
Pavel Shilovsky 已提交
878

879
	if (server->secmech.md5) {
880
		crypto_free_shash(server->secmech.md5);
881 882
		server->secmech.md5 = NULL;
	}
883

884
	if (server->secmech.hmacmd5) {
885
		crypto_free_shash(server->secmech.hmacmd5);
886 887
		server->secmech.hmacmd5 = NULL;
	}
888

S
Steve French 已提交
889
	kfree(server->secmech.sdesccmacaes);
890
	server->secmech.sdesccmacaes = NULL;
P
Pavel Shilovsky 已提交
891
	kfree(server->secmech.sdeschmacsha256);
892
	server->secmech.sdeschmacsha256 = NULL;
893
	kfree(server->secmech.sdeschmacmd5);
894
	server->secmech.sdeschmacmd5 = NULL;
895
	kfree(server->secmech.sdescmd5);
896
	server->secmech.sdescmd5 = NULL;
897
}