xref: /linux/fs/smb/server/auth.c (revision 63e62baaa72e1aceb422f64a50408bc9b02a6022)
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/hash.h>
15 #include <crypto/aead.h>
16 #include <linux/random.h>
17 #include <linux/scatterlist.h>
18 
19 #include "auth.h"
20 #include "glob.h"
21 
22 #include <linux/fips.h>
23 #include <crypto/arc4.h>
24 #include <crypto/des.h>
25 
26 #include "server.h"
27 #include "smb_common.h"
28 #include "connection.h"
29 #include "mgmt/user_session.h"
30 #include "mgmt/user_config.h"
31 #include "crypto_ctx.h"
32 #include "transport_ipc.h"
33 
34 /*
35  * Fixed format data defining GSS header and fixed string
36  * "not_defined_in_RFC4178@please_ignore".
37  * So sec blob data in neg phase could be generated statically.
38  */
39 static char NEGOTIATE_GSS_HEADER[AUTH_GSS_LENGTH] = {
40 #ifdef CONFIG_SMB_SERVER_KERBEROS5
41 	0x60, 0x5e, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
42 	0x05, 0x02, 0xa0, 0x54, 0x30, 0x52, 0xa0, 0x24,
43 	0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
44 	0xf7, 0x12, 0x01, 0x02, 0x02, 0x06, 0x09, 0x2a,
45 	0x86, 0x48, 0x82, 0xf7, 0x12, 0x01, 0x02, 0x02,
46 	0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
47 	0x37, 0x02, 0x02, 0x0a, 0xa3, 0x2a, 0x30, 0x28,
48 	0xa0, 0x26, 0x1b, 0x24, 0x6e, 0x6f, 0x74, 0x5f,
49 	0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f,
50 	0x69, 0x6e, 0x5f, 0x52, 0x46, 0x43, 0x34, 0x31,
51 	0x37, 0x38, 0x40, 0x70, 0x6c, 0x65, 0x61, 0x73,
52 	0x65, 0x5f, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65
53 #else
54 	0x60, 0x48, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
55 	0x05, 0x02, 0xa0, 0x3e, 0x30, 0x3c, 0xa0, 0x0e,
56 	0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
57 	0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa3, 0x2a,
58 	0x30, 0x28, 0xa0, 0x26, 0x1b, 0x24, 0x6e, 0x6f,
59 	0x74, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65,
60 	0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x52, 0x46, 0x43,
61 	0x34, 0x31, 0x37, 0x38, 0x40, 0x70, 0x6c, 0x65,
62 	0x61, 0x73, 0x65, 0x5f, 0x69, 0x67, 0x6e, 0x6f,
63 	0x72, 0x65
64 #endif
65 };
66 
ksmbd_copy_gss_neg_header(void * buf)67 void ksmbd_copy_gss_neg_header(void *buf)
68 {
69 	memcpy(buf, NEGOTIATE_GSS_HEADER, AUTH_GSS_LENGTH);
70 }
71 
72 /**
73  * ksmbd_gen_sess_key() - function to generate session key
74  * @sess:	session of connection
75  * @hash:	source hash value to be used for find session key
76  * @hmac:	source hmac value to be used for finding session key
77  *
78  */
ksmbd_gen_sess_key(struct ksmbd_session * sess,char * hash,char * hmac)79 static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
80 			      char *hmac)
81 {
82 	struct ksmbd_crypto_ctx *ctx;
83 	int rc;
84 
85 	ctx = ksmbd_crypto_ctx_find_hmacmd5();
86 	if (!ctx) {
87 		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
88 		return -ENOMEM;
89 	}
90 
91 	rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
92 				 hash,
93 				 CIFS_HMAC_MD5_HASH_SIZE);
94 	if (rc) {
95 		ksmbd_debug(AUTH, "hmacmd5 set key fail error %d\n", rc);
96 		goto out;
97 	}
98 
99 	rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
100 	if (rc) {
101 		ksmbd_debug(AUTH, "could not init hmacmd5 error %d\n", rc);
102 		goto out;
103 	}
104 
105 	rc = crypto_shash_update(CRYPTO_HMACMD5(ctx),
106 				 hmac,
107 				 SMB2_NTLMV2_SESSKEY_SIZE);
108 	if (rc) {
109 		ksmbd_debug(AUTH, "Could not update with response error %d\n", rc);
110 		goto out;
111 	}
112 
113 	rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
114 	if (rc) {
115 		ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n", rc);
116 		goto out;
117 	}
118 
119 out:
120 	ksmbd_release_crypto_ctx(ctx);
121 	return rc;
122 }
123 
calc_ntlmv2_hash(struct ksmbd_conn * conn,struct ksmbd_session * sess,char * ntlmv2_hash,char * dname)124 static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
125 			    char *ntlmv2_hash, char *dname)
126 {
127 	int ret, len, conv_len;
128 	wchar_t *domain = NULL;
129 	__le16 *uniname = NULL;
130 	struct ksmbd_crypto_ctx *ctx;
131 
132 	ctx = ksmbd_crypto_ctx_find_hmacmd5();
133 	if (!ctx) {
134 		ksmbd_debug(AUTH, "can't generate ntlmv2 hash\n");
135 		return -ENOMEM;
136 	}
137 
138 	ret = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
139 				  user_passkey(sess->user),
140 				  CIFS_ENCPWD_SIZE);
141 	if (ret) {
142 		ksmbd_debug(AUTH, "Could not set NT Hash as a key\n");
143 		goto out;
144 	}
145 
146 	ret = crypto_shash_init(CRYPTO_HMACMD5(ctx));
147 	if (ret) {
148 		ksmbd_debug(AUTH, "could not init hmacmd5\n");
149 		goto out;
150 	}
151 
152 	/* convert user_name to unicode */
153 	len = strlen(user_name(sess->user));
154 	uniname = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
155 	if (!uniname) {
156 		ret = -ENOMEM;
157 		goto out;
158 	}
159 
160 	conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
161 				  conn->local_nls);
162 	if (conv_len < 0 || conv_len > len) {
163 		ret = -EINVAL;
164 		goto out;
165 	}
166 	UniStrupr(uniname);
167 
168 	ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
169 				  (char *)uniname,
170 				  UNICODE_LEN(conv_len));
171 	if (ret) {
172 		ksmbd_debug(AUTH, "Could not update with user\n");
173 		goto out;
174 	}
175 
176 	/* Convert domain name or conn name to unicode and uppercase */
177 	len = strlen(dname);
178 	domain = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
179 	if (!domain) {
180 		ret = -ENOMEM;
181 		goto out;
182 	}
183 
184 	conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
185 				  conn->local_nls);
186 	if (conv_len < 0 || conv_len > len) {
187 		ret = -EINVAL;
188 		goto out;
189 	}
190 
191 	ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
192 				  (char *)domain,
193 				  UNICODE_LEN(conv_len));
194 	if (ret) {
195 		ksmbd_debug(AUTH, "Could not update with domain\n");
196 		goto out;
197 	}
198 
199 	ret = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_hash);
200 	if (ret)
201 		ksmbd_debug(AUTH, "Could not generate md5 hash\n");
202 out:
203 	kfree(uniname);
204 	kfree(domain);
205 	ksmbd_release_crypto_ctx(ctx);
206 	return ret;
207 }
208 
209 /**
210  * ksmbd_auth_ntlmv2() - NTLMv2 authentication handler
211  * @conn:		connection
212  * @sess:		session of connection
213  * @ntlmv2:		NTLMv2 challenge response
214  * @blen:		NTLMv2 blob length
215  * @domain_name:	domain name
216  * @cryptkey:		session crypto key
217  *
218  * Return:	0 on success, error number on error
219  */
ksmbd_auth_ntlmv2(struct ksmbd_conn * conn,struct ksmbd_session * sess,struct ntlmv2_resp * ntlmv2,int blen,char * domain_name,char * cryptkey)220 int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
221 		      struct ntlmv2_resp *ntlmv2, int blen, char *domain_name,
222 		      char *cryptkey)
223 {
224 	char ntlmv2_hash[CIFS_ENCPWD_SIZE];
225 	char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
226 	struct ksmbd_crypto_ctx *ctx = NULL;
227 	char *construct = NULL;
228 	int rc, len;
229 
230 	rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
231 	if (rc) {
232 		ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
233 		goto out;
234 	}
235 
236 	ctx = ksmbd_crypto_ctx_find_hmacmd5();
237 	if (!ctx) {
238 		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
239 		return -ENOMEM;
240 	}
241 
242 	rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
243 				 ntlmv2_hash,
244 				 CIFS_HMAC_MD5_HASH_SIZE);
245 	if (rc) {
246 		ksmbd_debug(AUTH, "Could not set NTLMV2 Hash as a key\n");
247 		goto out;
248 	}
249 
250 	rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
251 	if (rc) {
252 		ksmbd_debug(AUTH, "Could not init hmacmd5\n");
253 		goto out;
254 	}
255 
256 	len = CIFS_CRYPTO_KEY_SIZE + blen;
257 	construct = kzalloc(len, KSMBD_DEFAULT_GFP);
258 	if (!construct) {
259 		rc = -ENOMEM;
260 		goto out;
261 	}
262 
263 	memcpy(construct, cryptkey, CIFS_CRYPTO_KEY_SIZE);
264 	memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
265 
266 	rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
267 	if (rc) {
268 		ksmbd_debug(AUTH, "Could not update with response\n");
269 		goto out;
270 	}
271 
272 	rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_rsp);
273 	if (rc) {
274 		ksmbd_debug(AUTH, "Could not generate md5 hash\n");
275 		goto out;
276 	}
277 	ksmbd_release_crypto_ctx(ctx);
278 	ctx = NULL;
279 
280 	rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
281 	if (rc) {
282 		ksmbd_debug(AUTH, "Could not generate sess key\n");
283 		goto out;
284 	}
285 
286 	if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
287 		rc = -EINVAL;
288 out:
289 	if (ctx)
290 		ksmbd_release_crypto_ctx(ctx);
291 	kfree(construct);
292 	return rc;
293 }
294 
295 /**
296  * ksmbd_decode_ntlmssp_auth_blob() - helper function to construct
297  * authenticate blob
298  * @authblob:	authenticate blob source pointer
299  * @blob_len:	length of the @authblob message
300  * @conn:	connection
301  * @sess:	session of connection
302  *
303  * Return:	0 on success, error number on error
304  */
ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message * authblob,int blob_len,struct ksmbd_conn * conn,struct ksmbd_session * sess)305 int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
306 				   int blob_len, struct ksmbd_conn *conn,
307 				   struct ksmbd_session *sess)
308 {
309 	char *domain_name;
310 	unsigned int nt_off, dn_off;
311 	unsigned short nt_len, dn_len;
312 	int ret;
313 
314 	if (blob_len < sizeof(struct authenticate_message)) {
315 		ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
316 			    blob_len);
317 		return -EINVAL;
318 	}
319 
320 	if (memcmp(authblob->Signature, "NTLMSSP", 8)) {
321 		ksmbd_debug(AUTH, "blob signature incorrect %s\n",
322 			    authblob->Signature);
323 		return -EINVAL;
324 	}
325 
326 	nt_off = le32_to_cpu(authblob->NtChallengeResponse.BufferOffset);
327 	nt_len = le16_to_cpu(authblob->NtChallengeResponse.Length);
328 	dn_off = le32_to_cpu(authblob->DomainName.BufferOffset);
329 	dn_len = le16_to_cpu(authblob->DomainName.Length);
330 
331 	if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len ||
332 	    nt_len < CIFS_ENCPWD_SIZE)
333 		return -EINVAL;
334 
335 	/* TODO : use domain name that imported from configuration file */
336 	domain_name = smb_strndup_from_utf16((const char *)authblob + dn_off,
337 					     dn_len, true, conn->local_nls);
338 	if (IS_ERR(domain_name))
339 		return PTR_ERR(domain_name);
340 
341 	/* process NTLMv2 authentication */
342 	ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
343 		    domain_name);
344 	ret = ksmbd_auth_ntlmv2(conn, sess,
345 				(struct ntlmv2_resp *)((char *)authblob + nt_off),
346 				nt_len - CIFS_ENCPWD_SIZE,
347 				domain_name, conn->ntlmssp.cryptkey);
348 	kfree(domain_name);
349 
350 	/* The recovered secondary session key */
351 	if (conn->ntlmssp.client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) {
352 		struct arc4_ctx *ctx_arc4;
353 		unsigned int sess_key_off, sess_key_len;
354 
355 		sess_key_off = le32_to_cpu(authblob->SessionKey.BufferOffset);
356 		sess_key_len = le16_to_cpu(authblob->SessionKey.Length);
357 
358 		if (blob_len < (u64)sess_key_off + sess_key_len)
359 			return -EINVAL;
360 
361 		if (sess_key_len > CIFS_KEY_SIZE)
362 			return -EINVAL;
363 
364 		ctx_arc4 = kmalloc(sizeof(*ctx_arc4), KSMBD_DEFAULT_GFP);
365 		if (!ctx_arc4)
366 			return -ENOMEM;
367 
368 		arc4_setkey(ctx_arc4, sess->sess_key, SMB2_NTLMV2_SESSKEY_SIZE);
369 		arc4_crypt(ctx_arc4, sess->sess_key,
370 			   (char *)authblob + sess_key_off, sess_key_len);
371 		kfree_sensitive(ctx_arc4);
372 	}
373 
374 	return ret;
375 }
376 
377 /**
378  * ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
379  * negotiate blob
380  * @negblob: negotiate blob source pointer
381  * @blob_len:	length of the @authblob message
382  * @conn:	connection
383  *
384  */
ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message * negblob,int blob_len,struct ksmbd_conn * conn)385 int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
386 				  int blob_len, struct ksmbd_conn *conn)
387 {
388 	if (blob_len < sizeof(struct negotiate_message)) {
389 		ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
390 			    blob_len);
391 		return -EINVAL;
392 	}
393 
394 	if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
395 		ksmbd_debug(AUTH, "blob signature incorrect %s\n",
396 			    negblob->Signature);
397 		return -EINVAL;
398 	}
399 
400 	conn->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
401 	return 0;
402 }
403 
404 /**
405  * ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
406  * challenge blob
407  * @chgblob: challenge blob source pointer to initialize
408  * @conn:	connection
409  *
410  */
411 unsigned int
ksmbd_build_ntlmssp_challenge_blob(struct challenge_message * chgblob,struct ksmbd_conn * conn)412 ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
413 				   struct ksmbd_conn *conn)
414 {
415 	struct target_info *tinfo;
416 	wchar_t *name;
417 	__u8 *target_name;
418 	unsigned int flags, blob_off, blob_len, type, target_info_len = 0;
419 	int len, uni_len, conv_len;
420 	int cflags = conn->ntlmssp.client_flags;
421 
422 	memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
423 	chgblob->MessageType = NtLmChallenge;
424 
425 	flags = NTLMSSP_NEGOTIATE_UNICODE |
426 		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
427 		NTLMSSP_NEGOTIATE_TARGET_INFO;
428 
429 	if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
430 		flags |= NTLMSSP_NEGOTIATE_SIGN;
431 		flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
432 				   NTLMSSP_NEGOTIATE_56);
433 	}
434 
435 	if (cflags & NTLMSSP_NEGOTIATE_SEAL && smb3_encryption_negotiated(conn))
436 		flags |= NTLMSSP_NEGOTIATE_SEAL;
437 
438 	if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
439 		flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
440 
441 	if (cflags & NTLMSSP_REQUEST_TARGET)
442 		flags |= NTLMSSP_REQUEST_TARGET;
443 
444 	if (conn->use_spnego &&
445 	    (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
446 		flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
447 
448 	if (cflags & NTLMSSP_NEGOTIATE_KEY_XCH)
449 		flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
450 
451 	chgblob->NegotiateFlags = cpu_to_le32(flags);
452 	len = strlen(ksmbd_netbios_name());
453 	name = kmalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
454 	if (!name)
455 		return -ENOMEM;
456 
457 	conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
458 				  conn->local_nls);
459 	if (conv_len < 0 || conv_len > len) {
460 		kfree(name);
461 		return -EINVAL;
462 	}
463 
464 	uni_len = UNICODE_LEN(conv_len);
465 
466 	blob_off = sizeof(struct challenge_message);
467 	blob_len = blob_off + uni_len;
468 
469 	chgblob->TargetName.Length = cpu_to_le16(uni_len);
470 	chgblob->TargetName.MaximumLength = cpu_to_le16(uni_len);
471 	chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
472 
473 	/* Initialize random conn challenge */
474 	get_random_bytes(conn->ntlmssp.cryptkey, sizeof(__u64));
475 	memcpy(chgblob->Challenge, conn->ntlmssp.cryptkey,
476 	       CIFS_CRYPTO_KEY_SIZE);
477 
478 	/* Add Target Information to security buffer */
479 	chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
480 
481 	target_name = (__u8 *)chgblob + blob_off;
482 	memcpy(target_name, name, uni_len);
483 	tinfo = (struct target_info *)(target_name + uni_len);
484 
485 	chgblob->TargetInfoArray.Length = 0;
486 	/* Add target info list for NetBIOS/DNS settings */
487 	for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
488 	     type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
489 		tinfo->Type = cpu_to_le16(type);
490 		tinfo->Length = cpu_to_le16(uni_len);
491 		memcpy(tinfo->Content, name, uni_len);
492 		tinfo = (struct target_info *)((char *)tinfo + 4 + uni_len);
493 		target_info_len += 4 + uni_len;
494 	}
495 
496 	/* Add terminator subblock */
497 	tinfo->Type = 0;
498 	tinfo->Length = 0;
499 	target_info_len += 4;
500 
501 	chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
502 	chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
503 	blob_len += target_info_len;
504 	kfree(name);
505 	ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
506 	return blob_len;
507 }
508 
509 #ifdef CONFIG_SMB_SERVER_KERBEROS5
ksmbd_krb5_authenticate(struct ksmbd_session * sess,char * in_blob,int in_len,char * out_blob,int * out_len)510 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
511 			    int in_len, char *out_blob, int *out_len)
512 {
513 	struct ksmbd_spnego_authen_response *resp;
514 	struct ksmbd_login_response_ext *resp_ext = NULL;
515 	struct ksmbd_user *user = NULL;
516 	int retval;
517 
518 	resp = ksmbd_ipc_spnego_authen_request(in_blob, in_len);
519 	if (!resp) {
520 		ksmbd_debug(AUTH, "SPNEGO_AUTHEN_REQUEST failure\n");
521 		return -EINVAL;
522 	}
523 
524 	if (!(resp->login_response.status & KSMBD_USER_FLAG_OK)) {
525 		ksmbd_debug(AUTH, "krb5 authentication failure\n");
526 		retval = -EPERM;
527 		goto out;
528 	}
529 
530 	if (*out_len <= resp->spnego_blob_len) {
531 		ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
532 			    *out_len, resp->spnego_blob_len);
533 		retval = -EINVAL;
534 		goto out;
535 	}
536 
537 	if (resp->session_key_len > sizeof(sess->sess_key)) {
538 		ksmbd_debug(AUTH, "session key is too long\n");
539 		retval = -EINVAL;
540 		goto out;
541 	}
542 
543 	if (resp->login_response.status & KSMBD_USER_FLAG_EXTENSION)
544 		resp_ext = ksmbd_ipc_login_request_ext(resp->login_response.account);
545 
546 	user = ksmbd_alloc_user(&resp->login_response, resp_ext);
547 	if (!user) {
548 		ksmbd_debug(AUTH, "login failure\n");
549 		retval = -ENOMEM;
550 		goto out;
551 	}
552 
553 	if (!sess->user) {
554 		/* First successful authentication */
555 		sess->user = user;
556 	} else {
557 		if (!ksmbd_compare_user(sess->user, user)) {
558 			ksmbd_debug(AUTH, "different user tried to reuse session\n");
559 			retval = -EPERM;
560 			ksmbd_free_user(user);
561 			goto out;
562 		}
563 		ksmbd_free_user(user);
564 	}
565 
566 	memcpy(sess->sess_key, resp->payload, resp->session_key_len);
567 	memcpy(out_blob, resp->payload + resp->session_key_len,
568 	       resp->spnego_blob_len);
569 	*out_len = resp->spnego_blob_len;
570 	retval = 0;
571 out:
572 	kvfree(resp);
573 	return retval;
574 }
575 #else
ksmbd_krb5_authenticate(struct ksmbd_session * sess,char * in_blob,int in_len,char * out_blob,int * out_len)576 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
577 			    int in_len, char *out_blob, int *out_len)
578 {
579 	return -EOPNOTSUPP;
580 }
581 #endif
582 
583 /**
584  * ksmbd_sign_smb2_pdu() - function to generate packet signing
585  * @conn:	connection
586  * @key:	signing key
587  * @iov:        buffer iov array
588  * @n_vec:	number of iovecs
589  * @sig:	signature value generated for client request packet
590  *
591  */
ksmbd_sign_smb2_pdu(struct ksmbd_conn * conn,char * key,struct kvec * iov,int n_vec,char * sig)592 int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
593 			int n_vec, char *sig)
594 {
595 	struct ksmbd_crypto_ctx *ctx;
596 	int rc, i;
597 
598 	ctx = ksmbd_crypto_ctx_find_hmacsha256();
599 	if (!ctx) {
600 		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
601 		return -ENOMEM;
602 	}
603 
604 	rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
605 				 key,
606 				 SMB2_NTLMV2_SESSKEY_SIZE);
607 	if (rc)
608 		goto out;
609 
610 	rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
611 	if (rc) {
612 		ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
613 		goto out;
614 	}
615 
616 	for (i = 0; i < n_vec; i++) {
617 		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
618 					 iov[i].iov_base,
619 					 iov[i].iov_len);
620 		if (rc) {
621 			ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
622 			goto out;
623 		}
624 	}
625 
626 	rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
627 	if (rc)
628 		ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
629 out:
630 	ksmbd_release_crypto_ctx(ctx);
631 	return rc;
632 }
633 
634 /**
635  * ksmbd_sign_smb3_pdu() - function to generate packet signing
636  * @conn:	connection
637  * @key:	signing key
638  * @iov:        buffer iov array
639  * @n_vec:	number of iovecs
640  * @sig:	signature value generated for client request packet
641  *
642  */
ksmbd_sign_smb3_pdu(struct ksmbd_conn * conn,char * key,struct kvec * iov,int n_vec,char * sig)643 int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
644 			int n_vec, char *sig)
645 {
646 	struct ksmbd_crypto_ctx *ctx;
647 	int rc, i;
648 
649 	ctx = ksmbd_crypto_ctx_find_cmacaes();
650 	if (!ctx) {
651 		ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
652 		return -ENOMEM;
653 	}
654 
655 	rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
656 				 key,
657 				 SMB2_CMACAES_SIZE);
658 	if (rc)
659 		goto out;
660 
661 	rc = crypto_shash_init(CRYPTO_CMACAES(ctx));
662 	if (rc) {
663 		ksmbd_debug(AUTH, "cmaces init error %d\n", rc);
664 		goto out;
665 	}
666 
667 	for (i = 0; i < n_vec; i++) {
668 		rc = crypto_shash_update(CRYPTO_CMACAES(ctx),
669 					 iov[i].iov_base,
670 					 iov[i].iov_len);
671 		if (rc) {
672 			ksmbd_debug(AUTH, "cmaces update error %d\n", rc);
673 			goto out;
674 		}
675 	}
676 
677 	rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig);
678 	if (rc)
679 		ksmbd_debug(AUTH, "cmaces generation error %d\n", rc);
680 out:
681 	ksmbd_release_crypto_ctx(ctx);
682 	return rc;
683 }
684 
685 struct derivation {
686 	struct kvec label;
687 	struct kvec context;
688 	bool binding;
689 };
690 
generate_key(struct ksmbd_conn * conn,struct ksmbd_session * sess,struct kvec label,struct kvec context,__u8 * key,unsigned int key_size)691 static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
692 			struct kvec label, struct kvec context, __u8 *key,
693 			unsigned int key_size)
694 {
695 	unsigned char zero = 0x0;
696 	__u8 i[4] = {0, 0, 0, 1};
697 	__u8 L128[4] = {0, 0, 0, 128};
698 	__u8 L256[4] = {0, 0, 1, 0};
699 	int rc;
700 	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
701 	unsigned char *hashptr = prfhash;
702 	struct ksmbd_crypto_ctx *ctx;
703 
704 	memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
705 	memset(key, 0x0, key_size);
706 
707 	ctx = ksmbd_crypto_ctx_find_hmacsha256();
708 	if (!ctx) {
709 		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
710 		return -ENOMEM;
711 	}
712 
713 	rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
714 				 sess->sess_key,
715 				 SMB2_NTLMV2_SESSKEY_SIZE);
716 	if (rc)
717 		goto smb3signkey_ret;
718 
719 	rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
720 	if (rc) {
721 		ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
722 		goto smb3signkey_ret;
723 	}
724 
725 	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
726 	if (rc) {
727 		ksmbd_debug(AUTH, "could not update with n\n");
728 		goto smb3signkey_ret;
729 	}
730 
731 	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
732 				 label.iov_base,
733 				 label.iov_len);
734 	if (rc) {
735 		ksmbd_debug(AUTH, "could not update with label\n");
736 		goto smb3signkey_ret;
737 	}
738 
739 	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
740 	if (rc) {
741 		ksmbd_debug(AUTH, "could not update with zero\n");
742 		goto smb3signkey_ret;
743 	}
744 
745 	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
746 				 context.iov_base,
747 				 context.iov_len);
748 	if (rc) {
749 		ksmbd_debug(AUTH, "could not update with context\n");
750 		goto smb3signkey_ret;
751 	}
752 
753 	if (key_size == SMB3_ENC_DEC_KEY_SIZE &&
754 	    (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
755 	     conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
756 		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
757 	else
758 		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
759 	if (rc) {
760 		ksmbd_debug(AUTH, "could not update with L\n");
761 		goto smb3signkey_ret;
762 	}
763 
764 	rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
765 	if (rc) {
766 		ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
767 			    rc);
768 		goto smb3signkey_ret;
769 	}
770 
771 	memcpy(key, hashptr, key_size);
772 
773 smb3signkey_ret:
774 	ksmbd_release_crypto_ctx(ctx);
775 	return rc;
776 }
777 
generate_smb3signingkey(struct ksmbd_session * sess,struct ksmbd_conn * conn,const struct derivation * signing)778 static int generate_smb3signingkey(struct ksmbd_session *sess,
779 				   struct ksmbd_conn *conn,
780 				   const struct derivation *signing)
781 {
782 	int rc;
783 	struct channel *chann;
784 	char *key;
785 
786 	chann = lookup_chann_list(sess, conn);
787 	if (!chann)
788 		return 0;
789 
790 	if (conn->dialect >= SMB30_PROT_ID && signing->binding)
791 		key = chann->smb3signingkey;
792 	else
793 		key = sess->smb3signingkey;
794 
795 	rc = generate_key(conn, sess, signing->label, signing->context, key,
796 			  SMB3_SIGN_KEY_SIZE);
797 	if (rc)
798 		return rc;
799 
800 	if (!(conn->dialect >= SMB30_PROT_ID && signing->binding))
801 		memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
802 
803 	ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
804 	ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
805 	ksmbd_debug(AUTH, "Session Key   %*ph\n",
806 		    SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
807 	ksmbd_debug(AUTH, "Signing Key   %*ph\n",
808 		    SMB3_SIGN_KEY_SIZE, key);
809 	return 0;
810 }
811 
ksmbd_gen_smb30_signingkey(struct ksmbd_session * sess,struct ksmbd_conn * conn)812 int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
813 			       struct ksmbd_conn *conn)
814 {
815 	struct derivation d;
816 
817 	d.label.iov_base = "SMB2AESCMAC";
818 	d.label.iov_len = 12;
819 	d.context.iov_base = "SmbSign";
820 	d.context.iov_len = 8;
821 	d.binding = conn->binding;
822 
823 	return generate_smb3signingkey(sess, conn, &d);
824 }
825 
ksmbd_gen_smb311_signingkey(struct ksmbd_session * sess,struct ksmbd_conn * conn)826 int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
827 				struct ksmbd_conn *conn)
828 {
829 	struct derivation d;
830 
831 	d.label.iov_base = "SMBSigningKey";
832 	d.label.iov_len = 14;
833 	if (conn->binding) {
834 		struct preauth_session *preauth_sess;
835 
836 		preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
837 		if (!preauth_sess)
838 			return -ENOENT;
839 		d.context.iov_base = preauth_sess->Preauth_HashValue;
840 	} else {
841 		d.context.iov_base = sess->Preauth_HashValue;
842 	}
843 	d.context.iov_len = 64;
844 	d.binding = conn->binding;
845 
846 	return generate_smb3signingkey(sess, conn, &d);
847 }
848 
849 struct derivation_twin {
850 	struct derivation encryption;
851 	struct derivation decryption;
852 };
853 
generate_smb3encryptionkey(struct ksmbd_conn * conn,struct ksmbd_session * sess,const struct derivation_twin * ptwin)854 static int generate_smb3encryptionkey(struct ksmbd_conn *conn,
855 				      struct ksmbd_session *sess,
856 				      const struct derivation_twin *ptwin)
857 {
858 	int rc;
859 
860 	rc = generate_key(conn, sess, ptwin->encryption.label,
861 			  ptwin->encryption.context, sess->smb3encryptionkey,
862 			  SMB3_ENC_DEC_KEY_SIZE);
863 	if (rc)
864 		return rc;
865 
866 	rc = generate_key(conn, sess, ptwin->decryption.label,
867 			  ptwin->decryption.context,
868 			  sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
869 	if (rc)
870 		return rc;
871 
872 	ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
873 	ksmbd_debug(AUTH, "Cipher type   %d\n", conn->cipher_type);
874 	ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
875 	ksmbd_debug(AUTH, "Session Key   %*ph\n",
876 		    SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
877 	if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
878 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
879 		ksmbd_debug(AUTH, "ServerIn Key  %*ph\n",
880 			    SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
881 		ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
882 			    SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
883 	} else {
884 		ksmbd_debug(AUTH, "ServerIn Key  %*ph\n",
885 			    SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
886 		ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
887 			    SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
888 	}
889 	return 0;
890 }
891 
ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn * conn,struct ksmbd_session * sess)892 int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
893 				  struct ksmbd_session *sess)
894 {
895 	struct derivation_twin twin;
896 	struct derivation *d;
897 
898 	d = &twin.encryption;
899 	d->label.iov_base = "SMB2AESCCM";
900 	d->label.iov_len = 11;
901 	d->context.iov_base = "ServerOut";
902 	d->context.iov_len = 10;
903 
904 	d = &twin.decryption;
905 	d->label.iov_base = "SMB2AESCCM";
906 	d->label.iov_len = 11;
907 	d->context.iov_base = "ServerIn ";
908 	d->context.iov_len = 10;
909 
910 	return generate_smb3encryptionkey(conn, sess, &twin);
911 }
912 
ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn * conn,struct ksmbd_session * sess)913 int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
914 				   struct ksmbd_session *sess)
915 {
916 	struct derivation_twin twin;
917 	struct derivation *d;
918 
919 	d = &twin.encryption;
920 	d->label.iov_base = "SMBS2CCipherKey";
921 	d->label.iov_len = 16;
922 	d->context.iov_base = sess->Preauth_HashValue;
923 	d->context.iov_len = 64;
924 
925 	d = &twin.decryption;
926 	d->label.iov_base = "SMBC2SCipherKey";
927 	d->label.iov_len = 16;
928 	d->context.iov_base = sess->Preauth_HashValue;
929 	d->context.iov_len = 64;
930 
931 	return generate_smb3encryptionkey(conn, sess, &twin);
932 }
933 
ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn * conn,char * buf,__u8 * pi_hash)934 int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
935 				     __u8 *pi_hash)
936 {
937 	int rc;
938 	struct smb2_hdr *rcv_hdr = smb2_get_msg(buf);
939 	char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
940 	int msg_size = get_rfc1002_len(buf);
941 	struct ksmbd_crypto_ctx *ctx = NULL;
942 
943 	if (conn->preauth_info->Preauth_HashId !=
944 	    SMB2_PREAUTH_INTEGRITY_SHA512)
945 		return -EINVAL;
946 
947 	ctx = ksmbd_crypto_ctx_find_sha512();
948 	if (!ctx) {
949 		ksmbd_debug(AUTH, "could not alloc sha512\n");
950 		return -ENOMEM;
951 	}
952 
953 	rc = crypto_shash_init(CRYPTO_SHA512(ctx));
954 	if (rc) {
955 		ksmbd_debug(AUTH, "could not init shashn");
956 		goto out;
957 	}
958 
959 	rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
960 	if (rc) {
961 		ksmbd_debug(AUTH, "could not update with n\n");
962 		goto out;
963 	}
964 
965 	rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
966 	if (rc) {
967 		ksmbd_debug(AUTH, "could not update with n\n");
968 		goto out;
969 	}
970 
971 	rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
972 	if (rc) {
973 		ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
974 		goto out;
975 	}
976 out:
977 	ksmbd_release_crypto_ctx(ctx);
978 	return rc;
979 }
980 
ksmbd_get_encryption_key(struct ksmbd_work * work,__u64 ses_id,int enc,u8 * key)981 static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id,
982 				    int enc, u8 *key)
983 {
984 	struct ksmbd_session *sess;
985 	u8 *ses_enc_key;
986 
987 	if (enc)
988 		sess = work->sess;
989 	else
990 		sess = ksmbd_session_lookup_all(work->conn, ses_id);
991 	if (!sess)
992 		return -EINVAL;
993 
994 	ses_enc_key = enc ? sess->smb3encryptionkey :
995 		sess->smb3decryptionkey;
996 	memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
997 	if (!enc)
998 		ksmbd_user_session_put(sess);
999 
1000 	return 0;
1001 }
1002 
smb2_sg_set_buf(struct scatterlist * sg,const void * buf,unsigned int buflen)1003 static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
1004 				   unsigned int buflen)
1005 {
1006 	void *addr;
1007 
1008 	if (is_vmalloc_addr(buf))
1009 		addr = vmalloc_to_page(buf);
1010 	else
1011 		addr = virt_to_page(buf);
1012 	sg_set_page(sg, addr, buflen, offset_in_page(buf));
1013 }
1014 
ksmbd_init_sg(struct kvec * iov,unsigned int nvec,u8 * sign)1015 static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
1016 					 u8 *sign)
1017 {
1018 	struct scatterlist *sg;
1019 	unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1020 	int i, *nr_entries, total_entries = 0, sg_idx = 0;
1021 
1022 	if (!nvec)
1023 		return NULL;
1024 
1025 	nr_entries = kcalloc(nvec, sizeof(int), KSMBD_DEFAULT_GFP);
1026 	if (!nr_entries)
1027 		return NULL;
1028 
1029 	for (i = 0; i < nvec - 1; i++) {
1030 		unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
1031 
1032 		if (is_vmalloc_addr(iov[i + 1].iov_base)) {
1033 			nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
1034 					PAGE_SIZE - 1) >> PAGE_SHIFT) -
1035 				(kaddr >> PAGE_SHIFT);
1036 		} else {
1037 			nr_entries[i]++;
1038 		}
1039 		total_entries += nr_entries[i];
1040 	}
1041 
1042 	/* Add two entries for transform header and signature */
1043 	total_entries += 2;
1044 
1045 	sg = kmalloc_array(total_entries, sizeof(struct scatterlist),
1046 			   KSMBD_DEFAULT_GFP);
1047 	if (!sg) {
1048 		kfree(nr_entries);
1049 		return NULL;
1050 	}
1051 
1052 	sg_init_table(sg, total_entries);
1053 	smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1054 	for (i = 0; i < nvec - 1; i++) {
1055 		void *data = iov[i + 1].iov_base;
1056 		int len = iov[i + 1].iov_len;
1057 
1058 		if (is_vmalloc_addr(data)) {
1059 			int j, offset = offset_in_page(data);
1060 
1061 			for (j = 0; j < nr_entries[i]; j++) {
1062 				unsigned int bytes = PAGE_SIZE - offset;
1063 
1064 				if (!len)
1065 					break;
1066 
1067 				if (bytes > len)
1068 					bytes = len;
1069 
1070 				sg_set_page(&sg[sg_idx++],
1071 					    vmalloc_to_page(data), bytes,
1072 					    offset_in_page(data));
1073 
1074 				data += bytes;
1075 				len -= bytes;
1076 				offset = 0;
1077 			}
1078 		} else {
1079 			sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1080 				    offset_in_page(data));
1081 		}
1082 	}
1083 	smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1084 	kfree(nr_entries);
1085 	return sg;
1086 }
1087 
ksmbd_crypt_message(struct ksmbd_work * work,struct kvec * iov,unsigned int nvec,int enc)1088 int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
1089 			unsigned int nvec, int enc)
1090 {
1091 	struct ksmbd_conn *conn = work->conn;
1092 	struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
1093 	unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1094 	int rc;
1095 	struct scatterlist *sg;
1096 	u8 sign[SMB2_SIGNATURE_SIZE] = {};
1097 	u8 key[SMB3_ENC_DEC_KEY_SIZE];
1098 	struct aead_request *req;
1099 	char *iv;
1100 	unsigned int iv_len;
1101 	struct crypto_aead *tfm;
1102 	unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1103 	struct ksmbd_crypto_ctx *ctx;
1104 
1105 	rc = ksmbd_get_encryption_key(work,
1106 				      le64_to_cpu(tr_hdr->SessionId),
1107 				      enc,
1108 				      key);
1109 	if (rc) {
1110 		pr_err("Could not get %scryption key\n", enc ? "en" : "de");
1111 		return rc;
1112 	}
1113 
1114 	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1115 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1116 		ctx = ksmbd_crypto_ctx_find_gcm();
1117 	else
1118 		ctx = ksmbd_crypto_ctx_find_ccm();
1119 	if (!ctx) {
1120 		pr_err("crypto alloc failed\n");
1121 		return -ENOMEM;
1122 	}
1123 
1124 	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1125 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1126 		tfm = CRYPTO_GCM(ctx);
1127 	else
1128 		tfm = CRYPTO_CCM(ctx);
1129 
1130 	if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1131 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1132 		rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1133 	else
1134 		rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
1135 	if (rc) {
1136 		pr_err("Failed to set aead key %d\n", rc);
1137 		goto free_ctx;
1138 	}
1139 
1140 	rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1141 	if (rc) {
1142 		pr_err("Failed to set authsize %d\n", rc);
1143 		goto free_ctx;
1144 	}
1145 
1146 	req = aead_request_alloc(tfm, KSMBD_DEFAULT_GFP);
1147 	if (!req) {
1148 		rc = -ENOMEM;
1149 		goto free_ctx;
1150 	}
1151 
1152 	if (!enc) {
1153 		memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1154 		crypt_len += SMB2_SIGNATURE_SIZE;
1155 	}
1156 
1157 	sg = ksmbd_init_sg(iov, nvec, sign);
1158 	if (!sg) {
1159 		pr_err("Failed to init sg\n");
1160 		rc = -ENOMEM;
1161 		goto free_req;
1162 	}
1163 
1164 	iv_len = crypto_aead_ivsize(tfm);
1165 	iv = kzalloc(iv_len, KSMBD_DEFAULT_GFP);
1166 	if (!iv) {
1167 		rc = -ENOMEM;
1168 		goto free_sg;
1169 	}
1170 
1171 	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1172 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1173 		memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
1174 	} else {
1175 		iv[0] = 3;
1176 		memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
1177 	}
1178 
1179 	aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1180 	aead_request_set_ad(req, assoc_data_len);
1181 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1182 
1183 	if (enc)
1184 		rc = crypto_aead_encrypt(req);
1185 	else
1186 		rc = crypto_aead_decrypt(req);
1187 	if (rc)
1188 		goto free_iv;
1189 
1190 	if (enc)
1191 		memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1192 
1193 free_iv:
1194 	kfree(iv);
1195 free_sg:
1196 	kfree(sg);
1197 free_req:
1198 	aead_request_free(req);
1199 free_ctx:
1200 	ksmbd_release_crypto_ctx(ctx);
1201 	return rc;
1202 }
1203