cifsencrypt.c 24.7 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>
37
#include <crypto/aead.h>
L
Linus Torvalds 已提交
38

39 40 41 42 43 44 45 46 47 48 49 50
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");
51 52 53
		rc = PTR_ERR(server->secmech.md5);
		server->secmech.md5 = NULL;
		return rc;
54 55 56 57 58 59 60 61
	}

	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;
62
		return -ENOMEM;
63 64 65 66 67 68 69
	}
	server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
	server->secmech.sdescmd5->shash.flags = 0x0;

	return 0;
}

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

79 80 81 82
	if (n_vec < 2 || iov[0].iov_len != 4)
		return -EIO;

	for (i = 1; i < n_vec; i++) {
83 84
		if (iov[i].iov_len == 0)
			continue;
S
Steve French 已提交
85
		if (iov[i].iov_base == NULL) {
86
			cifs_dbg(VFS, "null iovec entry\n");
87
			return -EIO;
88
		}
89 90 91 92
		if (i == 1 && iov[1].iov_len <= 4)
			break; /* nothing to sign or corrupt header */
		rc = crypto_shash_update(shash,
					 iov[i].iov_base, iov[i].iov_len);
93
		if (rc) {
94 95
			cifs_dbg(VFS, "%s: Could not update with payload\n",
				 __func__);
96 97
			return rc;
		}
98
	}
99

100 101
	/* now hash over the rq_pages array */
	for (i = 0; i < rqst->rq_npages; i++) {
102 103 104 105 106 107 108
		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);
109 110 111 112

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

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

117
	return rc;
118 119
}

120 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
/*
 * 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);
}

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

168 169 170 171
	if (rqst->rq_iov[0].iov_len != 4 ||
	    rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
		return -EIO;

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

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

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

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

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

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

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

200 201 202 203 204 205 206 207 208
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);
}

209 210 211 212
/* 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)
{
213
	struct kvec iov[2];
214

215 216 217 218
	iov[0].iov_base = cifs_pdu;
	iov[0].iov_len = 4;
	iov[1].iov_base = (char *)cifs_pdu + 4;
	iov[1].iov_len = be32_to_cpu(cifs_pdu->smb_buf_length);
219

220
	return cifs_sign_smbv(iov, 2, server,
221 222 223
			      pexpected_response_sequence_number);
}

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

233 234 235 236
	if (rqst->rq_iov[0].iov_len != 4 ||
	    rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
		return -EIO;

237
	if (cifs_pdu == NULL || server == NULL)
L
Linus Torvalds 已提交
238 239
		return -EINVAL;

240
	if (!server->session_estab)
L
Linus Torvalds 已提交
241 242 243
		return 0;

	if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
244
		struct smb_com_lock_req *pSMB =
S
Steve French 已提交
245 246
			(struct smb_com_lock_req *)cifs_pdu;
	    if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
L
Linus Torvalds 已提交
247 248 249
			return 0;
	}

250 251 252
	/* BB what if signatures are supposed to be on for session but
	   server does not send one? BB */

L
Linus Torvalds 已提交
253
	/* Do not need to verify session setups with signature "BSRSPYL "  */
254
	if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
255 256
		cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
			 cifs_pdu->Command);
L
Linus Torvalds 已提交
257 258 259

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

262 263
	cifs_pdu->Signature.Sequence.SequenceNumber =
					cpu_to_le32(expected_sequence_number);
L
Linus Torvalds 已提交
264 265
	cifs_pdu->Signature.Sequence.Reserved = 0;

266
	mutex_lock(&server->srv_mutex);
267
	rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
268
	mutex_unlock(&server->srv_mutex);
L
Linus Torvalds 已提交
269

270
	if (rc)
L
Linus Torvalds 已提交
271 272
		return rc;

273 274
/*	cifs_dump_mem("what we think it should be: ",
		      what_we_think_sig_should_be, 16); */
L
Linus Torvalds 已提交
275

276
	if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
L
Linus Torvalds 已提交
277 278 279 280 281 282
		return -EACCES;
	else
		return 0;

}

283
/* first calculate 24 bytes ntlm response and then 16 byte session key */
284
int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
L
Linus Torvalds 已提交
285
{
286
	int rc = 0;
287 288 289 290
	unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
	char temp_key[CIFS_SESS_KEY_SIZE];

	if (!ses)
L
Linus Torvalds 已提交
291 292
		return -EINVAL;

293
	ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
294
	if (!ses->auth_key.response)
295
		return -ENOMEM;
296

297 298
	ses->auth_key.len = temp_len;

299
	rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
300
			ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
301
	if (rc) {
302 303
		cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
			 __func__, rc);
304 305 306
		return rc;
	}

307
	rc = E_md4hash(ses->password, temp_key, nls_cp);
308
	if (rc) {
309 310
		cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
			 __func__, rc);
311 312
		return rc;
	}
313

314 315
	rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
	if (rc)
316 317
		cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
			 __func__, rc);
318

319
	return rc;
L
Linus Torvalds 已提交
320 321
}

322
#ifdef CONFIG_CIFS_WEAK_PW_HASH
323
int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
324
			char *lnm_session_key)
325 326
{
	int i;
327
	int rc;
328 329 330
	char password_with_pad[CIFS_ENCPWD_SIZE];

	memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
331 332 333
	if (password)
		strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);

334
	if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
335 336
		memcpy(lnm_session_key, password_with_pad,
			CIFS_ENCPWD_SIZE);
337
		return 0;
338
	}
339

340 341 342 343 344 345 346 347 348 349 350
	/* 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. */

351
	for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
352 353
		password_with_pad[i] = toupper(password_with_pad[i]);

354
	rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
355

356
	return rc;
357 358 359
}
#endif /* CIFS_WEAK_PW_HASH */

360 361 362 363
/* 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.
364 365
 */
static int
366
build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
367
{
368
	unsigned int dlen;
369
	unsigned int size = 2 * sizeof(struct ntlmssp2_name);
370 371
	char *defdmname = "WORKGROUP";
	unsigned char *blobptr;
372 373
	struct ntlmssp2_name *attrptr;

374 375 376 377 378 379 380 381
	if (!ses->domainName) {
		ses->domainName = kstrdup(defdmname, GFP_KERNEL);
		if (!ses->domainName)
			return -ENOMEM;
	}

	dlen = strlen(ses->domainName);

382 383 384 385 386
	/*
	 * 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
387
	 */
388
	ses->auth_key.len = size + 2 * dlen;
389 390 391
	ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
	if (!ses->auth_key.response) {
		ses->auth_key.len = 0;
392 393
		return -ENOMEM;
	}
394

395
	blobptr = ses->auth_key.response;
396 397
	attrptr = (struct ntlmssp2_name *) blobptr;

398 399 400 401
	/*
	 * As defined in MS-NTLM 3.3.2, just this av pair field
	 * is sufficient as part of the temp
	 */
402 403 404
	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);
405
	cifs_strtoUTF16((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
406

407 408 409 410 411 412 413 414 415 416 417 418 419 420
	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
421
find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
422 423 424 425 426 427 428 429
{
	unsigned int attrsize;
	unsigned int type;
	unsigned int onesize = sizeof(struct ntlmssp2_name);
	unsigned char *blobptr;
	unsigned char *blobend;
	struct ntlmssp2_name *attrptr;

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

433 434
	blobptr = ses->auth_key.response;
	blobend = blobptr + ses->auth_key.len;
435 436 437 438 439 440 441 442 443 444 445 446

	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) {
447
			if (!attrsize || attrsize >= CIFS_MAX_DOMAINNAME_LEN)
448 449 450 451 452 453
				break;
			if (!ses->domainName) {
				ses->domainName =
					kmalloc(attrsize + 1, GFP_KERNEL);
				if (!ses->domainName)
						return -ENOMEM;
454
				cifs_from_utf16(ses->domainName,
455
					(__le16 *)blobptr, attrsize, attrsize,
456
					nls_cp, NO_MAP_UNI_RSVD);
457 458 459 460 461 462 463 464 465
				break;
			}
		}
		blobptr += attrsize; /* advance attr  value */
	}

	return 0;
}

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 501 502 503 504 505 506 507
/* 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));
}

508
static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
509
			    const struct nls_table *nls_cp)
S
Steve French 已提交
510 511 512
{
	int rc = 0;
	int len;
513
	char nt_hash[CIFS_NTHASH_SIZE];
514
	__le16 *user;
515
	wchar_t *domain;
516
	wchar_t *server;
S
Steve French 已提交
517

518
	if (!ses->server->secmech.sdeschmacmd5) {
519
		cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
520 521
		return -1;
	}
522

523
	/* calculate md4 hash of password */
524
	E_md4hash(ses->password, nt_hash, nls_cp);
525

526
	rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
527
				CIFS_NTHASH_SIZE);
528
	if (rc) {
529
		cifs_dbg(VFS, "%s: Could not set NT Hash as a key\n", __func__);
530 531
		return rc;
	}
532 533 534

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

539
	/* convert ses->user_name to unicode */
J
Jeff Layton 已提交
540
	len = ses->user_name ? strlen(ses->user_name) : 0;
S
Steve French 已提交
541
	user = kmalloc(2 + (len * 2), GFP_KERNEL);
542 543
	if (user == NULL) {
		rc = -ENOMEM;
544
		return rc;
545
	}
J
Jeff Layton 已提交
546 547

	if (len) {
548
		len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp);
J
Jeff Layton 已提交
549 550 551 552
		UniStrupr(user);
	} else {
		memset(user, '\0', 2);
	}
553

554
	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
555
				(char *)user, 2 * len);
556 557
	kfree(user);
	if (rc) {
558
		cifs_dbg(VFS, "%s: Could not update with user\n", __func__);
559 560
		return rc;
	}
S
Steve French 已提交
561 562

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

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

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

	rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
605
					ntlmv2_hash);
606
	if (rc)
607
		cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
608 609 610 611 612

	return rc;
}

static int
613
CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
614 615
{
	int rc;
616 617 618 619 620 621 622
	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]));
623 624

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

629
	rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
630
				 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
631
	if (rc) {
632 633
		cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
			 __func__);
634 635
		return rc;
	}
636 637 638

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

643
	if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED)
644 645
		memcpy(ntlmv2->challenge.key,
		       ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
646
	else
647 648
		memcpy(ntlmv2->challenge.key,
		       ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
649
	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
650
				 ntlmv2->challenge.key, hash_len);
651
	if (rc) {
652
		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
653 654
		return rc;
	}
655

656
	/* Note that the MD5 digest over writes anon.challenge_key.key */
657
	rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
658
				ntlmv2->ntlmv2_hash);
659
	if (rc)
660
		cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
661 662 663 664

	return rc;
}

665 666
static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server)
{
667
	int rc;
668 669 670 671 672 673 674 675 676
	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");
677 678 679
		rc = PTR_ERR(server->secmech.hmacmd5);
		server->secmech.hmacmd5 = NULL;
		return rc;
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
	}

	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;
}
695

696
int
697
setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
698
{
699
	int rc;
700
	int baselen;
701
	unsigned int tilen;
702
	struct ntlmv2_resp *ntlmv2;
703 704
	char ntlmv2_hash[16];
	unsigned char *tiblob = NULL; /* target info blob */
705
	__le64 rsp_timestamp;
S
Steve French 已提交
706

707
	if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
708
		if (!ses->domainName) {
709 710 711 712 713 714 715 716 717
			if (ses->domainAuto) {
				rc = find_domain_name(ses, nls_cp);
				if (rc) {
					cifs_dbg(VFS, "error %d finding domain name\n",
						 rc);
					goto setup_ntlmv2_rsp_ret;
				}
			} else {
				ses->domainName = kstrdup("", GFP_KERNEL);
718 719 720
			}
		}
	} else {
721
		rc = build_avpair_blob(ses, nls_cp);
722
		if (rc) {
723
			cifs_dbg(VFS, "error %d building av pair blob\n", rc);
724
			goto setup_ntlmv2_rsp_ret;
725 726
		}
	}
S
Steve French 已提交
727

728 729 730 731 732 733
	/* 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);

734
	baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
735 736 737 738
	tilen = ses->auth_key.len;
	tiblob = ses->auth_key.response;

	ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
739
	if (!ses->auth_key.response) {
740
		rc = -ENOMEM;
741
		ses->auth_key.len = 0;
742 743
		goto setup_ntlmv2_rsp_ret;
	}
744
	ses->auth_key.len += baselen;
745

746
	ntlmv2 = (struct ntlmv2_resp *)
747
			(ses->auth_key.response + CIFS_SESS_KEY_SIZE);
748 749
	ntlmv2->blob_signature = cpu_to_le32(0x00000101);
	ntlmv2->reserved = 0;
750 751
	ntlmv2->time = rsp_timestamp;

752 753
	get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal));
	ntlmv2->reserved2 = 0;
754

755
	memcpy(ses->auth_key.response + baselen, tiblob, tilen);
756

757 758
	mutex_lock(&ses->server->srv_mutex);

759 760 761
	rc = crypto_hmacmd5_alloc(ses->server);
	if (rc) {
		cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc);
762
		goto unlock;
763 764
	}

765
	/* calculate ntlmv2_hash */
766
	rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
767
	if (rc) {
768
		cifs_dbg(VFS, "could not get v2 hash rc %d\n", rc);
769
		goto unlock;
770
	}
771 772

	/* calculate first part of the client response (CR1) */
773
	rc = CalcNTLMv2_response(ses, ntlmv2_hash);
774
	if (rc) {
775
		cifs_dbg(VFS, "Could not calculate CR1 rc: %d\n", rc);
776
		goto unlock;
777
	}
778

779
	/* now calculate the session key for NTLMv2 */
780
	rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
781
		ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
782
	if (rc) {
783 784
		cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
			 __func__);
785
		goto unlock;
786
	}
787 788 789

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

794
	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
795
		ntlmv2->ntlmv2_hash,
796
		CIFS_HMAC_MD5_HASH_SIZE);
797
	if (rc) {
798
		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
799
		goto unlock;
800
	}
801 802 803

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

807 808
unlock:
	mutex_unlock(&ses->server->srv_mutex);
809
setup_ntlmv2_rsp_ret:
810
	kfree(tiblob);
811 812

	return rc;
S
Steve French 已提交
813 814
}

815
int
816
calc_seckey(struct cifs_ses *ses)
817 818
{
	int rc;
H
Herbert Xu 已提交
819
	struct crypto_skcipher *tfm_arc4;
820
	struct scatterlist sgin, sgout;
H
Herbert Xu 已提交
821
	struct skcipher_request *req;
S
Sachin Prabhu 已提交
822 823 824 825 826
	unsigned char *sec_key;

	sec_key = kmalloc(CIFS_SESS_KEY_SIZE, GFP_KERNEL);
	if (sec_key == NULL)
		return -ENOMEM;
827 828 829

	get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);

H
Herbert Xu 已提交
830
	tfm_arc4 = crypto_alloc_skcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
831 832
	if (IS_ERR(tfm_arc4)) {
		rc = PTR_ERR(tfm_arc4);
833
		cifs_dbg(VFS, "could not allocate crypto API arc4\n");
S
Sachin Prabhu 已提交
834
		goto out;
835 836
	}

H
Herbert Xu 已提交
837
	rc = crypto_skcipher_setkey(tfm_arc4, ses->auth_key.response,
838
					CIFS_SESS_KEY_SIZE);
839
	if (rc) {
840 841
		cifs_dbg(VFS, "%s: Could not set response as a key\n",
			 __func__);
H
Herbert Xu 已提交
842 843 844 845 846 847 848 849
		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;
850
	}
851 852

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

H
Herbert Xu 已提交
855 856 857 858 859
	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);
860
	if (rc) {
861
		cifs_dbg(VFS, "could not encrypt session key rc: %d\n", rc);
H
Herbert Xu 已提交
862
		goto out_free_cipher;
863 864 865 866 867 868 869
	}

	/* 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 已提交
870 871
out_free_cipher:
	crypto_free_skcipher(tfm_arc4);
S
Sachin Prabhu 已提交
872 873
out:
	kfree(sec_key);
874
	return rc;
875 876 877
}

void
878
cifs_crypto_secmech_release(struct TCP_Server_Info *server)
879
{
880
	if (server->secmech.cmacaes) {
S
Steve French 已提交
881
		crypto_free_shash(server->secmech.cmacaes);
882 883
		server->secmech.cmacaes = NULL;
	}
S
Steve French 已提交
884

885
	if (server->secmech.hmacsha256) {
P
Pavel Shilovsky 已提交
886
		crypto_free_shash(server->secmech.hmacsha256);
887 888
		server->secmech.hmacsha256 = NULL;
	}
P
Pavel Shilovsky 已提交
889

890
	if (server->secmech.md5) {
891
		crypto_free_shash(server->secmech.md5);
892 893
		server->secmech.md5 = NULL;
	}
894

895
	if (server->secmech.hmacmd5) {
896
		crypto_free_shash(server->secmech.hmacmd5);
897 898
		server->secmech.hmacmd5 = NULL;
	}
899

900 901 902 903 904 905 906 907 908 909
	if (server->secmech.ccmaesencrypt) {
		crypto_free_aead(server->secmech.ccmaesencrypt);
		server->secmech.ccmaesencrypt = NULL;
	}

	if (server->secmech.ccmaesdecrypt) {
		crypto_free_aead(server->secmech.ccmaesdecrypt);
		server->secmech.ccmaesdecrypt = NULL;
	}

S
Steve French 已提交
910
	kfree(server->secmech.sdesccmacaes);
911
	server->secmech.sdesccmacaes = NULL;
P
Pavel Shilovsky 已提交
912
	kfree(server->secmech.sdeschmacsha256);
913
	server->secmech.sdeschmacsha256 = NULL;
914
	kfree(server->secmech.sdeschmacmd5);
915
	server->secmech.sdeschmacmd5 = NULL;
916
	kfree(server->secmech.sdescmd5);
917
	server->secmech.sdescmd5 = NULL;
918
}