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