xref: /linux/fs/smb/server/auth.c (revision 50a400cff59f534254ace2828f2eb9d844517fbb)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
4  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
5  */
6 
7 #include <linux/kernel.h>
8 #include <linux/fs.h>
9 #include <linux/uaccess.h>
10 #include <linux/backing-dev.h>
11 #include <linux/writeback.h>
12 #include <linux/uio.h>
13 #include <linux/xattr.h>
14 #include <crypto/aead.h>
15 #include <crypto/aes-cbc-macs.h>
16 #include <crypto/md5.h>
17 #include <crypto/sha2.h>
18 #include <crypto/utils.h>
19 #include <linux/random.h>
20 #include <linux/scatterlist.h>
21 
22 #include "auth.h"
23 #include "glob.h"
24 
25 #include <linux/fips.h>
26 #include <crypto/arc4.h>
27 #include <crypto/des.h>
28 
29 #include "server.h"
30 #include "smb_common.h"
31 #include "connection.h"
32 #include "mgmt/user_session.h"
33 #include "mgmt/user_config.h"
34 #include "crypto_ctx.h"
35 #include "transport_ipc.h"
36 
37 /*
38  * Fixed format data defining GSS header and fixed string
39  * "not_defined_in_RFC4178@please_ignore".
40  * So sec blob data in neg phase could be generated statically.
41  */
42 static char NEGOTIATE_GSS_HEADER[AUTH_GSS_LENGTH] = {
43 #ifdef CONFIG_SMB_SERVER_KERBEROS5
44 	0x60, 0x5e, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
45 	0x05, 0x02, 0xa0, 0x54, 0x30, 0x52, 0xa0, 0x24,
46 	0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
47 	0xf7, 0x12, 0x01, 0x02, 0x02, 0x06, 0x09, 0x2a,
48 	0x86, 0x48, 0x82, 0xf7, 0x12, 0x01, 0x02, 0x02,
49 	0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
50 	0x37, 0x02, 0x02, 0x0a, 0xa3, 0x2a, 0x30, 0x28,
51 	0xa0, 0x26, 0x1b, 0x24, 0x6e, 0x6f, 0x74, 0x5f,
52 	0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f,
53 	0x69, 0x6e, 0x5f, 0x52, 0x46, 0x43, 0x34, 0x31,
54 	0x37, 0x38, 0x40, 0x70, 0x6c, 0x65, 0x61, 0x73,
55 	0x65, 0x5f, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65
56 #else
57 	0x60, 0x48, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
58 	0x05, 0x02, 0xa0, 0x3e, 0x30, 0x3c, 0xa0, 0x0e,
59 	0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
60 	0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa3, 0x2a,
61 	0x30, 0x28, 0xa0, 0x26, 0x1b, 0x24, 0x6e, 0x6f,
62 	0x74, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65,
63 	0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x52, 0x46, 0x43,
64 	0x34, 0x31, 0x37, 0x38, 0x40, 0x70, 0x6c, 0x65,
65 	0x61, 0x73, 0x65, 0x5f, 0x69, 0x67, 0x6e, 0x6f,
66 	0x72, 0x65
67 #endif
68 };
69 
70 void ksmbd_copy_gss_neg_header(void *buf)
71 {
72 	memcpy(buf, NEGOTIATE_GSS_HEADER, AUTH_GSS_LENGTH);
73 }
74 
75 static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
76 			    char *ntlmv2_hash, char *dname)
77 {
78 	int ret, len, conv_len;
79 	wchar_t *domain = NULL;
80 	__le16 *uniname = NULL;
81 	struct hmac_md5_ctx ctx;
82 
83 	hmac_md5_init_usingrawkey(&ctx, user_passkey(sess->user),
84 				  CIFS_ENCPWD_SIZE);
85 
86 	/* convert user_name to unicode */
87 	len = strlen(user_name(sess->user));
88 	uniname = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
89 	if (!uniname) {
90 		ret = -ENOMEM;
91 		goto out;
92 	}
93 
94 	conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
95 				  conn->local_nls);
96 	if (conv_len < 0 || conv_len > len) {
97 		ret = -EINVAL;
98 		goto out;
99 	}
100 	UniStrupr(uniname);
101 
102 	hmac_md5_update(&ctx, (const u8 *)uniname, UNICODE_LEN(conv_len));
103 
104 	/* Convert domain name or conn name to unicode and uppercase */
105 	len = strlen(dname);
106 	domain = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
107 	if (!domain) {
108 		ret = -ENOMEM;
109 		goto out;
110 	}
111 
112 	conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
113 				  conn->local_nls);
114 	if (conv_len < 0 || conv_len > len) {
115 		ret = -EINVAL;
116 		goto out;
117 	}
118 
119 	hmac_md5_update(&ctx, (const u8 *)domain, UNICODE_LEN(conv_len));
120 	hmac_md5_final(&ctx, ntlmv2_hash);
121 	ret = 0;
122 out:
123 	kfree(uniname);
124 	kfree(domain);
125 	if (ret)	/* Done by hmac_md5_final() already if ret == 0 */
126 		memzero_explicit(&ctx, sizeof(ctx));
127 	return ret;
128 }
129 
130 /**
131  * ksmbd_auth_ntlmv2() - NTLMv2 authentication handler
132  * @conn:		connection
133  * @sess:		session of connection
134  * @ntlmv2:		NTLMv2 challenge response
135  * @blen:		NTLMv2 blob length
136  * @domain_name:	domain name
137  * @cryptkey:		session crypto key
138  * @sess_key:		derived session key output buffer
139  *
140  * Return:	0 on success, error number on error
141  */
142 int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
143 		      struct ntlmv2_resp *ntlmv2, int blen, char *domain_name,
144 		      char *cryptkey, char *sess_key)
145 {
146 	char ntlmv2_hash[CIFS_ENCPWD_SIZE];
147 	char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
148 	char base_key[SMB2_NTLMV2_SESSKEY_SIZE];
149 	struct hmac_md5_ctx ctx;
150 	int rc;
151 
152 	if (fips_enabled) {
153 		ksmbd_debug(AUTH, "NTLMv2 support is disabled due to FIPS\n");
154 		return -EOPNOTSUPP;
155 	}
156 
157 	rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
158 	if (rc) {
159 		ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
160 		return rc;
161 	}
162 
163 	hmac_md5_init_usingrawkey(&ctx, ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
164 	hmac_md5_update(&ctx, cryptkey, CIFS_CRYPTO_KEY_SIZE);
165 	hmac_md5_update(&ctx, (const u8 *)&ntlmv2->blob_signature, blen);
166 	hmac_md5_final(&ctx, ntlmv2_rsp);
167 
168 	/* Generate the session key */
169 	hmac_md5_usingrawkey(ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE,
170 			     ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE,
171 			     base_key);
172 
173 	if (crypto_memneq(ntlmv2->ntlmv2_hash, ntlmv2_rsp,
174 			  CIFS_HMAC_MD5_HASH_SIZE)) {
175 		rc = -EINVAL;
176 		goto out;
177 	}
178 
179 	memcpy(sess_key, base_key, sizeof(base_key));
180 	rc = 0;
181 out:
182 	memzero_explicit(ntlmv2_hash, sizeof(ntlmv2_hash));
183 	memzero_explicit(ntlmv2_rsp, sizeof(ntlmv2_rsp));
184 	memzero_explicit(base_key, sizeof(base_key));
185 	return rc;
186 }
187 
188 /**
189  * ksmbd_decode_ntlmssp_auth_blob() - helper function to construct
190  * authenticate blob
191  * @authblob:	authenticate blob source pointer
192  * @blob_len:	length of the @authblob message
193  * @conn:	connection
194  * @sess:	session of connection
195  * @sess_key:	derived session key output buffer
196  *
197  * Return:	0 on success, error number on error
198  */
199 int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
200 				   int blob_len, struct ksmbd_conn *conn,
201 				   struct ksmbd_session *sess, char *sess_key)
202 {
203 	char *domain_name;
204 	unsigned int nt_off, dn_off;
205 	unsigned short nt_len, dn_len;
206 	int ret;
207 
208 	if (blob_len < sizeof(struct authenticate_message)) {
209 		ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
210 			    blob_len);
211 		return -EINVAL;
212 	}
213 
214 	if (memcmp(authblob->Signature, "NTLMSSP", 8)) {
215 		ksmbd_debug(AUTH, "blob signature incorrect %s\n",
216 			    authblob->Signature);
217 		return -EINVAL;
218 	}
219 
220 	nt_off = le32_to_cpu(authblob->NtChallengeResponse.BufferOffset);
221 	nt_len = le16_to_cpu(authblob->NtChallengeResponse.Length);
222 	dn_off = le32_to_cpu(authblob->DomainName.BufferOffset);
223 	dn_len = le16_to_cpu(authblob->DomainName.Length);
224 
225 	if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len ||
226 	    nt_len < CIFS_ENCPWD_SIZE)
227 		return -EINVAL;
228 
229 	/* TODO : use domain name that imported from configuration file */
230 	domain_name = smb_strndup_from_utf16((const char *)authblob + dn_off,
231 					     dn_len, true, conn->local_nls);
232 	if (IS_ERR(domain_name))
233 		return PTR_ERR(domain_name);
234 
235 	/* process NTLMv2 authentication */
236 	ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
237 		    domain_name);
238 	ret = ksmbd_auth_ntlmv2(conn, sess,
239 				(struct ntlmv2_resp *)((char *)authblob + nt_off),
240 				nt_len - CIFS_ENCPWD_SIZE,
241 				domain_name, conn->ntlmssp.cryptkey, sess_key);
242 	kfree(domain_name);
243 	if (ret)
244 		return ret;
245 
246 	/* The recovered secondary session key */
247 	if (conn->ntlmssp.client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) {
248 		struct arc4_ctx *ctx_arc4;
249 		unsigned int sess_key_off, sess_key_len;
250 
251 		sess_key_off = le32_to_cpu(authblob->SessionKey.BufferOffset);
252 		sess_key_len = le16_to_cpu(authblob->SessionKey.Length);
253 
254 		if (blob_len < (u64)sess_key_off + sess_key_len)
255 			return -EINVAL;
256 
257 		if (sess_key_len > CIFS_KEY_SIZE)
258 			return -EINVAL;
259 
260 		ctx_arc4 = kmalloc_obj(*ctx_arc4, KSMBD_DEFAULT_GFP);
261 		if (!ctx_arc4)
262 			return -ENOMEM;
263 
264 		arc4_setkey(ctx_arc4, sess_key, SMB2_NTLMV2_SESSKEY_SIZE);
265 		arc4_crypt(ctx_arc4, sess_key,
266 			   (char *)authblob + sess_key_off, sess_key_len);
267 		kfree_sensitive(ctx_arc4);
268 	}
269 
270 	return ret;
271 }
272 
273 /**
274  * ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
275  * negotiate blob
276  * @negblob: negotiate blob source pointer
277  * @blob_len:	length of the @authblob message
278  * @conn:	connection
279  *
280  */
281 int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
282 				  int blob_len, struct ksmbd_conn *conn)
283 {
284 	if (blob_len < sizeof(struct negotiate_message)) {
285 		ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
286 			    blob_len);
287 		return -EINVAL;
288 	}
289 
290 	if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
291 		ksmbd_debug(AUTH, "blob signature incorrect %s\n",
292 			    negblob->Signature);
293 		return -EINVAL;
294 	}
295 
296 	conn->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
297 	return 0;
298 }
299 
300 /**
301  * ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
302  * challenge blob
303  * @chgblob: challenge blob source pointer to initialize
304  * @conn:	connection
305  *
306  */
307 unsigned int
308 ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
309 				   struct ksmbd_conn *conn)
310 {
311 	struct target_info *tinfo;
312 	wchar_t *name;
313 	__u8 *target_name;
314 	unsigned int flags, blob_off, blob_len, type, target_info_len = 0;
315 	int len, uni_len, conv_len;
316 	int cflags = conn->ntlmssp.client_flags;
317 
318 	memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
319 	chgblob->MessageType = NtLmChallenge;
320 
321 	flags = NTLMSSP_NEGOTIATE_UNICODE |
322 		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
323 		NTLMSSP_NEGOTIATE_TARGET_INFO;
324 
325 	if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
326 		flags |= NTLMSSP_NEGOTIATE_SIGN;
327 		flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
328 				   NTLMSSP_NEGOTIATE_56);
329 	}
330 
331 	if (cflags & NTLMSSP_NEGOTIATE_SEAL && smb3_encryption_negotiated(conn))
332 		flags |= NTLMSSP_NEGOTIATE_SEAL;
333 
334 	if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
335 		flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
336 
337 	if (cflags & NTLMSSP_REQUEST_TARGET)
338 		flags |= NTLMSSP_REQUEST_TARGET;
339 
340 	if (conn->use_spnego &&
341 	    (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
342 		flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
343 
344 	if (cflags & NTLMSSP_NEGOTIATE_KEY_XCH)
345 		flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
346 
347 	chgblob->NegotiateFlags = cpu_to_le32(flags);
348 	len = strlen(ksmbd_netbios_name());
349 	name = kmalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
350 	if (!name)
351 		return -ENOMEM;
352 
353 	conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
354 				  conn->local_nls);
355 	if (conv_len < 0 || conv_len > len) {
356 		kfree(name);
357 		return -EINVAL;
358 	}
359 
360 	uni_len = UNICODE_LEN(conv_len);
361 
362 	blob_off = sizeof(struct challenge_message);
363 	blob_len = blob_off + uni_len;
364 
365 	chgblob->TargetName.Length = cpu_to_le16(uni_len);
366 	chgblob->TargetName.MaximumLength = cpu_to_le16(uni_len);
367 	chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
368 
369 	/* Initialize random conn challenge */
370 	get_random_bytes(conn->ntlmssp.cryptkey, sizeof(__u64));
371 	memcpy(chgblob->Challenge, conn->ntlmssp.cryptkey,
372 	       CIFS_CRYPTO_KEY_SIZE);
373 
374 	/* Add Target Information to security buffer */
375 	chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
376 
377 	target_name = (__u8 *)chgblob + blob_off;
378 	memcpy(target_name, name, uni_len);
379 	tinfo = (struct target_info *)(target_name + uni_len);
380 
381 	chgblob->TargetInfoArray.Length = 0;
382 	/* Add target info list for NetBIOS/DNS settings */
383 	for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
384 	     type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
385 		tinfo->Type = cpu_to_le16(type);
386 		tinfo->Length = cpu_to_le16(uni_len);
387 		memcpy(tinfo->Content, name, uni_len);
388 		tinfo = (struct target_info *)((char *)tinfo + 4 + uni_len);
389 		target_info_len += 4 + uni_len;
390 	}
391 
392 	/* Add terminator subblock */
393 	tinfo->Type = 0;
394 	tinfo->Length = 0;
395 	target_info_len += 4;
396 
397 	chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
398 	chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
399 	blob_len += target_info_len;
400 	kfree(name);
401 	ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
402 	return blob_len;
403 }
404 
405 #ifdef CONFIG_SMB_SERVER_KERBEROS5
406 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
407 			    int in_len, char *out_blob, int *out_len,
408 			    char *sess_key)
409 {
410 	struct ksmbd_spnego_authen_response *resp;
411 	struct ksmbd_login_response_ext *resp_ext = NULL;
412 	struct ksmbd_user *user = NULL;
413 	int retval;
414 
415 	resp = ksmbd_ipc_spnego_authen_request(in_blob, in_len);
416 	if (!resp) {
417 		ksmbd_debug(AUTH, "SPNEGO_AUTHEN_REQUEST failure\n");
418 		return -EINVAL;
419 	}
420 
421 	if (!(resp->login_response.status & KSMBD_USER_FLAG_OK)) {
422 		ksmbd_debug(AUTH, "krb5 authentication failure\n");
423 		retval = -EPERM;
424 		goto out;
425 	}
426 
427 	if (*out_len <= resp->spnego_blob_len) {
428 		ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
429 			    *out_len, resp->spnego_blob_len);
430 		retval = -EINVAL;
431 		goto out;
432 	}
433 
434 	if (resp->session_key_len > sizeof(sess->sess_key)) {
435 		ksmbd_debug(AUTH, "session key is too long\n");
436 		retval = -EINVAL;
437 		goto out;
438 	}
439 
440 	if (resp->login_response.status & KSMBD_USER_FLAG_EXTENSION)
441 		resp_ext = ksmbd_ipc_login_request_ext(resp->login_response.account);
442 
443 	user = ksmbd_alloc_user(&resp->login_response, resp_ext);
444 	kvfree(resp_ext);
445 	if (!user) {
446 		ksmbd_debug(AUTH, "login failure\n");
447 		retval = -ENOMEM;
448 		goto out;
449 	}
450 
451 	if (!sess->user) {
452 		/* First successful authentication */
453 		sess->user = user;
454 	} else {
455 		if (!ksmbd_compare_user(sess->user, user)) {
456 			ksmbd_debug(AUTH, "different user tried to reuse session\n");
457 			retval = -EKEYREJECTED;
458 			ksmbd_free_user(user);
459 			goto out;
460 		}
461 		ksmbd_free_user(user);
462 	}
463 
464 	memcpy(sess_key, resp->payload, resp->session_key_len);
465 	memcpy(out_blob, resp->payload + resp->session_key_len,
466 	       resp->spnego_blob_len);
467 	*out_len = resp->spnego_blob_len;
468 	sess->kerberos_expiry = resp->session_expiry;
469 	retval = 0;
470 out:
471 	kvfree_sensitive(resp, sizeof(*resp) + resp->session_key_len +
472 				resp->spnego_blob_len);
473 	return retval;
474 }
475 #else
476 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
477 			    int in_len, char *out_blob, int *out_len,
478 			    char *sess_key)
479 {
480 	return -EOPNOTSUPP;
481 }
482 #endif
483 
484 /**
485  * ksmbd_sign_smb2_pdu() - function to generate packet signing
486  * @conn:	connection
487  * @key:	signing key
488  * @iov:        buffer iov array
489  * @n_vec:	number of iovecs
490  * @sig:	signature value generated for client request packet
491  *
492  */
493 void ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
494 			 int n_vec, char *sig)
495 {
496 	struct hmac_sha256_ctx ctx;
497 	int i;
498 
499 	hmac_sha256_init_usingrawkey(&ctx, key, SMB2_NTLMV2_SESSKEY_SIZE);
500 	for (i = 0; i < n_vec; i++)
501 		hmac_sha256_update(&ctx, iov[i].iov_base, iov[i].iov_len);
502 	hmac_sha256_final(&ctx, sig);
503 }
504 
505 /**
506  * ksmbd_sign_smb3_pdu() - function to generate packet signing
507  * @conn:	connection
508  * @key:	signing key
509  * @iov:        buffer iov array
510  * @n_vec:	number of iovecs
511  * @sig:	signature value generated for client request packet
512  *
513  */
514 void ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
515 			 int n_vec, char *sig)
516 {
517 	struct aes_cmac_key cmac_key;
518 	struct aes_cmac_ctx cmac_ctx;
519 	int i;
520 
521 	/* This cannot fail, since we always pass a valid key length. */
522 	static_assert(SMB2_CMACAES_SIZE == AES_KEYSIZE_128);
523 	aes_cmac_preparekey(&cmac_key, key, SMB2_CMACAES_SIZE);
524 
525 	aes_cmac_init(&cmac_ctx, &cmac_key);
526 	for (i = 0; i < n_vec; i++)
527 		aes_cmac_update(&cmac_ctx, iov[i].iov_base, iov[i].iov_len);
528 	aes_cmac_final(&cmac_ctx, sig);
529 }
530 
531 struct derivation {
532 	struct kvec label;
533 	struct kvec context;
534 	bool binding;
535 };
536 
537 static void generate_key(struct ksmbd_conn *conn, const char *sess_key,
538 			 struct kvec label, struct kvec context, __u8 *key,
539 			 unsigned int key_size)
540 {
541 	unsigned char zero = 0x0;
542 	__u8 i[4] = {0, 0, 0, 1};
543 	__u8 L128[4] = {0, 0, 0, 128};
544 	__u8 L256[4] = {0, 0, 1, 0};
545 	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
546 	struct hmac_sha256_ctx ctx;
547 
548 	hmac_sha256_init_usingrawkey(&ctx, sess_key,
549 				     SMB2_NTLMV2_SESSKEY_SIZE);
550 	hmac_sha256_update(&ctx, i, 4);
551 	hmac_sha256_update(&ctx, label.iov_base, label.iov_len);
552 	hmac_sha256_update(&ctx, &zero, 1);
553 	hmac_sha256_update(&ctx, context.iov_base, context.iov_len);
554 
555 	if (key_size == SMB3_ENC_DEC_KEY_SIZE &&
556 	    (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
557 	     conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
558 		hmac_sha256_update(&ctx, L256, 4);
559 	else
560 		hmac_sha256_update(&ctx, L128, 4);
561 
562 	hmac_sha256_final(&ctx, prfhash);
563 	memcpy(key, prfhash, key_size);
564 	memzero_explicit(prfhash, sizeof(prfhash));
565 }
566 
567 static int generate_smb3signingkey(struct ksmbd_session *sess,
568 				   struct ksmbd_conn *conn,
569 				   const struct derivation *signing)
570 {
571 	struct channel *chann;
572 	char *key, *sess_key;
573 
574 	chann = lookup_chann_list(sess, conn);
575 	if (!chann)
576 		return 0;
577 
578 	if (conn->dialect >= SMB30_PROT_ID && signing->binding) {
579 		key = chann->smb3signingkey;
580 		sess_key = chann->sess_key;
581 	} else {
582 		key = sess->smb3signingkey;
583 		sess_key = sess->sess_key;
584 	}
585 
586 	generate_key(conn, sess_key, signing->label, signing->context, key,
587 		     SMB3_SIGN_KEY_SIZE);
588 
589 	if (!(conn->dialect >= SMB30_PROT_ID && signing->binding))
590 		memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
591 
592 	ksmbd_debug(AUTH, "generated SMB3 signing key\n");
593 	ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
594 	return 0;
595 }
596 
597 int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
598 			       struct ksmbd_conn *conn)
599 {
600 	struct derivation d;
601 
602 	d.label.iov_base = "SMB2AESCMAC";
603 	d.label.iov_len = 12;
604 	d.context.iov_base = "SmbSign";
605 	d.context.iov_len = 8;
606 	d.binding = conn->binding;
607 
608 	return generate_smb3signingkey(sess, conn, &d);
609 }
610 
611 int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
612 				struct ksmbd_conn *conn)
613 {
614 	struct derivation d;
615 
616 	d.label.iov_base = "SMBSigningKey";
617 	d.label.iov_len = 14;
618 	if (conn->binding) {
619 		struct preauth_session *preauth_sess;
620 
621 		preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
622 		if (!preauth_sess)
623 			return -ENOENT;
624 		d.context.iov_base = preauth_sess->Preauth_HashValue;
625 	} else {
626 		d.context.iov_base = sess->Preauth_HashValue;
627 	}
628 	d.context.iov_len = 64;
629 	d.binding = conn->binding;
630 
631 	return generate_smb3signingkey(sess, conn, &d);
632 }
633 
634 struct derivation_twin {
635 	struct derivation encryption;
636 	struct derivation decryption;
637 };
638 
639 static void generate_smb3encryptionkey(struct ksmbd_conn *conn,
640 				       struct ksmbd_session *sess,
641 				       const struct derivation_twin *ptwin)
642 {
643 	generate_key(conn, sess->sess_key, ptwin->encryption.label,
644 		     ptwin->encryption.context, sess->smb3encryptionkey,
645 		     SMB3_ENC_DEC_KEY_SIZE);
646 
647 	generate_key(conn, sess->sess_key, ptwin->decryption.label,
648 		     ptwin->decryption.context,
649 		     sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
650 
651 	ksmbd_debug(AUTH, "generated SMB3 encryption/decryption keys\n");
652 	ksmbd_debug(AUTH, "Cipher type   %d\n", conn->cipher_type);
653 	ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
654 }
655 
656 void ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
657 				   struct ksmbd_session *sess)
658 {
659 	struct derivation_twin twin;
660 	struct derivation *d;
661 
662 	d = &twin.encryption;
663 	d->label.iov_base = "SMB2AESCCM";
664 	d->label.iov_len = 11;
665 	d->context.iov_base = "ServerOut";
666 	d->context.iov_len = 10;
667 
668 	d = &twin.decryption;
669 	d->label.iov_base = "SMB2AESCCM";
670 	d->label.iov_len = 11;
671 	d->context.iov_base = "ServerIn ";
672 	d->context.iov_len = 10;
673 
674 	generate_smb3encryptionkey(conn, sess, &twin);
675 }
676 
677 void ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
678 				    struct ksmbd_session *sess)
679 {
680 	struct derivation_twin twin;
681 	struct derivation *d;
682 
683 	d = &twin.encryption;
684 	d->label.iov_base = "SMBS2CCipherKey";
685 	d->label.iov_len = 16;
686 	d->context.iov_base = sess->Preauth_HashValue;
687 	d->context.iov_len = 64;
688 
689 	d = &twin.decryption;
690 	d->label.iov_base = "SMBC2SCipherKey";
691 	d->label.iov_len = 16;
692 	d->context.iov_base = sess->Preauth_HashValue;
693 	d->context.iov_len = 64;
694 
695 	generate_smb3encryptionkey(conn, sess, &twin);
696 }
697 
698 int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
699 				     __u8 *pi_hash)
700 {
701 	struct smb2_hdr *rcv_hdr = smb_get_msg(buf);
702 	char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
703 	int msg_size = get_rfc1002_len(buf);
704 	struct sha512_ctx sha_ctx;
705 
706 	if (conn->preauth_info->Preauth_HashId !=
707 	    SMB2_PREAUTH_INTEGRITY_SHA512)
708 		return -EINVAL;
709 
710 	sha512_init(&sha_ctx);
711 	sha512_update(&sha_ctx, pi_hash, 64);
712 	sha512_update(&sha_ctx, all_bytes_msg, msg_size);
713 	sha512_final(&sha_ctx, pi_hash);
714 	return 0;
715 }
716 
717 static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id,
718 				    int enc, u8 *key)
719 {
720 	struct ksmbd_session *sess;
721 	u8 *ses_enc_key;
722 
723 	if (enc)
724 		sess = work->sess;
725 	else {
726 		/*
727 		 * An encrypted SESSION_SETUP request may reauthenticate an expired
728 		 * Kerberos session.  Keep using the established decryption key so
729 		 * that the command can reach the session setup handler. Other
730 		 * commands are rejected there with STATUS_NETWORK_SESSION_EXPIRED.
731 		 */
732 		sess = ksmbd_session_lookup(work->conn, ses_id);
733 		if (sess && sess->state != SMB2_SESSION_VALID &&
734 		    (sess->state != SMB2_SESSION_EXPIRED ||
735 		     !sess->kerberos_expiry)) {
736 			ksmbd_user_session_put(sess);
737 			sess = NULL;
738 		}
739 	}
740 	if (!sess)
741 		return -EINVAL;
742 
743 	ses_enc_key = enc ? sess->smb3encryptionkey :
744 		sess->smb3decryptionkey;
745 	memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
746 	if (!enc)
747 		ksmbd_user_session_put(sess);
748 
749 	return 0;
750 }
751 
752 static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
753 				   unsigned int buflen)
754 {
755 	void *addr;
756 
757 	if (is_vmalloc_addr(buf))
758 		addr = vmalloc_to_page(buf);
759 	else
760 		addr = virt_to_page(buf);
761 	sg_set_page(sg, addr, buflen, offset_in_page(buf));
762 }
763 
764 static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
765 					 u8 *sign)
766 {
767 	struct scatterlist *sg;
768 	unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
769 	int i, *nr_entries, total_entries = 0, sg_idx = 0;
770 
771 	if (!nvec)
772 		return NULL;
773 
774 	nr_entries = kzalloc_objs(int, nvec, KSMBD_DEFAULT_GFP);
775 	if (!nr_entries)
776 		return NULL;
777 
778 	for (i = 0; i < nvec - 1; i++) {
779 		unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
780 
781 		if (is_vmalloc_addr(iov[i + 1].iov_base)) {
782 			nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
783 					PAGE_SIZE - 1) >> PAGE_SHIFT) -
784 				(kaddr >> PAGE_SHIFT);
785 		} else {
786 			nr_entries[i]++;
787 		}
788 		total_entries += nr_entries[i];
789 	}
790 
791 	/* Add two entries for transform header and signature */
792 	total_entries += 2;
793 
794 	sg = kmalloc_objs(struct scatterlist, total_entries, KSMBD_DEFAULT_GFP);
795 	if (!sg) {
796 		kfree(nr_entries);
797 		return NULL;
798 	}
799 
800 	sg_init_table(sg, total_entries);
801 	smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
802 	for (i = 0; i < nvec - 1; i++) {
803 		void *data = iov[i + 1].iov_base;
804 		int len = iov[i + 1].iov_len;
805 
806 		if (is_vmalloc_addr(data)) {
807 			int j, offset = offset_in_page(data);
808 
809 			for (j = 0; j < nr_entries[i]; j++) {
810 				unsigned int bytes = PAGE_SIZE - offset;
811 
812 				if (!len)
813 					break;
814 
815 				if (bytes > len)
816 					bytes = len;
817 
818 				sg_set_page(&sg[sg_idx++],
819 					    vmalloc_to_page(data), bytes,
820 					    offset_in_page(data));
821 
822 				data += bytes;
823 				len -= bytes;
824 				offset = 0;
825 			}
826 		} else {
827 			sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
828 				    offset_in_page(data));
829 		}
830 	}
831 	smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
832 	kfree(nr_entries);
833 	return sg;
834 }
835 
836 int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
837 			unsigned int nvec, int enc)
838 {
839 	struct ksmbd_conn *conn = work->conn;
840 	struct smb2_transform_hdr *tr_hdr = smb_get_msg(iov[0].iov_base);
841 	unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
842 	int rc;
843 	DECLARE_CRYPTO_WAIT(wait);
844 	struct scatterlist *sg;
845 	u8 sign[SMB2_SIGNATURE_SIZE] = {};
846 	u8 key[SMB3_ENC_DEC_KEY_SIZE];
847 	struct aead_request *req;
848 	char *iv;
849 	unsigned int iv_len;
850 	struct crypto_aead *tfm;
851 	unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
852 	struct ksmbd_crypto_ctx *ctx;
853 
854 	rc = ksmbd_get_encryption_key(work,
855 				      le64_to_cpu(tr_hdr->SessionId),
856 				      enc,
857 				      key);
858 	if (rc) {
859 		pr_err("Could not get %scryption key\n", enc ? "en" : "de");
860 		return rc;
861 	}
862 
863 	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
864 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
865 		ctx = ksmbd_crypto_ctx_find_gcm();
866 	else
867 		ctx = ksmbd_crypto_ctx_find_ccm();
868 	if (!ctx) {
869 		pr_err("crypto alloc failed\n");
870 		rc = -ENOMEM;
871 		goto zeroize_key;
872 	}
873 
874 	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
875 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
876 		tfm = CRYPTO_GCM(ctx);
877 	else
878 		tfm = CRYPTO_CCM(ctx);
879 
880 	if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
881 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
882 		rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
883 	else
884 		rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
885 	if (rc) {
886 		pr_err("Failed to set aead key %d\n", rc);
887 		goto free_ctx;
888 	}
889 
890 	rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
891 	if (rc) {
892 		pr_err("Failed to set authsize %d\n", rc);
893 		goto free_ctx;
894 	}
895 
896 	req = aead_request_alloc(tfm, KSMBD_DEFAULT_GFP);
897 	if (!req) {
898 		rc = -ENOMEM;
899 		goto free_ctx;
900 	}
901 
902 	if (!enc) {
903 		memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
904 		crypt_len += SMB2_SIGNATURE_SIZE;
905 	}
906 
907 	sg = ksmbd_init_sg(iov, nvec, sign);
908 	if (!sg) {
909 		pr_err("Failed to init sg\n");
910 		rc = -ENOMEM;
911 		goto free_req;
912 	}
913 
914 	iv_len = crypto_aead_ivsize(tfm);
915 	iv = kzalloc(iv_len, KSMBD_DEFAULT_GFP);
916 	if (!iv) {
917 		rc = -ENOMEM;
918 		goto free_sg;
919 	}
920 
921 	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
922 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
923 		memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
924 	} else {
925 		iv[0] = 3;
926 		memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
927 	}
928 
929 	aead_request_set_crypt(req, sg, sg, crypt_len, iv);
930 	aead_request_set_ad(req, assoc_data_len);
931 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
932 				  CRYPTO_TFM_REQ_MAY_SLEEP,
933 				  crypto_req_done, &wait);
934 
935 	rc = crypto_wait_req(enc ? crypto_aead_encrypt(req) :
936 			     crypto_aead_decrypt(req), &wait);
937 	if (rc)
938 		goto free_iv;
939 
940 	if (enc)
941 		memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
942 
943 free_iv:
944 	kfree(iv);
945 free_sg:
946 	kfree(sg);
947 free_req:
948 	aead_request_free(req);
949 free_ctx:
950 	ksmbd_release_crypto_ctx(ctx);
951 zeroize_key:
952 	memzero_explicit(key, sizeof(key));
953 	memzero_explicit(sign, sizeof(sign));
954 	return rc;
955 }
956